]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.6-grsec_full.patch
- kernel kvm module build disabled, it is provided by kvm.spec
[packages/kernel.git] / linux-2.6-grsec_full.patch
CommitLineData
3ba9fddb 1diff -urNp linux-2.6.22.1/arch/alpha/kernel/module.c linux-2.6.22.1/arch/alpha/kernel/module.c
2--- linux-2.6.22.1/arch/alpha/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
3+++ linux-2.6.22.1/arch/alpha/kernel/module.c 2007-08-02 11:38:45.000000000 -0400
4@@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs,
5
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;
11
12 for (i = 0; i < n; i++) {
13diff -urNp linux-2.6.22.1/arch/alpha/kernel/osf_sys.c linux-2.6.22.1/arch/alpha/kernel/osf_sys.c
14--- linux-2.6.22.1/arch/alpha/kernel/osf_sys.c 2007-07-10 14:56:30.000000000 -0400
15+++ linux-2.6.22.1/arch/alpha/kernel/osf_sys.c 2007-08-02 11:38:45.000000000 -0400
16@@ -1288,6 +1288,10 @@ arch_get_unmapped_area(struct file *filp
17 merely specific addresses, but regions of memory -- perhaps
18 this feature should be incorporated into all ports? */
19
20+#ifdef CONFIG_PAX_RANDMMAP
21+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
22+#endif
23+
24 if (addr) {
25 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
26 if (addr != (unsigned long) -ENOMEM)
27@@ -1295,8 +1299,8 @@ arch_get_unmapped_area(struct file *filp
28 }
29
30 /* Next, try allocating at TASK_UNMAPPED_BASE. */
31- addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
32- len, limit);
33+ addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
34+
35 if (addr != (unsigned long) -ENOMEM)
36 return addr;
37
38diff -urNp linux-2.6.22.1/arch/alpha/kernel/ptrace.c linux-2.6.22.1/arch/alpha/kernel/ptrace.c
39--- linux-2.6.22.1/arch/alpha/kernel/ptrace.c 2007-07-10 14:56:30.000000000 -0400
40+++ linux-2.6.22.1/arch/alpha/kernel/ptrace.c 2007-08-02 11:09:14.000000000 -0400
41@@ -16,6 +16,7 @@
42 #include <linux/security.h>
43 #include <linux/signal.h>
44 #include <linux/vs_base.h>
45+#include <linux/grsecurity.h>
46
47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h>
b5630f59 49@@ -289,6 +290,11 @@ do_sys_ptrace(long request, long pid, lo
3ba9fddb 50 goto out;
51 }
52
b5630f59 53+ if (gr_handle_ptrace(child, request)) {
54+ ret = -EPERM;
3ba9fddb 55+ goto out;
b5630f59 56+ }
3ba9fddb 57+
58 if (request == PTRACE_ATTACH) {
59 ret = ptrace_attach(child);
60 goto out;
61diff -urNp linux-2.6.22.1/arch/alpha/mm/fault.c linux-2.6.22.1/arch/alpha/mm/fault.c
62--- linux-2.6.22.1/arch/alpha/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
63+++ linux-2.6.22.1/arch/alpha/mm/fault.c 2007-08-02 11:38:45.000000000 -0400
64@@ -23,6 +23,7 @@
65 #include <linux/smp.h>
66 #include <linux/interrupt.h>
67 #include <linux/module.h>
68+#include <linux/binfmts.h>
69
70 #include <asm/system.h>
71 #include <asm/uaccess.h>
72@@ -54,6 +55,124 @@ __load_new_mm_context(struct mm_struct *
73 __reload_thread(pcb);
74 }
75
76+#ifdef CONFIG_PAX_PAGEEXEC
77+/*
78+ * PaX: decide what to do with offenders (regs->pc = fault address)
79+ *
80+ * returns 1 when task should be killed
81+ * 2 when patched PLT trampoline was detected
82+ * 3 when unpatched PLT trampoline was detected
83+ */
84+static int pax_handle_fetch_fault(struct pt_regs *regs)
85+{
86+
87+#ifdef CONFIG_PAX_EMUPLT
88+ int err;
89+
90+ do { /* PaX: patched PLT emulation #1 */
91+ unsigned int ldah, ldq, jmp;
92+
93+ err = get_user(ldah, (unsigned int *)regs->pc);
94+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
95+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
96+
97+ if (err)
98+ break;
99+
100+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
101+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
102+ jmp == 0x6BFB0000U)
103+ {
104+ unsigned long r27, addr;
105+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
106+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
107+
108+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
109+ err = get_user(r27, (unsigned long *)addr);
110+ if (err)
111+ break;
112+
113+ regs->r27 = r27;
114+ regs->pc = r27;
115+ return 2;
116+ }
117+ } while (0);
118+
119+ do { /* PaX: patched PLT emulation #2 */
120+ unsigned int ldah, lda, br;
121+
122+ err = get_user(ldah, (unsigned int *)regs->pc);
123+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
124+ err |= get_user(br, (unsigned int *)(regs->pc+8));
125+
126+ if (err)
127+ break;
128+
129+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
130+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
131+ (br & 0xFFE00000U) == 0xC3E00000U)
132+ {
133+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
134+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
135+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
136+
137+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
138+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
139+ return 2;
140+ }
141+ } while (0);
142+
143+ do { /* PaX: unpatched PLT emulation */
144+ unsigned int br;
145+
146+ err = get_user(br, (unsigned int *)regs->pc);
147+
148+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
149+ unsigned int br2, ldq, nop, jmp;
150+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
151+
152+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
153+ err = get_user(br2, (unsigned int *)addr);
154+ err |= get_user(ldq, (unsigned int *)(addr+4));
155+ err |= get_user(nop, (unsigned int *)(addr+8));
156+ err |= get_user(jmp, (unsigned int *)(addr+12));
157+ err |= get_user(resolver, (unsigned long *)(addr+16));
158+
159+ if (err)
160+ break;
161+
162+ if (br2 == 0xC3600000U &&
163+ ldq == 0xA77B000CU &&
164+ nop == 0x47FF041FU &&
165+ jmp == 0x6B7B0000U)
166+ {
167+ regs->r28 = regs->pc+4;
168+ regs->r27 = addr+16;
169+ regs->pc = resolver;
170+ return 3;
171+ }
172+ }
173+ } while (0);
174+#endif
175+
176+ return 1;
177+}
178+
179+void pax_report_insns(void *pc, void *sp)
180+{
181+ unsigned long i;
182+
183+ printk(KERN_ERR "PAX: bytes at PC: ");
184+ for (i = 0; i < 5; i++) {
185+ unsigned int c;
186+ if (get_user(c, (unsigned int *)pc+i))
187+ printk("???????? ");
188+ else
189+ printk("%08x ", c);
190+ }
191+ printk("\n");
192+}
193+#endif
194
195 /*
196 * This routine handles page faults. It determines the address,
197@@ -131,8 +250,29 @@ do_page_fault(unsigned long address, uns
198 good_area:
199 si_code = SEGV_ACCERR;
200 if (cause < 0) {
201- if (!(vma->vm_flags & VM_EXEC))
202+ if (!(vma->vm_flags & VM_EXEC)) {
203+
204+#ifdef CONFIG_PAX_PAGEEXEC
205+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
206+ goto bad_area;
207+
208+ up_read(&mm->mmap_sem);
209+ switch (pax_handle_fetch_fault(regs)) {
210+
211+#ifdef CONFIG_PAX_EMUPLT
212+ case 2:
213+ case 3:
214+ return;
215+#endif
216+
217+ }
218+ pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
219+ do_exit(SIGKILL);
220+#else
221 goto bad_area;
222+#endif
223+
224+ }
225 } else if (!cause) {
226 /* Allow reads even for write-only mappings */
227 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
228diff -urNp linux-2.6.22.1/arch/arm/mm/mmap.c linux-2.6.22.1/arch/arm/mm/mmap.c
229--- linux-2.6.22.1/arch/arm/mm/mmap.c 2007-07-10 14:56:30.000000000 -0400
230+++ linux-2.6.22.1/arch/arm/mm/mmap.c 2007-08-02 11:38:45.000000000 -0400
231@@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
232 if (len > TASK_SIZE)
233 return -ENOMEM;
234
235+#ifdef CONFIG_PAX_RANDMMAP
236+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
237+#endif
238+
239 if (addr) {
240 if (do_align)
241 addr = COLOUR_ALIGN(addr, pgoff);
242@@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
243 return addr;
244 }
245 if (len > mm->cached_hole_size) {
246- start_addr = addr = mm->free_area_cache;
247+ start_addr = addr = mm->free_area_cache;
248 } else {
249- start_addr = addr = TASK_UNMAPPED_BASE;
250- mm->cached_hole_size = 0;
251+ start_addr = addr = mm->mmap_base;
252+ mm->cached_hole_size = 0;
253 }
254
255 full_search:
256@@ -91,8 +95,8 @@ full_search:
257 * Start a new search - just in case we missed
258 * some holes.
259 */
260- if (start_addr != TASK_UNMAPPED_BASE) {
261- start_addr = addr = TASK_UNMAPPED_BASE;
262+ if (start_addr != mm->mmap_base) {
263+ start_addr = addr = mm->mmap_base;
264 mm->cached_hole_size = 0;
265 goto full_search;
266 }
267diff -urNp linux-2.6.22.1/arch/avr32/mm/fault.c linux-2.6.22.1/arch/avr32/mm/fault.c
268--- linux-2.6.22.1/arch/avr32/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
269+++ linux-2.6.22.1/arch/avr32/mm/fault.c 2007-08-02 11:38:45.000000000 -0400
270@@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
271
272 int exception_trace = 1;
273
274+#ifdef CONFIG_PAX_PAGEEXEC
275+void pax_report_insns(void *pc, void *sp)
276+{
277+ unsigned long i;
278+
279+ printk(KERN_ERR "PAX: bytes at PC: ");
280+ for (i = 0; i < 20; i++) {
281+ unsigned char c;
282+ if (get_user(c, (unsigned char *)pc+i))
283+ printk("???????? ");
284+ else
285+ printk("%02x ", c);
286+ }
287+ printk("\n");
288+}
289+#endif
290+
291 /*
292 * This routine handles page faults. It determines the address and the
293 * problem, and then passes it off to one of the appropriate routines.
294@@ -158,6 +175,16 @@ bad_area:
295 up_read(&mm->mmap_sem);
296
297 if (user_mode(regs)) {
298+
299+#ifdef CONFIG_PAX_PAGEEXEC
300+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
301+ if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
302+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
303+ do_exit(SIGKILL);
304+ }
305+ }
306+#endif
307+
308 if (exception_trace && printk_ratelimit())
309 printk("%s%s[%d]: segfault at %08lx pc %08lx "
310 "sp %08lx ecr %lu\n",
311diff -urNp linux-2.6.22.1/arch/i386/boot/setup.S linux-2.6.22.1/arch/i386/boot/setup.S
312--- linux-2.6.22.1/arch/i386/boot/setup.S 2007-07-10 14:56:30.000000000 -0400
313+++ linux-2.6.22.1/arch/i386/boot/setup.S 2007-08-02 11:38:45.000000000 -0400
314@@ -893,11 +893,13 @@ startup_32:
315 movl %eax, %gs
316 movl %eax, %ss
317
318+ movl 0x00000000, %ecx
319 xorl %eax, %eax
320 1: incl %eax # check that A20 really IS enabled
321 movl %eax, 0x00000000 # loop forever if it isn't
322 cmpl %eax, 0x00100000
323 je 1b
324+ movl %ecx, 0x00000000
325
326 # Jump to the 32bit entry point
327 jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
328diff -urNp linux-2.6.22/arch/i386/boot/video.S linux-2.6.22/arch/i386/boot/video.S
329--- linux-2.6.22/arch/i386/boot/video.S 2007-07-10 14:56:30.000000000 -0400
330+++ linux-2.6.22/arch/i386/boot/video.S 2007-07-10 14:56:30.000000000 -0400
331@@ -96,6 +96,7 @@
332 #define PARAM_LFB_PAGES 0x32
333 #define PARAM_VESA_ATTRIB 0x34
334 #define PARAM_CAPABILITIES 0x36
335+#define PARAM_VESAPM_SIZE 0x3a
336
337 /* Define DO_STORE according to CONFIG_VIDEO_RETAIN */
338 #ifdef CONFIG_VIDEO_RETAIN
339@@ -280,6 +281,7 @@ dac_done:
340
341 movw %es, %fs:(PARAM_VESAPM_SEG)
342 movw %di, %fs:(PARAM_VESAPM_OFF)
343+ movw %cx, %fs:(PARAM_VESAPM_SIZE)
344 no_pm: ret
345
346 # The video mode menu
347diff -urNp linux-2.6.22.1/arch/i386/Kconfig linux-2.6.22.1/arch/i386/Kconfig
348--- linux-2.6.22.1/arch/i386/Kconfig 2007-07-10 14:56:30.000000000 -0400
349+++ linux-2.6.22.1/arch/i386/Kconfig 2007-08-03 12:36:16.000000000 -0400
350@@ -586,7 +586,7 @@ config PAGE_OFFSET
351 hex
352 default 0xB0000000 if VMSPLIT_3G_OPT
353 default 0x80000000 if VMSPLIT_2G
354- default 0x78000000 if VMSPLIT_2G_OPT
355+ default 0x70000000 if VMSPLIT_2G_OPT
356 default 0x40000000 if VMSPLIT_1G
357 default 0xC0000000
358
359@@ -815,7 +815,7 @@ config CRASH_DUMP
360
361 config PHYSICAL_START
362 hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
363- default "0x100000"
364+ default "0x200000"
365 help
366 This gives the physical address where the kernel is loaded.
367
368@@ -900,7 +900,7 @@ config HOTPLUG_CPU
369
370 config COMPAT_VDSO
371 bool "Compat VDSO support"
372- default y
373+ default n
374 help
375 Map the VDSO to the predictable old-style address too.
376 ---help---
377diff -urNp linux-2.6.22.1/arch/i386/Kconfig.cpu linux-2.6.22.1/arch/i386/Kconfig.cpu
378--- linux-2.6.22.1/arch/i386/Kconfig.cpu 2007-07-10 14:56:30.000000000 -0400
379+++ linux-2.6.22.1/arch/i386/Kconfig.cpu 2007-08-02 11:38:45.000000000 -0400
380@@ -274,7 +274,7 @@ config X86_PPRO_FENCE
381
382 config X86_F00F_BUG
383 bool
384- depends on M586MMX || M586TSC || M586 || M486 || M386
385+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
386 default y
387
388 config X86_WP_WORKS_OK
389@@ -304,7 +304,7 @@ config X86_CMPXCHG64
390
391 config X86_ALIGNMENT_16
392 bool
393- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
394+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
395 default y
396
397 config X86_GOOD_APIC
398diff -urNp linux-2.6.22.1/arch/i386/Kconfig.debug linux-2.6.22.1/arch/i386/Kconfig.debug
399--- linux-2.6.22.1/arch/i386/Kconfig.debug 2007-07-10 14:56:30.000000000 -0400
400+++ linux-2.6.22.1/arch/i386/Kconfig.debug 2007-08-02 11:38:45.000000000 -0400
401@@ -46,16 +46,6 @@ config DEBUG_PAGEALLOC
402 This results in a large slowdown, but helps to find certain types
403 of memory corruptions.
404
405-config DEBUG_RODATA
406- bool "Write protect kernel read-only data structures"
407- depends on DEBUG_KERNEL
408- help
409- Mark the kernel read-only data as write-protected in the pagetables,
410- in order to catch accidental (and incorrect) writes to such const
411- data. This option may have a slight performance impact because a
412- portion of the kernel code won't be covered by a 2MB TLB anymore.
413- If in doubt, say "N".
414-
415 config 4KSTACKS
416 bool "Use 4Kb for kernel stacks instead of 8Kb"
417 depends on DEBUG_KERNEL
418diff -urNp linux-2.6.22.1/arch/i386/kernel/acpi/boot.c linux-2.6.22.1/arch/i386/kernel/acpi/boot.c
419--- linux-2.6.22.1/arch/i386/kernel/acpi/boot.c 2007-07-10 14:56:30.000000000 -0400
420+++ linux-2.6.22.1/arch/i386/kernel/acpi/boot.c 2007-08-02 11:38:45.000000000 -0400
421@@ -1095,7 +1095,7 @@ static struct dmi_system_id __initdata a
422 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
423 },
424 },
425- {}
426+ { NULL, NULL, {{0, NULL}}, NULL}
427 };
428
429 #endif /* __i386__ */
430diff -urNp linux-2.6.22.1/arch/i386/kernel/acpi/sleep.c linux-2.6.22.1/arch/i386/kernel/acpi/sleep.c
431--- linux-2.6.22.1/arch/i386/kernel/acpi/sleep.c 2007-07-10 14:56:30.000000000 -0400
432+++ linux-2.6.22.1/arch/i386/kernel/acpi/sleep.c 2007-08-02 11:38:45.000000000 -0400
433@@ -94,7 +94,7 @@ static __initdata struct dmi_system_id a
434 DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
435 },
436 },
437- {}
438+ { NULL, NULL, {{0, NULL}}, NULL}
439 };
440
441 static int __init acpisleep_dmi_init(void)
442diff -urNp linux-2.6.22.1/arch/i386/kernel/acpi/wakeup.S linux-2.6.22.1/arch/i386/kernel/acpi/wakeup.S
443--- linux-2.6.22.1/arch/i386/kernel/acpi/wakeup.S 2007-07-10 14:56:30.000000000 -0400
444+++ linux-2.6.22.1/arch/i386/kernel/acpi/wakeup.S 2007-08-02 11:38:45.000000000 -0400
445@@ -2,6 +2,7 @@
446 #include <linux/linkage.h>
447 #include <asm/segment.h>
448 #include <asm/page.h>
449+#include <asm/msr-index.h>
450
451 #
452 # wakeup_code runs in real mode, and at unknown address (determined at run-time).
453@@ -64,7 +65,7 @@ wakeup_code:
454 # restore efer setting
455 movl real_save_efer_edx - wakeup_code, %edx
456 movl real_save_efer_eax - wakeup_code, %eax
457- mov $0xc0000080, %ecx
458+ mov $MSR_EFER, %ecx
459 wrmsr
460 4:
461 # make sure %cr4 is set correctly (features, etc)
462@@ -205,13 +206,11 @@ wakeup_pmode_return:
463 # and restore the stack ... but you need gdt for this to work
464 movl saved_context_esp, %esp
465
466- movl %cs:saved_magic, %eax
467- cmpl $0x12345678, %eax
468+ cmpl $0x12345678, saved_magic
469 jne bogus_magic
470
471 # jump to place where we left off
472- movl saved_eip,%eax
473- jmp *%eax
474+ jmp *(saved_eip)
475
476 bogus_magic:
477 movw $0x0e00 + 'B', 0xb8018
478@@ -243,7 +242,7 @@ ENTRY(acpi_copy_wakeup_routine)
479 # save efer setting
480 pushl %eax
481 movl %eax, %ebx
482- mov $0xc0000080, %ecx
483+ mov $MSR_EFER, %ecx
484 rdmsr
485 movl %edx, real_save_efer_edx - wakeup_start (%ebx)
486 movl %eax, real_save_efer_eax - wakeup_start (%ebx)
487diff -urNp linux-2.6.22.1/arch/i386/kernel/alternative.c linux-2.6.22.1/arch/i386/kernel/alternative.c
488--- linux-2.6.22.1/arch/i386/kernel/alternative.c 2007-07-10 14:56:30.000000000 -0400
489+++ linux-2.6.22.1/arch/i386/kernel/alternative.c 2007-08-02 11:38:45.000000000 -0400
490@@ -4,6 +4,7 @@
491 #include <linux/list.h>
492 #include <asm/alternative.h>
493 #include <asm/sections.h>
494+#include <asm/desc.h>
495
496 static int noreplace_smp = 0;
497 static int smp_alt_once = 0;
498@@ -165,12 +166,18 @@ void apply_alternatives(struct alt_instr
499 u8 *instr;
500 int diff;
501
502+#ifdef CONFIG_PAX_KERNEXEC
503+ unsigned long cr0;
504+
505+ pax_open_kernel(cr0);
506+#endif
507+
508 DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
509 for (a = start; a < end; a++) {
510 BUG_ON(a->replacementlen > a->instrlen);
511 if (!boot_cpu_has(a->cpuid))
512 continue;
513- instr = a->instr;
514+ instr = a->instr + __KERNEL_TEXT_OFFSET;
515 #ifdef CONFIG_X86_64
516 /* vsyscall code is not mapped yet. resolve it manually. */
517 if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
518@@ -183,6 +190,11 @@ void apply_alternatives(struct alt_instr
519 diff = a->instrlen - a->replacementlen;
520 nop_out(instr + a->replacementlen, diff);
521 }
522+
523+#ifdef CONFIG_PAX_KERNEXEC
524+ pax_close_kernel(cr0);
525+#endif
526+
527 }
528
529 #ifdef CONFIG_SMP
530@@ -191,29 +203,53 @@ static void alternatives_smp_lock(u8 **s
531 {
532 u8 **ptr;
533
534+#ifdef CONFIG_PAX_KERNEXEC
535+ unsigned long cr0;
536+
537+ pax_open_kernel(cr0);
538+#endif
539+
540 for (ptr = start; ptr < end; ptr++) {
541 if (*ptr < text)
542 continue;
543 if (*ptr > text_end)
544 continue;
545- **ptr = 0xf0; /* lock prefix */
546- };
547+ *(*ptr + __KERNEL_TEXT_OFFSET) = 0xf0; /* lock prefix */
548+ }
549+
550+#ifdef CONFIG_PAX_KERNEXEC
551+ pax_close_kernel(cr0);
552+#endif
553+
554 }
555
556 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
557 {
558 u8 **ptr;
559
560+#ifdef CONFIG_PAX_KERNEXEC
561+ unsigned long cr0;
562+#endif
563+
564 if (noreplace_smp)
565 return;
566
567+#ifdef CONFIG_PAX_KERNEXEC
568+ pax_open_kernel(cr0);
569+#endif
570+
571 for (ptr = start; ptr < end; ptr++) {
572 if (*ptr < text)
573 continue;
574 if (*ptr > text_end)
575 continue;
576- nop_out(*ptr, 1);
577- };
578+ nop_out(*ptr + __KERNEL_TEXT_OFFSET, 1);
579+ }
580+
581+#ifdef CONFIG_PAX_KERNEXEC
582+ pax_close_kernel(cr0);
583+#endif
584+
585 }
586
587 struct smp_alt_module {
588@@ -340,21 +376,34 @@ void apply_paravirt(struct paravirt_patc
589 {
590 struct paravirt_patch_site *p;
591
592+#ifdef CONFIG_PAX_KERNEXEC
593+ unsigned long cr0;
594+#endif
595+
596 if (noreplace_paravirt)
597 return;
598
599+#ifdef CONFIG_PAX_KERNEXEC
600+ pax_open_kernel(cr0);
601+#endif
602+
603 for (p = start; p < end; p++) {
604 unsigned int used;
605+ u8 *instr = p->instr + __KERNEL_TEXT_OFFSET;
606
607- used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr,
608+ used = paravirt_ops.patch(p->instrtype, p->clobbers, instr,
609 p->len);
610
611 BUG_ON(used > p->len);
612
613 /* Pad the rest with nops */
614- nop_out(p->instr + used, p->len - used);
615+ nop_out(instr + used, p->len - used);
616 }
617
618+#ifdef CONFIG_PAX_KERNEXEC
619+ pax_close_kernel(cr0);
620+#endif
621+
622 /* Sync to be conservative, in case we patched following
623 * instructions */
624 sync_core();
625diff -urNp linux-2.6.22.1/arch/i386/kernel/apm.c linux-2.6.22.1/arch/i386/kernel/apm.c
626--- linux-2.6.22.1/arch/i386/kernel/apm.c 2007-07-10 14:56:30.000000000 -0400
627+++ linux-2.6.22.1/arch/i386/kernel/apm.c 2007-08-02 11:38:45.000000000 -0400
628@@ -600,9 +600,18 @@ static u8 apm_bios_call(u32 func, u32 eb
629 struct desc_struct save_desc_40;
630 struct desc_struct *gdt;
631
632+#ifdef CONFIG_PAX_KERNEXEC
633+ unsigned long cr0;
634+#endif
635+
636 cpus = apm_save_cpus();
637
638 cpu = get_cpu();
639+
640+#ifdef CONFIG_PAX_KERNEXEC
641+ pax_open_kernel(cr0);
642+#endif
643+
644 gdt = get_cpu_gdt_table(cpu);
645 save_desc_40 = gdt[0x40 / 8];
646 gdt[0x40 / 8] = bad_bios_desc;
647@@ -613,6 +622,11 @@ static u8 apm_bios_call(u32 func, u32 eb
648 APM_DO_RESTORE_SEGS;
649 apm_irq_restore(flags);
650 gdt[0x40 / 8] = save_desc_40;
651+
652+#ifdef CONFIG_PAX_KERNEXEC
653+ pax_close_kernel(cr0);
654+#endif
655+
656 put_cpu();
657 apm_restore_cpus(cpus);
658
659@@ -643,9 +657,18 @@ static u8 apm_bios_call_simple(u32 func,
660 struct desc_struct save_desc_40;
661 struct desc_struct *gdt;
662
663+#ifdef CONFIG_PAX_KERNEXEC
664+ unsigned long cr0;
665+#endif
666+
667 cpus = apm_save_cpus();
668
669 cpu = get_cpu();
670+
671+#ifdef CONFIG_PAX_KERNEXEC
672+ pax_open_kernel(cr0);
673+#endif
674+
675 gdt = get_cpu_gdt_table(cpu);
676 save_desc_40 = gdt[0x40 / 8];
677 gdt[0x40 / 8] = bad_bios_desc;
678@@ -656,6 +679,11 @@ static u8 apm_bios_call_simple(u32 func,
679 APM_DO_RESTORE_SEGS;
680 apm_irq_restore(flags);
681 gdt[0x40 / 8] = save_desc_40;
682+
683+#ifdef CONFIG_PAX_KERNEXEC
684+ pax_close_kernel(cr0);
685+#endif
686+
687 put_cpu();
688 apm_restore_cpus(cpus);
689 return error;
690@@ -923,7 +951,7 @@ recalc:
691
692 static void apm_power_off(void)
693 {
694- unsigned char po_bios_call[] = {
695+ const unsigned char po_bios_call[] = {
696 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
697 0x8e, 0xd0, /* movw ax,ss */
698 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
699@@ -1863,7 +1891,10 @@ static const struct file_operations apm_
700 static struct miscdevice apm_device = {
701 APM_MINOR_DEV,
702 "apm_bios",
703- &apm_bios_fops
704+ &apm_bios_fops,
705+ {NULL, NULL},
706+ NULL,
707+ NULL
708 };
709
710
711@@ -1973,210 +2004,210 @@ static struct dmi_system_id __initdata a
712 print_if_true,
713 KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
714 { DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
715- DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
716+ DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL
717 },
718 { /* Handle problems with APM on the C600 */
719 broken_ps2_resume, "Dell Latitude C600",
720 { DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
721- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
722+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL
723 },
724 { /* Allow interrupts during suspend on Dell Latitude laptops*/
725 set_apm_ints, "Dell Latitude",
726 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
727- DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
728+ DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL
729 },
730 { /* APM crashes */
731 apm_is_horked, "Dell Inspiron 2500",
732 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
733 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
734 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
735- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
736+ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
737 },
738 { /* Allow interrupts during suspend on Dell Inspiron laptops*/
739 set_apm_ints, "Dell Inspiron", {
740 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
741- DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
742+ DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL
743 },
744 { /* Handle problems with APM on Inspiron 5000e */
745 broken_apm_power, "Dell Inspiron 5000e",
746 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
747 DMI_MATCH(DMI_BIOS_VERSION, "A04"),
748- DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
749+ DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL
750 },
751 { /* Handle problems with APM on Inspiron 2500 */
752 broken_apm_power, "Dell Inspiron 2500",
753 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
754 DMI_MATCH(DMI_BIOS_VERSION, "A12"),
755- DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
756+ DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL
757 },
758 { /* APM crashes */
759 apm_is_horked, "Dell Dimension 4100",
760 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
761 DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
762 DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
763- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
764+ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
765 },
766 { /* Allow interrupts during suspend on Compaq Laptops*/
767 set_apm_ints, "Compaq 12XL125",
768 { DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
769 DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
770 DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
771- DMI_MATCH(DMI_BIOS_VERSION,"4.06"), },
772+ DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL
773 },
774 { /* Allow interrupts during APM or the clock goes slow */
775 set_apm_ints, "ASUSTeK",
776 { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
777- DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
778+ DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL
779 },
780 { /* APM blows on shutdown */
781 apm_is_horked, "ABIT KX7-333[R]",
782 { DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
783- DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
784+ DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL
785 },
786 { /* APM crashes */
787 apm_is_horked, "Trigem Delhi3",
788 { DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
789- DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
790+ DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL
791 },
792 { /* APM crashes */
793 apm_is_horked, "Fujitsu-Siemens",
794 { DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
795- DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
796+ DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL
797 },
798 { /* APM crashes */
799 apm_is_horked_d850md, "Intel D850MD",
800 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
801- DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
802+ DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL
803 },
804 { /* APM crashes */
805 apm_is_horked, "Intel D810EMO",
806 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
807- DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
808+ DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL
809 },
810 { /* APM crashes */
811 apm_is_horked, "Dell XPS-Z",
812 { DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
813 DMI_MATCH(DMI_BIOS_VERSION, "A11"),
814- DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
815+ DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL
816 },
817 { /* APM crashes */
818 apm_is_horked, "Sharp PC-PJ/AX",
819 { DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
820 DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
821 DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
822- DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), },
823+ DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL
824 },
825 { /* APM crashes */
826 apm_is_horked, "Dell Inspiron 2500",
827 { DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
828 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
829 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
830- DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
831+ DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
832 },
833 { /* APM idle hangs */
834 apm_likes_to_melt, "Jabil AMD",
835 { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
836- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
837+ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL
838 },
839 { /* APM idle hangs */
840 apm_likes_to_melt, "AMI Bios",
841 { DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
842- DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
843+ DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL
844 },
845 { /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
846 swab_apm_power_in_minutes, "Sony VAIO",
847 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
848 DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
849- DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
850+ DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL
851 },
852 { /* Handle problems with APM on Sony Vaio PCG-N505VX */
853 swab_apm_power_in_minutes, "Sony VAIO",
854 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
855 DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
856- DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
857+ DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL
858 },
859 { /* Handle problems with APM on Sony Vaio PCG-XG29 */
860 swab_apm_power_in_minutes, "Sony VAIO",
861 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
862 DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
863- DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
864+ DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL
865 },
866 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
867 swab_apm_power_in_minutes, "Sony VAIO",
868 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
869 DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
870- DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
871+ DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL
872 },
873 { /* Handle problems with APM on Sony Vaio PCG-Z600NE */
874 swab_apm_power_in_minutes, "Sony VAIO",
875 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
876 DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
877- DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
878+ DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL
879 },
880 { /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
881 swab_apm_power_in_minutes, "Sony VAIO",
882 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
883 DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
884- DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
885+ DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL
886 },
887 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
888 swab_apm_power_in_minutes, "Sony VAIO",
889 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
890 DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
891- DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
892+ DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL
893 },
894 { /* Handle problems with APM on Sony Vaio PCG-Z505LS */
895 swab_apm_power_in_minutes, "Sony VAIO",
896 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
897 DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
898- DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
899+ DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL
900 },
901 { /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
902 swab_apm_power_in_minutes, "Sony VAIO",
903 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
904 DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
905- DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
906+ DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL
907 },
908 { /* Handle problems with APM on Sony Vaio PCG-F104K */
909 swab_apm_power_in_minutes, "Sony VAIO",
910 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
911 DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
912- DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
913+ DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL
914 },
915
916 { /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
917 swab_apm_power_in_minutes, "Sony VAIO",
918 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
919 DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
920- DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
921+ DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL
922 },
923 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
924 swab_apm_power_in_minutes, "Sony VAIO",
925 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
926 DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
927- DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
928+ DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL
929 },
930 { /* Handle problems with APM on Sony Vaio PCG-C1VE */
931 swab_apm_power_in_minutes, "Sony VAIO",
932 { DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
933 DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
934- DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
935+ DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL
936 },
937 { /* broken PM poweroff bios */
938 set_realmode_power_off, "Award Software v4.60 PGMA",
939 { DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
940 DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
941- DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
942+ DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL
943 },
944
945 /* Generic per vendor APM settings */
946
947 { /* Allow interrupts during suspend on IBM laptops */
948 set_apm_ints, "IBM",
949- { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
950+ { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL
951 },
952
953- { }
954+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
955 };
956
957 /*
958@@ -2195,6 +2226,10 @@ static int __init apm_init(void)
959 struct desc_struct *gdt;
960 int err;
961
962+#ifdef CONFIG_PAX_KERNEXEC
963+ unsigned long cr0;
964+#endif
965+
966 dmi_check_system(apm_dmi_table);
967
968 if (apm_info.bios.version == 0 || paravirt_enabled()) {
969@@ -2291,6 +2326,11 @@ static int __init apm_init(void)
970 * code to that CPU.
971 */
972 gdt = get_cpu_gdt_table(0);
973+
974+#ifdef CONFIG_PAX_KERNEXEC
975+ pax_open_kernel(cr0);
976+#endif
977+
978 set_base(gdt[APM_CS >> 3],
979 __va((unsigned long)apm_info.bios.cseg << 4));
980 set_base(gdt[APM_CS_16 >> 3],
981@@ -2298,6 +2338,10 @@ static int __init apm_init(void)
982 set_base(gdt[APM_DS >> 3],
983 __va((unsigned long)apm_info.bios.dseg << 4));
984
985+#ifdef CONFIG_PAX_KERNEXEC
986+ pax_close_kernel(cr0);
987+#endif
988+
989 apm_proc = create_proc_entry("apm", 0, NULL);
990 if (apm_proc)
991 apm_proc->proc_fops = &apm_file_ops;
992diff -urNp linux-2.6.22.1/arch/i386/kernel/asm-offsets.c linux-2.6.22.1/arch/i386/kernel/asm-offsets.c
993--- linux-2.6.22.1/arch/i386/kernel/asm-offsets.c 2007-07-10 14:56:30.000000000 -0400
994+++ linux-2.6.22.1/arch/i386/kernel/asm-offsets.c 2007-08-02 11:38:45.000000000 -0400
995@@ -55,6 +55,7 @@ void foo(void)
996 OFFSET(TI_exec_domain, thread_info, exec_domain);
997 OFFSET(TI_flags, thread_info, flags);
998 OFFSET(TI_status, thread_info, status);
999+ OFFSET(TI_cpu, thread_info, cpu);
1000 OFFSET(TI_preempt_count, thread_info, preempt_count);
1001 OFFSET(TI_addr_limit, thread_info, addr_limit);
1002 OFFSET(TI_restart_block, thread_info, restart_block);
1003@@ -101,6 +102,7 @@ void foo(void)
1004 DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
1005 DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
1006 DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
1007+ DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
1008
1009 DEFINE(VDSO_PRELINK_asm, VDSO_PRELINK);
1010
1011@@ -114,5 +116,6 @@ void foo(void)
1012 OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
1013 OFFSET(PARAVIRT_iret, paravirt_ops, iret);
1014 OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
1015+ OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0);
1016 #endif
1017 }
1018diff -urNp linux-2.6.22.1/arch/i386/kernel/cpu/common.c linux-2.6.22.1/arch/i386/kernel/cpu/common.c
1019--- linux-2.6.22.1/arch/i386/kernel/cpu/common.c 2007-07-10 14:56:30.000000000 -0400
1020+++ linux-2.6.22.1/arch/i386/kernel/cpu/common.c 2007-08-02 11:38:45.000000000 -0400
1021@@ -4,7 +4,6 @@
1022 #include <linux/smp.h>
1023 #include <linux/module.h>
1024 #include <linux/percpu.h>
1025-#include <linux/bootmem.h>
1026 #include <asm/semaphore.h>
1027 #include <asm/processor.h>
1028 #include <asm/i387.h>
1029@@ -21,39 +20,15 @@
1030
1031 #include "cpu.h"
1032
1033-DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
1034- [GDT_ENTRY_KERNEL_CS] = { 0x0000ffff, 0x00cf9a00 },
1035- [GDT_ENTRY_KERNEL_DS] = { 0x0000ffff, 0x00cf9200 },
1036- [GDT_ENTRY_DEFAULT_USER_CS] = { 0x0000ffff, 0x00cffa00 },
1037- [GDT_ENTRY_DEFAULT_USER_DS] = { 0x0000ffff, 0x00cff200 },
1038- /*
1039- * Segments used for calling PnP BIOS have byte granularity.
1040- * They code segments and data segments have fixed 64k limits,
1041- * the transfer segment sizes are set at run time.
1042- */
1043- [GDT_ENTRY_PNPBIOS_CS32] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
1044- [GDT_ENTRY_PNPBIOS_CS16] = { 0x0000ffff, 0x00009a00 },/* 16-bit code */
1045- [GDT_ENTRY_PNPBIOS_DS] = { 0x0000ffff, 0x00009200 }, /* 16-bit data */
1046- [GDT_ENTRY_PNPBIOS_TS1] = { 0x00000000, 0x00009200 },/* 16-bit data */
1047- [GDT_ENTRY_PNPBIOS_TS2] = { 0x00000000, 0x00009200 },/* 16-bit data */
1048- /*
1049- * The APM segments have byte granularity and their bases
1050- * are set at run time. All have 64k limits.
1051- */
1052- [GDT_ENTRY_APMBIOS_BASE] = { 0x0000ffff, 0x00409a00 },/* 32-bit code */
1053- /* 16-bit code */
1054- [GDT_ENTRY_APMBIOS_BASE+1] = { 0x0000ffff, 0x00009a00 },
1055- [GDT_ENTRY_APMBIOS_BASE+2] = { 0x0000ffff, 0x00409200 }, /* data */
1056-
1057- [GDT_ENTRY_ESPFIX_SS] = { 0x00000000, 0x00c09200 },
1058- [GDT_ENTRY_PERCPU] = { 0x00000000, 0x00000000 },
1059-} };
1060-EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
1061-
1062 static int cachesize_override __cpuinitdata = -1;
1063 static int disable_x86_fxsr __cpuinitdata;
1064 static int disable_x86_serial_nr __cpuinitdata = 1;
1065-static int disable_x86_sep __cpuinitdata;
1066+
1067+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1068+int disable_x86_sep __cpuinitdata = 1;
1069+#else
1070+int disable_x86_sep __cpuinitdata;
1071+#endif
1072
1073 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
1074
1075@@ -261,10 +236,10 @@ static int __cpuinit have_cpuid_p(void)
1076 void __init cpu_detect(struct cpuinfo_x86 *c)
1077 {
1078 /* Get vendor name */
1079- cpuid(0x00000000, &c->cpuid_level,
1080- (int *)&c->x86_vendor_id[0],
1081- (int *)&c->x86_vendor_id[8],
1082- (int *)&c->x86_vendor_id[4]);
1083+ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
1084+ (unsigned int *)&c->x86_vendor_id[0],
1085+ (unsigned int *)&c->x86_vendor_id[8],
1086+ (unsigned int *)&c->x86_vendor_id[4]);
1087
1088 c->x86 = 4;
1089 if (c->cpuid_level >= 0x00000001) {
1090@@ -304,15 +279,14 @@ static void __init early_cpu_detect(void
1091
1092 static void __cpuinit generic_identify(struct cpuinfo_x86 * c)
1093 {
1094- u32 tfms, xlvl;
1095- int ebx;
1096+ u32 tfms, xlvl, ebx;
1097
1098 if (have_cpuid_p()) {
1099 /* Get vendor name */
1100- cpuid(0x00000000, &c->cpuid_level,
1101- (int *)&c->x86_vendor_id[0],
1102- (int *)&c->x86_vendor_id[8],
1103- (int *)&c->x86_vendor_id[4]);
1104+ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
1105+ (unsigned int *)&c->x86_vendor_id[0],
1106+ (unsigned int *)&c->x86_vendor_id[8],
1107+ (unsigned int *)&c->x86_vendor_id[4]);
1108
1109 get_cpu_vendor(c, 0);
1110 /* Initialize the standard set of capabilities */
1111@@ -644,7 +618,7 @@ void switch_to_new_gdt(void)
1112 {
1113 struct Xgt_desc_struct gdt_descr;
1114
1115- gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
1116+ gdt_descr.address = get_cpu_gdt_table(smp_processor_id());
1117 gdt_descr.size = GDT_SIZE - 1;
1118 load_gdt(&gdt_descr);
1119 asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
1120@@ -660,7 +634,7 @@ void __cpuinit cpu_init(void)
1121 {
1122 int cpu = smp_processor_id();
1123 struct task_struct *curr = current;
1124- struct tss_struct * t = &per_cpu(init_tss, cpu);
1125+ struct tss_struct *t = init_tss + cpu;
1126 struct thread_struct *thread = &curr->thread;
1127
1128 if (cpu_test_and_set(cpu, cpu_initialized)) {
1129diff -urNp linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
1130--- linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-07-10 14:56:30.000000000 -0400
1131+++ linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c 2007-08-02 11:38:45.000000000 -0400
1132@@ -563,7 +563,7 @@ static struct dmi_system_id sw_any_bug_d
1133 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1134 },
1135 },
1136- { }
1137+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1138 };
1139 #endif
1140
1141diff -urNp linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
1142--- linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-07-10 14:56:30.000000000 -0400
1143+++ linux-2.6.22.1/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c 2007-08-02 11:38:45.000000000 -0400
1144@@ -229,7 +229,7 @@ static struct cpu_model models[] =
1145 { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
1146 { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
1147
1148- { NULL, }
1149+ { NULL, NULL, 0, NULL}
1150 };
1151 #undef _BANIAS
1152 #undef BANIAS
1153@@ -404,7 +404,7 @@ static struct dmi_system_id sw_any_bug_d
1154 DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1155 },
1156 },
1157- { }
1158+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1159 };
1160 #endif
1161
1162diff -urNp linux-2.6.22.1/arch/i386/kernel/cpu/intel_cacheinfo.c linux-2.6.22.1/arch/i386/kernel/cpu/intel_cacheinfo.c
1163--- linux-2.6.22.1/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-07-10 14:56:30.000000000 -0400
1164+++ linux-2.6.22.1/arch/i386/kernel/cpu/intel_cacheinfo.c 2007-08-02 11:38:45.000000000 -0400
1165@@ -318,8 +318,8 @@ unsigned int __cpuinit init_intel_cachei
1166 */
1167 if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) {
1168 /* supports eax=2 call */
1169- int i, j, n;
1170- int regs[4];
1171+ int j, n;
1172+ unsigned int regs[4];
1173 unsigned char *dp = (unsigned char *)regs;
1174 int only_trace = 0;
1175
1176@@ -334,7 +334,7 @@ unsigned int __cpuinit init_intel_cachei
1177
1178 /* If bit 31 is set, this is an unknown format */
1179 for ( j = 0 ; j < 3 ; j++ ) {
1180- if ( regs[j] < 0 ) regs[j] = 0;
1181+ if ( (int)regs[j] < 0 ) regs[j] = 0;
1182 }
1183
1184 /* Byte 0 is level count, not a descriptor */
1185diff -urNp linux-2.6.22.1/arch/i386/kernel/cpu/mcheck/therm_throt.c linux-2.6.22.1/arch/i386/kernel/cpu/mcheck/therm_throt.c
1186--- linux-2.6.22.1/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-07-10 14:56:30.000000000 -0400
1187+++ linux-2.6.22.1/arch/i386/kernel/cpu/mcheck/therm_throt.c 2007-08-02 11:38:45.000000000 -0400
1188@@ -150,7 +150,7 @@ static __cpuinit int thermal_throttle_cp
1189 return NOTIFY_OK;
1190 }
1191
1192-static struct notifier_block thermal_throttle_cpu_notifier =
1193+static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier =
1194 {
1195 .notifier_call = thermal_throttle_cpu_callback,
1196 };
1197diff -urNp linux-2.6.22.1/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.22.1/arch/i386/kernel/cpu/mtrr/generic.c
1198--- linux-2.6.22.1/arch/i386/kernel/cpu/mtrr/generic.c 2007-07-10 14:56:30.000000000 -0400
1199+++ linux-2.6.22.1/arch/i386/kernel/cpu/mtrr/generic.c 2007-08-02 11:38:45.000000000 -0400
1200@@ -29,11 +29,11 @@ static struct fixed_range_block fixed_ra
1201 { MTRRfix64K_00000_MSR, 1 }, /* one 64k MTRR */
1202 { MTRRfix16K_80000_MSR, 2 }, /* two 16k MTRRs */
1203 { MTRRfix4K_C0000_MSR, 8 }, /* eight 4k MTRRs */
1204- {}
1205+ { 0, 0 }
1206 };
1207
1208 static unsigned long smp_changes_mask;
1209-static struct mtrr_state mtrr_state = {};
1210+static struct mtrr_state mtrr_state;
1211
1212 #undef MODULE_PARAM_PREFIX
1213 #define MODULE_PARAM_PREFIX "mtrr."
1214@@ -79,7 +79,7 @@ static void print_fixed(unsigned base, u
1215 }
1216
1217 /* Grab all of the MTRR state for this CPU into *state */
1218-void get_mtrr_state(void)
1219+void __init get_mtrr_state(void)
1220 {
1221 unsigned int i;
1222 struct mtrr_var_range *vrs;
1223diff -urNp linux-2.6.22.1/arch/i386/kernel/crash.c linux-2.6.22.1/arch/i386/kernel/crash.c
1224--- linux-2.6.22.1/arch/i386/kernel/crash.c 2007-07-10 14:56:30.000000000 -0400
1225+++ linux-2.6.22.1/arch/i386/kernel/crash.c 2007-08-02 11:38:45.000000000 -0400
1226@@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not
1227 return NOTIFY_STOP;
1228 local_irq_disable();
1229
1230- if (!user_mode_vm(regs)) {
1231+ if (!user_mode(regs)) {
1232 crash_fixup_ss_esp(&fixed_regs, regs);
1233 regs = &fixed_regs;
1234 }
1235diff -urNp linux-2.6.22.1/arch/i386/kernel/doublefault.c linux-2.6.22.1/arch/i386/kernel/doublefault.c
1236--- linux-2.6.22.1/arch/i386/kernel/doublefault.c 2007-07-10 14:56:30.000000000 -0400
1237+++ linux-2.6.22.1/arch/i386/kernel/doublefault.c 2007-08-02 11:38:45.000000000 -0400
1238@@ -11,17 +11,17 @@
1239
1240 #define DOUBLEFAULT_STACKSIZE (1024)
1241 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
1242-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
1243+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
1244
1245 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
1246
1247 static void doublefault_fn(void)
1248 {
1249- struct Xgt_desc_struct gdt_desc = {0, 0};
1250+ struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
1251 unsigned long gdt, tss;
1252
1253 store_gdt(&gdt_desc);
1254- gdt = gdt_desc.address;
1255+ gdt = (unsigned long)gdt_desc.address;
1256
1257 printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
1258
1259@@ -59,10 +59,10 @@ struct tss_struct doublefault_tss __cach
1260 /* 0x2 bit is always set */
1261 .eflags = X86_EFLAGS_SF | 0x2,
1262 .esp = STACK_START,
1263- .es = __USER_DS,
1264+ .es = __KERNEL_DS,
1265 .cs = __KERNEL_CS,
1266 .ss = __KERNEL_DS,
1267- .ds = __USER_DS,
1268+ .ds = __KERNEL_DS,
1269 .fs = __KERNEL_PERCPU,
1270
1271 .__cr3 = __pa(swapper_pg_dir)
1272diff -urNp linux-2.6.22.1/arch/i386/kernel/efi.c linux-2.6.22.1/arch/i386/kernel/efi.c
1273--- linux-2.6.22.1/arch/i386/kernel/efi.c 2007-07-10 14:56:30.000000000 -0400
1274+++ linux-2.6.22.1/arch/i386/kernel/efi.c 2007-08-02 11:38:45.000000000 -0400
1275@@ -63,45 +63,23 @@ extern void * boot_ioremap(unsigned long
1276
1277 static unsigned long efi_rt_eflags;
1278 static DEFINE_SPINLOCK(efi_rt_lock);
1279-static pgd_t efi_bak_pg_dir_pointer[2];
1280+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
1281
1282 static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
1283 {
1284- unsigned long cr4;
1285- unsigned long temp;
1286 struct Xgt_desc_struct gdt_descr;
1287
1288 spin_lock(&efi_rt_lock);
1289 local_irq_save(efi_rt_eflags);
1290
1291- /*
1292- * If I don't have PSE, I should just duplicate two entries in page
1293- * directory. If I have PSE, I just need to duplicate one entry in
1294- * page directory.
1295- */
1296- cr4 = read_cr4();
1297-
1298- if (cr4 & X86_CR4_PSE) {
1299- efi_bak_pg_dir_pointer[0].pgd =
1300- swapper_pg_dir[pgd_index(0)].pgd;
1301- swapper_pg_dir[0].pgd =
1302- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1303- } else {
1304- efi_bak_pg_dir_pointer[0].pgd =
1305- swapper_pg_dir[pgd_index(0)].pgd;
1306- efi_bak_pg_dir_pointer[1].pgd =
1307- swapper_pg_dir[pgd_index(0x400000)].pgd;
1308- swapper_pg_dir[pgd_index(0)].pgd =
1309- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1310- temp = PAGE_OFFSET + 0x400000;
1311- swapper_pg_dir[pgd_index(0x400000)].pgd =
1312- swapper_pg_dir[pgd_index(temp)].pgd;
1313- }
1314+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
1315+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1316+ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
1317
1318 /*
1319 * After the lock is released, the original page table is restored.
1320 */
1321- local_flush_tlb();
1322+ __flush_tlb_all();
1323
1324 gdt_descr.address = __pa(get_cpu_gdt_table(0));
1325 gdt_descr.size = GDT_SIZE - 1;
1326@@ -110,35 +88,24 @@ static void efi_call_phys_prelog(void) _
1327
1328 static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
1329 {
1330- unsigned long cr4;
1331 struct Xgt_desc_struct gdt_descr;
1332
1333- gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
1334+ gdt_descr.address = get_cpu_gdt_table(0);
1335 gdt_descr.size = GDT_SIZE - 1;
1336 load_gdt(&gdt_descr);
1337
1338- cr4 = read_cr4();
1339-
1340- if (cr4 & X86_CR4_PSE) {
1341- swapper_pg_dir[pgd_index(0)].pgd =
1342- efi_bak_pg_dir_pointer[0].pgd;
1343- } else {
1344- swapper_pg_dir[pgd_index(0)].pgd =
1345- efi_bak_pg_dir_pointer[0].pgd;
1346- swapper_pg_dir[pgd_index(0x400000)].pgd =
1347- efi_bak_pg_dir_pointer[1].pgd;
1348- }
1349+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
1350
1351 /*
1352 * After the lock is released, the original page table is restored.
1353 */
1354- local_flush_tlb();
1355+ __flush_tlb_all();
1356
1357 local_irq_restore(efi_rt_eflags);
1358 spin_unlock(&efi_rt_lock);
1359 }
1360
1361-static efi_status_t
1362+static efi_status_t __init
1363 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
1364 unsigned long descriptor_size,
1365 u32 descriptor_version,
1366@@ -154,7 +121,7 @@ phys_efi_set_virtual_address_map(unsigne
1367 return status;
1368 }
1369
1370-static efi_status_t
1371+static efi_status_t __init
1372 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
1373 {
1374 efi_status_t status;
1375diff -urNp linux-2.6.22.1/arch/i386/kernel/efi_stub.S linux-2.6.22.1/arch/i386/kernel/efi_stub.S
1376--- linux-2.6.22.1/arch/i386/kernel/efi_stub.S 2007-07-10 14:56:30.000000000 -0400
1377+++ linux-2.6.22.1/arch/i386/kernel/efi_stub.S 2007-08-02 11:38:45.000000000 -0400
1378@@ -6,6 +6,7 @@
1379 */
1380
1381 #include <linux/linkage.h>
1382+#include <linux/init.h>
1383 #include <asm/page.h>
1384
1385 /*
1386@@ -20,7 +21,7 @@
1387 * service functions will comply with gcc calling convention, too.
1388 */
1389
1390-.text
1391+__INIT
1392 ENTRY(efi_call_phys)
1393 /*
1394 * 0. The function can only be called in Linux kernel. So CS has been
1395@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
1396 * The mapping of lower virtual memory has been created in prelog and
1397 * epilog.
1398 */
1399- movl $1f, %edx
1400- subl $__PAGE_OFFSET, %edx
1401- jmp *%edx
1402+ jmp 1f-__PAGE_OFFSET
1403 1:
1404
1405 /*
1406@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
1407 * parameter 2, ..., param n. To make things easy, we save the return
1408 * address of efi_call_phys in a global variable.
1409 */
1410- popl %edx
1411- movl %edx, saved_return_addr
1412- /* get the function pointer into ECX*/
1413- popl %ecx
1414- movl %ecx, efi_rt_function_ptr
1415- movl $2f, %edx
1416- subl $__PAGE_OFFSET, %edx
1417- pushl %edx
1418+ popl (saved_return_addr)
1419+ popl (efi_rt_function_ptr)
1420
1421 /*
1422 * 3. Clear PG bit in %CR0.
1423@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
1424 /*
1425 * 5. Call the physical function.
1426 */
1427- jmp *%ecx
1428+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
1429
1430-2:
1431 /*
1432 * 6. After EFI runtime service returns, control will return to
1433 * following instruction. We'd better readjust stack pointer first.
1434@@ -85,37 +77,29 @@ ENTRY(efi_call_phys)
1435 /*
1436 * 7. Restore PG bit
1437 */
1438- movl %cr0, %edx
1439- orl $0x80000000, %edx
1440- movl %edx, %cr0
1441- jmp 1f
1442-1:
1443 /*
1444 * 8. Now restore the virtual mode from flat mode by
1445 * adding EIP with PAGE_OFFSET.
1446 */
1447- movl $1f, %edx
1448- jmp *%edx
1449+ movl %cr0, %edx
1450+ orl $0x80000000, %edx
1451+ movl %edx, %cr0
1452+ jmp 1f+__PAGE_OFFSET
1453 1:
1454
1455 /*
1456 * 9. Balance the stack. And because EAX contain the return value,
1457 * we'd better not clobber it.
1458 */
1459- leal efi_rt_function_ptr, %edx
1460- movl (%edx), %ecx
1461- pushl %ecx
1462+ pushl (efi_rt_function_ptr)
1463
1464 /*
1465- * 10. Push the saved return address onto the stack and return.
1466+ * 10. Return to the saved return address.
1467 */
1468- leal saved_return_addr, %edx
1469- movl (%edx), %ecx
1470- pushl %ecx
1471- ret
1472+ jmpl *(saved_return_addr)
1473 .previous
1474
1475-.data
1476+__INITDATA
1477 saved_return_addr:
1478 .long 0
1479 efi_rt_function_ptr:
1480diff -urNp linux-2.6.22.1/arch/i386/kernel/entry.S linux-2.6.22.1/arch/i386/kernel/entry.S
1481--- linux-2.6.22.1/arch/i386/kernel/entry.S 2007-07-10 14:56:30.000000000 -0400
1482+++ linux-2.6.22.1/arch/i386/kernel/entry.S 2007-08-02 11:38:45.000000000 -0400
1483@@ -97,7 +97,7 @@ VM_MASK = 0x00020000
1484 #define resume_userspace_sig resume_userspace
1485 #endif
1486
1487-#define SAVE_ALL \
1488+#define __SAVE_ALL(_DS) \
1489 cld; \
1490 pushl %fs; \
1491 CFI_ADJUST_CFA_OFFSET 4;\
1492@@ -129,12 +129,26 @@ VM_MASK = 0x00020000
1493 pushl %ebx; \
1494 CFI_ADJUST_CFA_OFFSET 4;\
1495 CFI_REL_OFFSET ebx, 0;\
1496- movl $(__USER_DS), %edx; \
1497+ movl $(_DS), %edx; \
1498 movl %edx, %ds; \
1499 movl %edx, %es; \
1500 movl $(__KERNEL_PERCPU), %edx; \
1501 movl %edx, %fs
1502
1503+#ifdef CONFIG_PAX_KERNEXEC
1504+#define SAVE_ALL \
1505+ __SAVE_ALL(__KERNEL_DS); \
1506+ GET_CR0_INTO_EDX; \
1507+ movl %edx, %esi; \
1508+ orl $X86_CR0_WP, %edx; \
1509+ xorl %edx, %esi; \
1510+ SET_CR0_FROM_EDX
1511+#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1512+#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1513+#else
1514+#define SAVE_ALL __SAVE_ALL(__USER_DS)
1515+#endif
1516+
1517 #define RESTORE_INT_REGS \
1518 popl %ebx; \
1519 CFI_ADJUST_CFA_OFFSET -4;\
1520@@ -248,7 +262,17 @@ check_userspace:
1521 movb PT_CS(%esp), %al
1522 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
1523 cmpl $USER_RPL, %eax
1524+
1525+#ifdef CONFIG_PAX_KERNEXEC
1526+ jae resume_userspace
1527+
1528+ GET_CR0_INTO_EDX
1529+ xorl %esi, %edx
1530+ SET_CR0_FROM_EDX
1531+ jmp resume_kernel
1532+#else
1533 jb resume_kernel # not returning to v8086 or userspace
1534+#endif
1535
1536 ENTRY(resume_userspace)
1537 DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
1538@@ -307,10 +331,9 @@ sysenter_past_esp:
1539 /*CFI_REL_OFFSET cs, 0*/
1540 /*
1541 * Push current_thread_info()->sysenter_return to the stack.
1542- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
1543- * pushed above; +8 corresponds to copy_thread's esp0 setting.
1544 */
1545- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
1546+ GET_THREAD_INFO(%ebp)
1547+ pushl TI_sysenter_return(%ebp)
1548 CFI_ADJUST_CFA_OFFSET 4
1549 CFI_REL_OFFSET eip, 0
1550
1551@@ -318,9 +341,17 @@ sysenter_past_esp:
1552 * Load the potential sixth argument from user stack.
1553 * Careful about security.
1554 */
1555+ movl 12(%esp),%ebp
1556+
1557+#ifdef CONFIG_PAX_MEMORY_UDEREF
1558+ mov 16(%esp),%ds
1559+1: movl %ds:(%ebp),%ebp
1560+#else
1561 cmpl $__PAGE_OFFSET-3,%ebp
1562 jae syscall_fault
1563 1: movl (%ebp),%ebp
1564+#endif
1565+
1566 .section __ex_table,"a"
1567 .align 4
1568 .long 1b,syscall_fault
1569@@ -343,20 +374,37 @@ sysenter_past_esp:
1570 movl TI_flags(%ebp), %ecx
1571 testw $_TIF_ALLWORK_MASK, %cx
1572 jne syscall_exit_work
1573+
1574+#ifdef CONFIG_PAX_RANDKSTACK
1575+ pushl %eax
1576+ CFI_ADJUST_CFA_OFFSET 4
1577+ call pax_randomize_kstack
1578+ popl %eax
1579+ CFI_ADJUST_CFA_OFFSET -4
1580+#endif
1581+
1582 /* if something modifies registers it must also disable sysexit */
1583 movl PT_EIP(%esp), %edx
1584 movl PT_OLDESP(%esp), %ecx
1585 xorl %ebp,%ebp
1586 TRACE_IRQS_ON
1587 1: mov PT_FS(%esp), %fs
1588+2: mov PT_DS(%esp), %ds
1589+3: mov PT_ES(%esp), %es
1590 ENABLE_INTERRUPTS_SYSEXIT
1591 CFI_ENDPROC
1592 .pushsection .fixup,"ax"
1593-2: movl $0,PT_FS(%esp)
1594+4: movl $0,PT_FS(%esp)
1595 jmp 1b
1596+5: movl $0,PT_DS(%esp)
1597+ jmp 2b
1598+6: movl $0,PT_ES(%esp)
1599+ jmp 3b
1600 .section __ex_table,"a"
1601 .align 4
1602- .long 1b,2b
1603+ .long 1b,4b
1604+ .long 2b,5b
1605+ .long 3b,6b
1606 .popsection
1607 ENDPROC(sysenter_entry)
1608
1609@@ -389,6 +437,10 @@ no_singlestep:
1610 testw $_TIF_ALLWORK_MASK, %cx # current->work
1611 jne syscall_exit_work
1612
1613+#ifdef CONFIG_PAX_RANDKSTACK
1614+ call pax_randomize_kstack
1615+#endif
1616+
1617 restore_all:
1618 movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
1619 # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
1620@@ -554,17 +606,24 @@ syscall_badsys:
1621 END(syscall_badsys)
1622 CFI_ENDPROC
1623
1624-#define FIXUP_ESPFIX_STACK \
1625- /* since we are on a wrong stack, we cant make it a C code :( */ \
1626- PER_CPU(gdt_page, %ebx); \
1627- GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
1628- addl %esp, %eax; \
1629- pushl $__KERNEL_DS; \
1630- CFI_ADJUST_CFA_OFFSET 4; \
1631- pushl %eax; \
1632- CFI_ADJUST_CFA_OFFSET 4; \
1633- lss (%esp), %esp; \
1634+.macro FIXUP_ESPFIX_STACK
1635+ /* since we are on a wrong stack, we cant make it a C code :( */
1636+#ifdef CONFIG_SMP
1637+ movl PER_CPU_VAR(cpu_number), %ebx;
1638+ shll $PAGE_SHIFT_asm, %ebx;
1639+ addl $cpu_gdt_table, %ebx;
1640+#else
1641+ movl $cpu_gdt_table, %ebx;
1642+#endif
1643+ GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
1644+ addl %esp, %eax;
1645+ pushl $__KERNEL_DS;
1646+ CFI_ADJUST_CFA_OFFSET 4;
1647+ pushl %eax;
1648+ CFI_ADJUST_CFA_OFFSET 4;
1649+ lss (%esp), %esp;
1650 CFI_ADJUST_CFA_OFFSET -8;
1651+.endm
1652 #define UNWIND_ESPFIX_STACK \
1653 movl %ss, %eax; \
1654 /* see if on espfix stack */ \
1655@@ -581,7 +640,7 @@ END(syscall_badsys)
1656 * Build the entry stubs and pointer table with
1657 * some assembler magic.
1658 */
1659-.data
1660+.section .rodata,"a",@progbits
1661 ENTRY(interrupt)
1662 .text
1663
1664@@ -681,12 +740,21 @@ error_code:
1665 popl %ecx
1666 CFI_ADJUST_CFA_OFFSET -4
1667 /*CFI_REGISTER es, ecx*/
1668+
1669+#ifdef CONFIG_PAX_KERNEXEC
1670+ GET_CR0_INTO_EDX
1671+ movl %edx, %esi
1672+ orl $X86_CR0_WP, %edx
1673+ xorl %edx, %esi
1674+ SET_CR0_FROM_EDX
1675+#endif
1676+
1677 movl PT_FS(%esp), %edi # get the function address
1678 movl PT_ORIG_EAX(%esp), %edx # get the error code
1679 movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
1680 mov %ecx, PT_FS(%esp)
1681 /*CFI_REL_OFFSET fs, ES*/
1682- movl $(__USER_DS), %ecx
1683+ movl $(__KERNEL_DS), %ecx
1684 movl %ecx, %ds
1685 movl %ecx, %es
1686 movl %esp,%eax # pt_regs pointer
1687@@ -820,6 +888,13 @@ nmi_stack_correct:
1688 xorl %edx,%edx # zero error code
1689 movl %esp,%eax # pt_regs pointer
1690 call do_nmi
1691+
1692+#ifdef CONFIG_PAX_KERNEXEC
1693+ GET_CR0_INTO_EDX
1694+ xorl %esi, %edx
1695+ SET_CR0_FROM_EDX
1696+#endif
1697+
1698 jmp restore_nocheck_notrace
1699 CFI_ENDPROC
1700
1701@@ -860,6 +935,13 @@ nmi_espfix_stack:
1702 FIXUP_ESPFIX_STACK # %eax == %esp
1703 xorl %edx,%edx # zero error code
1704 call do_nmi
1705+
1706+#ifdef CONFIG_PAX_KERNEXEC
1707+ GET_CR0_INTO_EDX
1708+ xorl %esi, %edx
1709+ SET_CR0_FROM_EDX
1710+#endif
1711+
1712 RESTORE_REGS
1713 lss 12+4(%esp), %esp # back to espfix stack
1714 CFI_ADJUST_CFA_OFFSET -24
1715@@ -1023,7 +1105,6 @@ ENTRY(kernel_thread_helper)
1716 CFI_ENDPROC
1717 ENDPROC(kernel_thread_helper)
1718
1719-.section .rodata,"a"
1720 #include "syscall_table.S"
1721
1722 syscall_table_size=(.-sys_call_table)
1723diff -urNp linux-2.6.22.1/arch/i386/kernel/head.S linux-2.6.22.1/arch/i386/kernel/head.S
1724--- linux-2.6.22.1/arch/i386/kernel/head.S 2007-07-10 14:56:30.000000000 -0400
1725+++ linux-2.6.22.1/arch/i386/kernel/head.S 2007-08-03 12:34:39.000000000 -0400
1726@@ -18,6 +18,7 @@
1727 #include <asm/thread_info.h>
1728 #include <asm/asm-offsets.h>
1729 #include <asm/setup.h>
1730+#include <asm/msr-index.h>
1731
1732 /*
1733 * References to members of the new_cpu_data structure.
1734@@ -51,16 +52,23 @@
1735 */
1736 LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
1737
1738-#if PTRS_PER_PMD > 1
1739-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
1740-#else
1741-PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
1742-#endif
1743+PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
1744 BOOTBITMAP_SIZE = LOW_PAGES / 8
1745 ALLOCATOR_SLOP = 4
1746
1747 INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
1748
1749+#ifdef CONFIG_PAX_KERNEXEC
1750+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1751+.fill 4096,1,0xcc
1752+#endif
1753+
1754+/*
1755+ * Real beginning of normal "text" segment
1756+ */
1757+ENTRY(stext)
1758+ENTRY(_stext)
1759+
1760 /*
1761 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
1762 * %esi points to the real-mode code as a 32-bit pointer.
1763@@ -82,6 +90,43 @@ ENTRY(startup_32)
1764 movl %eax,%fs
1765 movl %eax,%gs
1766
1767+ movl $__per_cpu_start,%eax
1768+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 2)
1769+ rorl $16,%eax
1770+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 4)
1771+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 7)
1772+ movl $__per_cpu_end + PERCPU_MODULE_RESERVE,%eax
1773+ subl $__per_cpu_start,%eax
1774+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PERCPU + 0)
1775+
1776+#ifdef CONFIG_PAX_MEMORY_UDEREF
1777+ /* check for VMware */
1778+ movl $0x564d5868,%eax
1779+ xorl %ebx,%ebx
1780+ movl $0xa,%ecx
1781+ movl $0x5658,%edx
1782+ in (%dx),%eax
1783+ cmpl $0x564d5868,%ebx
1784+ jz 1f
1785+
1786+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1787+ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1788+1:
1789+#endif
1790+
1791+#ifdef CONFIG_PAX_KERNEXEC
1792+ movl $__KERNEL_TEXT_OFFSET,%eax
1793+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1794+ rorl $16,%eax
1795+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1796+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1797+
1798+ movb %al,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 4)
1799+ movb %ah,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 7)
1800+ rorl $16,%eax
1801+ movw %ax,(boot_gdt - __PAGE_OFFSET + __BOOT_CS + 2)
1802+#endif
1803+
1804 /*
1805 * Clear BSS first so that there are no surprises...
1806 * No need to cld as DF is already clear from cld above...
1807@@ -129,24 +174,42 @@ ENTRY(startup_32)
1808 * Warning: don't use %esi or the stack in this code. However, %esp
1809 * can be used as a GPR if you really need it...
1810 */
1811-page_pde_offset = (__PAGE_OFFSET >> 20);
1812-
1813+#ifdef CONFIG_X86_PAE
1814+page_pde_offset = ((__PAGE_OFFSET >> 21) * (PAGE_SIZE_asm / PTRS_PER_PTE));
1815+#else
1816+page_pde_offset = ((__PAGE_OFFSET >> 22) * (PAGE_SIZE_asm / PTRS_PER_PTE));
1817+#endif
1818 movl $(pg0 - __PAGE_OFFSET), %edi
1819+#ifdef CONFIG_X86_PAE
1820+ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1821+#else
1822 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1823- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
1824+#endif
1825+ movl $0x063, %eax /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1826 10:
1827- leal 0x007(%edi),%ecx /* Create PDE entry */
1828+ leal 0x063(%edi),%ecx /* Create PDE entry */
1829 movl %ecx,(%edx) /* Store identity PDE entry */
1830 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
1831+#ifdef CONFIG_X86_PAE
1832+ movl $0,4(%edx)
1833+ movl $0,page_pde_offset+4(%edx)
1834+ addl $8,%edx
1835+ movl $512, %ecx
1836+#else
1837 addl $4,%edx
1838 movl $1024, %ecx
1839+#endif
1840 11:
1841 stosl
1842+#ifdef CONFIG_X86_PAE
1843+ movl $0,(%edi)
1844+ addl $4,%edi
1845+#endif
1846 addl $0x1000,%eax
1847 loop 11b
1848 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1849- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1850- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1851+ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1852+ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1853 cmpl %ebp,%eax
1854 jb 10b
1855 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1856@@ -177,6 +240,11 @@ ENTRY(startup_32_smp)
1857 movl %eax,%fs
1858 movl %eax,%gs
1859
1860+ /* This is a secondary processor (AP) */
1861+ xorl %ebx,%ebx
1862+ incl %ebx
1863+#endif /* CONFIG_SMP */
1864+
1865 /*
1866 * New page tables may be in 4Mbyte page mode and may
1867 * be using the global pages.
1868@@ -192,42 +260,47 @@ ENTRY(startup_32_smp)
1869 * not yet offset PAGE_OFFSET..
1870 */
1871 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1872+3:
1873 movl cr4_bits,%edx
1874 andl %edx,%edx
1875- jz 6f
1876+ jz 5f
1877 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
1878 orl %edx,%eax
1879 movl %eax,%cr4
1880
1881- btl $5, %eax # check if PAE is enabled
1882- jnc 6f
1883+#ifdef CONFIG_X86_PAE
1884+ movl %ebx,%edi
1885
1886 /* Check if extended functions are implemented */
1887 movl $0x80000000, %eax
1888 cpuid
1889 cmpl $0x80000000, %eax
1890- jbe 6f
1891+ jbe 4f
1892 mov $0x80000001, %eax
1893 cpuid
1894 /* Execute Disable bit supported? */
1895 btl $20, %edx
1896- jnc 6f
1897+ jnc 4f
1898
1899 /* Setup EFER (Extended Feature Enable Register) */
1900- movl $0xc0000080, %ecx
1901+ movl $MSR_EFER, %ecx
1902 rdmsr
1903
1904 btsl $11, %eax
1905 /* Make changes effective */
1906 wrmsr
1907
1908-6:
1909- /* This is a secondary processor (AP) */
1910- xorl %ebx,%ebx
1911- incl %ebx
1912+ btsl $63-32,__supported_pte_mask+4-__PAGE_OFFSET
1913+ movl $1,nx_enabled-__PAGE_OFFSET
1914
1915-#endif /* CONFIG_SMP */
1916-3:
1917+#if !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC) && !defined(CONFIG_PAX_MEMORY_UDEREF)
1918+ movl $0,disable_x86_sep-__PAGE_OFFSET
1919+#endif
1920+
1921+4:
1922+ movl %edi,%ebx
1923+#endif
1924+5:
1925
1926 /*
1927 * Enable paging
1928@@ -252,9 +325,7 @@ ENTRY(startup_32_smp)
1929
1930 #ifdef CONFIG_SMP
1931 andl %ebx,%ebx
1932- jz 1f /* Initial CPU cleans BSS */
1933- jmp checkCPUtype
1934-1:
1935+ jnz checkCPUtype /* Initial CPU cleans BSS */
1936 #endif /* CONFIG_SMP */
1937
1938 /*
1939@@ -331,12 +402,12 @@ is386: movl $2,%ecx # set MP
1940 ljmp $(__KERNEL_CS),$1f
1941 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
1942 movl %eax,%ss # after changing gdt.
1943- movl %eax,%fs # gets reset once there's real percpu
1944-
1945- movl $(__USER_DS),%eax # DS/ES contains default USER segment
1946 movl %eax,%ds
1947 movl %eax,%es
1948
1949+ movl $(__KERNEL_PERCPU), %eax
1950+ movl %eax,%fs # set this cpu's percpu
1951+
1952 xorl %eax,%eax # Clear GS and LDT
1953 movl %eax,%gs
1954 lldt %ax
1955@@ -347,11 +418,7 @@ is386: movl $2,%ecx # set MP
1956 movb ready, %cl
1957 movb $1, ready
1958 cmpb $0,%cl # the first CPU calls start_kernel
1959- je 1f
1960- movl $(__KERNEL_PERCPU), %eax
1961- movl %eax,%fs # set this cpu's percpu
1962- jmp initialize_secondary # all other CPUs call initialize_secondary
1963-1:
1964+ jne initialize_secondary # all other CPUs call initialize_secondary
1965 #endif /* CONFIG_SMP */
1966 jmp start_kernel
1967
1968@@ -462,8 +529,8 @@ hlt_loop:
1969 /* This is the default interrupt "handler" :-) */
1970 ALIGN
1971 ignore_int:
1972- cld
1973 #ifdef CONFIG_PRINTK
1974+ cld
1975 pushl %eax
1976 pushl %ecx
1977 pushl %edx
1978@@ -494,28 +561,54 @@ ignore_int:
1979 #endif
1980 iret
1981
1982-.section .text
1983-/*
1984- * Real beginning of normal "text" segment
1985- */
1986-ENTRY(stext)
1987-ENTRY(_stext)
1988-
1989 /*
1990 * BSS section
1991 */
1992-.section ".bss.page_aligned","w"
1993+.section .swapper_pg_dir,"a",@progbits
1994 ENTRY(swapper_pg_dir)
1995+#ifdef CONFIG_X86_PAE
1996+ .long swapper_pm_dir-__PAGE_OFFSET+1
1997+ .long 0
1998+ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1999+ .long 0
2000+ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
2001+ .long 0
2002+ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
2003+ .long 0
2004+#else
2005 .fill 1024,4,0
2006+#endif
2007+
2008+#ifdef CONFIG_X86_PAE
2009+.section .swapper_pm_dir,"a",@progbits
2010+ENTRY(swapper_pm_dir)
2011+ .fill 512,8,0
2012+ .fill 512,8,0
2013+ .fill 512,8,0
2014+ .fill 512,8,0
2015+#endif
2016+
2017+.section .empty_zero_page,"a",@progbits
2018 ENTRY(empty_zero_page)
2019 .fill 4096,1,0
2020
2021 /*
2022+ * The IDT has to be page-aligned to simplify the Pentium
2023+ * F0 0F bug workaround.. We have a special link segment
2024+ * for this.
2025+ */
2026+.section .idt,"a",@progbits
2027+ENTRY(idt_table)
2028+ .fill 256,8,0
2029+
2030+/*
2031 * This starts the data section.
2032 */
2033 .data
2034+
2035+.section .rodata,"a",@progbits
2036 ENTRY(stack_start)
2037- .long init_thread_union+THREAD_SIZE
2038+ .long init_thread_union+THREAD_SIZE-8
2039 .long __BOOT_DS
2040
2041 ready: .byte 0
2042@@ -556,7 +649,7 @@ idt_descr:
2043 .word 0 # 32 bit align gdt_desc.address
2044 ENTRY(early_gdt_descr)
2045 .word GDT_ENTRIES*8-1
2046- .long per_cpu__gdt_page /* Overwritten for secondary CPUs */
2047+ .long cpu_gdt_table /* Overwritten for secondary CPUs */
2048
2049 /*
2050 * The boot_gdt must mirror the equivalent in setup.S and is
2051@@ -565,5 +658,61 @@ ENTRY(early_gdt_descr)
2052 .align L1_CACHE_BYTES
2053 ENTRY(boot_gdt)
2054 .fill GDT_ENTRY_BOOT_CS,8,0
2055- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
2056- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
2057+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
2058+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
2059+
2060+ .align PAGE_SIZE_asm
2061+ENTRY(cpu_gdt_table)
2062+ .quad 0x0000000000000000 /* NULL descriptor */
2063+ .quad 0x0000000000000000 /* 0x0b reserved */
2064+ .quad 0x0000000000000000 /* 0x13 reserved */
2065+ .quad 0x0000000000000000 /* 0x1b reserved */
2066+ .quad 0x0000000000000000 /* 0x20 unused */
2067+ .quad 0x0000000000000000 /* 0x28 unused */
2068+ .quad 0x0000000000000000 /* 0x33 TLS entry 1 */
2069+ .quad 0x0000000000000000 /* 0x3b TLS entry 2 */
2070+ .quad 0x0000000000000000 /* 0x43 TLS entry 3 */
2071+ .quad 0x0000000000000000 /* 0x4b reserved */
2072+ .quad 0x0000000000000000 /* 0x53 reserved */
2073+ .quad 0x0000000000000000 /* 0x5b reserved */
2074+
2075+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
2076+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
2077+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
2078+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
2079+
2080+ .quad 0x0000000000000000 /* 0x80 TSS descriptor */
2081+ .quad 0x0000000000000000 /* 0x88 LDT descriptor */
2082+
2083+ /*
2084+ * Segments used for calling PnP BIOS have byte granularity.
2085+ * The code segments and data segments have fixed 64k limits,
2086+ * the transfer segment sizes are set at run time.
2087+ */
2088+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
2089+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
2090+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
2091+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
2092+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
2093+
2094+ /*
2095+ * The APM segments have byte granularity and their bases
2096+ * are set at run time. All have 64k limits.
2097+ */
2098+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
2099+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
2100+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
2101+
2102+ .quad 0x00c0930000000000 /* 0xd0 - ESPFIX SS */
2103+ .quad 0x0040930000000000 /* 0xd8 - PERCPU */
2104+ .quad 0x0000000000000000 /* 0xe0 - PCIBIOS_CS */
2105+ .quad 0x0000000000000000 /* 0xe8 - PCIBIOS_DS */
2106+ .quad 0x0000000000000000 /* 0xf0 - unused */
2107+ .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
2108+
2109+ /* Be sure this is zeroed to avoid false validations in Xen */
2110+ .fill PAGE_SIZE_asm - GDT_ENTRIES,1,0
2111+
2112+#ifdef CONFIG_SMP
2113+ .fill (NR_CPUS-1) * (PAGE_SIZE_asm),1,0 /* other CPU's GDT */
2114+#endif
2115diff -urNp linux-2.6.22.1/arch/i386/kernel/hpet.c linux-2.6.22.1/arch/i386/kernel/hpet.c
2116--- linux-2.6.22.1/arch/i386/kernel/hpet.c 2007-07-10 14:56:30.000000000 -0400
2117+++ linux-2.6.22.1/arch/i386/kernel/hpet.c 2007-08-02 11:38:45.000000000 -0400
2118@@ -95,7 +95,7 @@ static void hpet_reserve_platform_timers
2119 hd.hd_irq[1] = HPET_LEGACY_RTC;
2120
2121 for (i = 2; i < nrtimers; timer++, i++)
2122- hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
2123+ hd.hd_irq[i] = (readl(&timer->hpet_config) & Tn_INT_ROUTE_CNF_MASK) >>
2124 Tn_INT_ROUTE_CNF_SHIFT;
2125
2126 hpet_alloc(&hd);
2127diff -urNp linux-2.6.22.1/arch/i386/kernel/i386_ksyms.c linux-2.6.22.1/arch/i386/kernel/i386_ksyms.c
2128--- linux-2.6.22.1/arch/i386/kernel/i386_ksyms.c 2007-07-10 14:56:30.000000000 -0400
2129+++ linux-2.6.22.1/arch/i386/kernel/i386_ksyms.c 2007-08-02 11:38:45.000000000 -0400
2130@@ -2,12 +2,16 @@
2131 #include <asm/checksum.h>
2132 #include <asm/desc.h>
2133
2134+EXPORT_SYMBOL_GPL(cpu_gdt_table);
2135+
2136 EXPORT_SYMBOL(__down_failed);
2137 EXPORT_SYMBOL(__down_failed_interruptible);
2138 EXPORT_SYMBOL(__down_failed_trylock);
2139 EXPORT_SYMBOL(__up_wakeup);
2140 /* Networking helper routines. */
2141 EXPORT_SYMBOL(csum_partial_copy_generic);
2142+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
2143+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
2144
2145 EXPORT_SYMBOL(__get_user_1);
2146 EXPORT_SYMBOL(__get_user_2);
2147diff -urNp linux-2.6.22.1/arch/i386/kernel/i8259.c linux-2.6.22.1/arch/i386/kernel/i8259.c
2148--- linux-2.6.22.1/arch/i386/kernel/i8259.c 2007-07-10 14:56:30.000000000 -0400
2149+++ linux-2.6.22.1/arch/i386/kernel/i8259.c 2007-08-02 11:38:45.000000000 -0400
2150@@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp
2151 * New motherboards sometimes make IRQ 13 be a PCI interrupt,
2152 * so allow interrupt sharing.
2153 */
2154-static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
2155+static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL };
2156
2157 void __init init_ISA_irqs (void)
2158 {
2159diff -urNp linux-2.6.22.1/arch/i386/kernel/init_task.c linux-2.6.22.1/arch/i386/kernel/init_task.c
2160--- linux-2.6.22.1/arch/i386/kernel/init_task.c 2007-07-10 14:56:30.000000000 -0400
2161+++ linux-2.6.22.1/arch/i386/kernel/init_task.c 2007-08-02 11:38:45.000000000 -0400
2162@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
2163 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
2164 * no more per-task TSS's.
2165 */
2166-DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
2167+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
2168
2169diff -urNp linux-2.6.22.1/arch/i386/kernel/io_apic.c linux-2.6.22.1/arch/i386/kernel/io_apic.c
2170--- linux-2.6.22.1/arch/i386/kernel/io_apic.c 2007-07-10 14:56:30.000000000 -0400
2171+++ linux-2.6.22.1/arch/i386/kernel/io_apic.c 2007-08-02 11:38:45.000000000 -0400
2172@@ -357,8 +357,8 @@ static void set_ioapic_affinity_irq(unsi
2173 # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
2174 # define Dprintk(x...) do { TDprintk(x); } while (0)
2175 # else
2176-# define TDprintk(x...)
2177-# define Dprintk(x...)
2178+# define TDprintk(x...) do {} while (0)
2179+# define Dprintk(x...) do {} while (0)
2180 # endif
2181
2182 #define IRQBALANCE_CHECK_ARCH -999
2183diff -urNp linux-2.6.22.1/arch/i386/kernel/ioport.c linux-2.6.22.1/arch/i386/kernel/ioport.c
2184--- linux-2.6.22.1/arch/i386/kernel/ioport.c 2007-07-10 14:56:30.000000000 -0400
2185+++ linux-2.6.22.1/arch/i386/kernel/ioport.c 2007-08-02 11:38:45.000000000 -0400
2186@@ -16,6 +16,7 @@
2187 #include <linux/slab.h>
2188 #include <linux/thread_info.h>
2189 #include <linux/syscalls.h>
2190+#include <linux/grsecurity.h>
2191
2192 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
2193 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
2194@@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
2195
2196 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
2197 return -EINVAL;
2198+#ifdef CONFIG_GRKERNSEC_IO
2199+ if (turn_on) {
2200+ gr_handle_ioperm();
2201+#else
2202 if (turn_on && !capable(CAP_SYS_RAWIO))
2203+#endif
2204 return -EPERM;
2205-
2206+#ifdef CONFIG_GRKERNSEC_IO
2207+ }
2208+#endif
2209 /*
2210 * If it's the first ioperm() call in this thread's lifetime, set the
2211 * IO bitmap up. ioperm() is much less timing critical than clone(),
2212@@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
2213 * because the ->io_bitmap_max value must match the bitmap
2214 * contents:
2215 */
2216- tss = &per_cpu(init_tss, get_cpu());
2217+ tss = init_tss + get_cpu();
2218
2219 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
2220
2221@@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
2222 return -EINVAL;
2223 /* Trying to gain more privileges? */
2224 if (level > old) {
2225+#ifdef CONFIG_GRKERNSEC_IO
2226+ gr_handle_iopl();
2227+ return -EPERM;
2228+#else
2229 if (!capable(CAP_SYS_RAWIO))
2230 return -EPERM;
2231+#endif
2232 }
2233 t->iopl = level << 12;
2234 regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
2235diff -urNp linux-2.6.22.1/arch/i386/kernel/irq.c linux-2.6.22.1/arch/i386/kernel/irq.c
2236--- linux-2.6.22.1/arch/i386/kernel/irq.c 2007-07-10 14:56:30.000000000 -0400
2237+++ linux-2.6.22.1/arch/i386/kernel/irq.c 2007-08-02 11:38:45.000000000 -0400
2238@@ -117,7 +117,7 @@ fastcall unsigned int do_IRQ(struct pt_r
2239 int arg1, arg2, ebx;
2240
2241 /* build the stack frame on the IRQ stack */
2242- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2243+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2244 irqctx->tinfo.task = curctx->tinfo.task;
2245 irqctx->tinfo.previous_esp = current_stack_pointer;
2246
2247@@ -154,10 +154,10 @@ fastcall unsigned int do_IRQ(struct pt_r
2248 * gcc's 3.0 and earlier don't handle that correctly.
2249 */
2250 static char softirq_stack[NR_CPUS * THREAD_SIZE]
2251- __attribute__((__aligned__(THREAD_SIZE)));
2252+ __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2253
2254 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
2255- __attribute__((__aligned__(THREAD_SIZE)));
2256+ __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2257
2258 /*
2259 * allocate per-cpu stacks for hardirq and for softirq processing
2260@@ -217,7 +217,7 @@ asmlinkage void do_softirq(void)
2261 irqctx->tinfo.previous_esp = current_stack_pointer;
2262
2263 /* build the stack frame on the softirq stack */
2264- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2265+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2266
2267 asm volatile(
2268 " xchgl %%ebx,%%esp \n"
2269diff -urNp linux-2.6.22/arch/i386/kernel/kprobes.c linux-2.6.22/arch/i386/kernel/kprobes.c
2270--- linux-2.6.22/arch/i386/kernel/kprobes.c 2007-07-10 14:56:30.000000000 -0400
2271+++ linux-2.6.22/arch/i386/kernel/kprobes.c 2007-07-10 14:56:30.000000000 -0400
2272@@ -48,9 +48,24 @@ static __always_inline void set_jmp_op(v
2273 char op;
2274 long raddr;
2275 } __attribute__((packed)) *jop;
2276- jop = (struct __arch_jmp_op *)from;
2277+
2278+#ifdef CONFIG_PAX_KERNEXEC
2279+ unsigned long cr0;
2280+#endif
2281+
2282+ jop = (struct __arch_jmp_op *)(from + __KERNEL_TEXT_OFFSET);
2283+
2284+#ifdef CONFIG_PAX_KERNEXEC
2285+ pax_open_kernel(cr0);
2286+#endif
2287+
2288 jop->raddr = (long)(to) - ((long)(from) + 5);
2289 jop->op = RELATIVEJUMP_INSTRUCTION;
2290+
2291+#ifdef CONFIG_PAX_KERNEXEC
2292+ pax_close_kernel(cr0);
2293+#endif
2294+
2295 }
2296
2297 /*
2298@@ -152,12 +167,26 @@ static int __kprobes is_IF_modifier(kpro
2299
2300 int __kprobes arch_prepare_kprobe(struct kprobe *p)
2301 {
2302+
2303+#ifdef CONFIG_PAX_KERNEXEC
2304+ unsigned long cr0;
2305+#endif
2306+
2307 /* insn: must be on special executable page on i386. */
2308 p->ainsn.insn = get_insn_slot();
2309 if (!p->ainsn.insn)
2310 return -ENOMEM;
2311
2312- memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
2313+#ifdef CONFIG_PAX_KERNEXEC
2314+ pax_open_kernel(cr0);
2315+#endif
2316+
2317+ memcpy(p->ainsn.insn, p->addr + __KERNEL_TEXT_OFFSET, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
2318+
2319+#ifdef CONFIG_PAX_KERNEXEC
2320+ pax_close_kernel(cr0);
2321+#endif
2322+
2323 p->opcode = *p->addr;
2324 if (can_boost(p->addr)) {
2325 p->ainsn.boostable = 0;
2326@@ -222,7 +251,7 @@ static void __kprobes prepare_singlestep
2327 if (p->opcode == BREAKPOINT_INSTRUCTION)
2328 regs->eip = (unsigned long)p->addr;
2329 else
2330- regs->eip = (unsigned long)p->ainsn.insn;
2331+ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2332 }
2333
2334 /* Called with kretprobe_lock held */
2335@@ -328,7 +357,7 @@ ss_probe:
2336 if (p->ainsn.boostable == 1 && !p->post_handler){
2337 /* Boost up -- we can execute copied instructions directly */
2338 reset_current_kprobe();
2339- regs->eip = (unsigned long)p->ainsn.insn;
2340+ regs->eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2341 preempt_enable_no_resched();
2342 return 1;
2343 }
2344@@ -478,7 +507,7 @@ static void __kprobes resume_execution(s
2345 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
2346 {
2347 unsigned long *tos = (unsigned long *)&regs->esp;
2348- unsigned long copy_eip = (unsigned long)p->ainsn.insn;
2349+ unsigned long copy_eip = (unsigned long)p->ainsn.insn - __KERNEL_TEXT_OFFSET;
2350 unsigned long orig_eip = (unsigned long)p->addr;
2351
2352 regs->eflags &= ~TF_MASK;
2353@@ -651,7 +680,7 @@ int __kprobes kprobe_exceptions_notify(s
2354 struct die_args *args = (struct die_args *)data;
2355 int ret = NOTIFY_DONE;
2356
2357- if (args->regs && user_mode_vm(args->regs))
2358+ if (args->regs && user_mode(args->regs))
2359 return ret;
2360
2361 switch (val) {
2362diff -urNp linux-2.6.22.1/arch/i386/kernel/ldt.c linux-2.6.22.1/arch/i386/kernel/ldt.c
2363--- linux-2.6.22.1/arch/i386/kernel/ldt.c 2007-07-10 14:56:30.000000000 -0400
2364+++ linux-2.6.22.1/arch/i386/kernel/ldt.c 2007-08-02 11:38:45.000000000 -0400
2365@@ -58,7 +58,7 @@ static int alloc_ldt(mm_context_t *pc, i
2366 #ifdef CONFIG_SMP
2367 cpumask_t mask;
2368 preempt_disable();
2369- load_LDT(pc);
2370+ load_LDT_nolock(pc);
2371 mask = cpumask_of_cpu(smp_processor_id());
2372 if (!cpus_equal(current->mm->cpu_vm_mask, mask))
2373 smp_call_function(flush_ldt, NULL, 1, 1);
2374@@ -102,6 +102,22 @@ int init_new_context(struct task_struct
2375 retval = copy_ldt(&mm->context, &old_mm->context);
2376 up(&old_mm->context.sem);
2377 }
2378+
2379+ if (tsk == current) {
2380+ mm->context.vdso = ~0UL;
2381+
2382+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2383+ mm->context.user_cs_base = 0UL;
2384+ mm->context.user_cs_limit = ~0UL;
2385+
2386+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
2387+ cpus_clear(mm->context.cpu_user_cs_mask);
2388+#endif
2389+
2390+#endif
2391+
2392+ }
2393+
2394 return retval;
2395 }
2396
2397@@ -212,6 +228,13 @@ static int write_ldt(void __user * ptr,
2398 }
2399 }
2400
2401+#ifdef CONFIG_PAX_SEGMEXEC
2402+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
2403+ error = -EINVAL;
2404+ goto out_unlock;
2405+ }
2406+#endif
2407+
2408 entry_1 = LDT_entry_a(&ldt_info);
2409 entry_2 = LDT_entry_b(&ldt_info);
2410 if (oldmode)
2411diff -urNp linux-2.6.22.1/arch/i386/kernel/machine_kexec.c linux-2.6.22.1/arch/i386/kernel/machine_kexec.c
2412--- linux-2.6.22.1/arch/i386/kernel/machine_kexec.c 2007-07-10 14:56:30.000000000 -0400
2413+++ linux-2.6.22.1/arch/i386/kernel/machine_kexec.c 2007-08-02 11:38:45.000000000 -0400
2414@@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
2415 static u32 kexec_pte0[1024] PAGE_ALIGNED;
2416 static u32 kexec_pte1[1024] PAGE_ALIGNED;
2417
2418-static void set_idt(void *newidt, __u16 limit)
2419+static void set_idt(struct desc_struct *newidt, __u16 limit)
2420 {
2421 struct Xgt_desc_struct curidt;
2422
2423 /* ia32 supports unaliged loads & stores */
2424 curidt.size = limit;
2425- curidt.address = (unsigned long)newidt;
2426+ curidt.address = newidt;
2427
2428 load_idt(&curidt);
2429 };
2430
2431
2432-static void set_gdt(void *newgdt, __u16 limit)
2433+static void set_gdt(struct desc_struct *newgdt, __u16 limit)
2434 {
2435 struct Xgt_desc_struct curgdt;
2436
2437 /* ia32 supports unaligned loads & stores */
2438 curgdt.size = limit;
2439- curgdt.address = (unsigned long)newgdt;
2440+ curgdt.address = newgdt;
2441
2442 load_gdt(&curgdt);
2443 };
2444@@ -110,10 +110,10 @@ NORET_TYPE void machine_kexec(struct kim
2445 local_irq_disable();
2446
2447 control_page = page_address(image->control_code_page);
2448- memcpy(control_page, relocate_kernel, PAGE_SIZE);
2449+ memcpy(control_page, relocate_kernel + __KERNEL_TEXT_OFFSET, PAGE_SIZE);
2450
2451 page_list[PA_CONTROL_PAGE] = __pa(control_page);
2452- page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel;
2453+ page_list[VA_CONTROL_PAGE] = (unsigned long)relocate_kernel + __KERNEL_TEXT_OFFSET;
2454 page_list[PA_PGD] = __pa(kexec_pgd);
2455 page_list[VA_PGD] = (unsigned long)kexec_pgd;
2456 #ifdef CONFIG_X86_PAE
2457diff -urNp linux-2.6.22.1/arch/i386/kernel/module.c linux-2.6.22.1/arch/i386/kernel/module.c
2458--- linux-2.6.22.1/arch/i386/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
2459+++ linux-2.6.22.1/arch/i386/kernel/module.c 2007-08-02 11:38:45.000000000 -0400
2460@@ -23,6 +23,8 @@
2461 #include <linux/kernel.h>
2462 #include <linux/bug.h>
2463
2464+#include <asm/desc.h>
2465+
2466 #if 0
2467 #define DEBUGP printk
2468 #else
2469@@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
2470 {
2471 if (size == 0)
2472 return NULL;
2473+
2474+#ifdef CONFIG_PAX_KERNEXEC
2475+ return vmalloc(size);
2476+#else
2477 return vmalloc_exec(size);
2478+#endif
2479+
2480 }
2481
2482+#ifdef CONFIG_PAX_KERNEXEC
2483+void *module_alloc_exec(unsigned long size)
2484+{
2485+ struct vm_struct *area;
2486+
2487+ if (size == 0)
2488+ return NULL;
2489+
2490+ area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
2491+ if (area)
2492+ return area->addr;
2493+
2494+ return NULL;
2495+}
2496+#endif
2497
2498 /* Free memory returned from module_alloc */
2499 void module_free(struct module *mod, void *module_region)
2500@@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
2501 table entries. */
2502 }
2503
2504+#ifdef CONFIG_PAX_KERNEXEC
2505+void module_free_exec(struct module *mod, void *module_region)
2506+{
2507+ struct vm_struct **p, *tmp;
2508+
2509+ if (!module_region)
2510+ return;
2511+
2512+ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
2513+ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
2514+ WARN_ON(1);
2515+ return;
2516+ }
2517+
2518+ write_lock(&vmlist_lock);
2519+ for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
2520+ if (tmp->addr == module_region)
2521+ break;
2522+
2523+ if (tmp) {
2524+ unsigned long cr0;
2525+
2526+ pax_open_kernel(cr0);
2527+ memset(tmp->addr, 0xCC, tmp->size);
2528+ pax_close_kernel(cr0);
2529+
2530+ *p = tmp->next;
2531+ kfree(tmp);
2532+ }
2533+ write_unlock(&vmlist_lock);
2534+
2535+ if (!tmp) {
2536+ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
2537+ module_region);
2538+ WARN_ON(1);
2539+ }
2540+}
2541+#endif
2542+
2543 /* We don't need anything special. */
2544 int module_frob_arch_sections(Elf_Ehdr *hdr,
2545 Elf_Shdr *sechdrs,
2546@@ -63,14 +125,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2547 unsigned int i;
2548 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
2549 Elf32_Sym *sym;
2550- uint32_t *location;
2551+ uint32_t *plocation, location;
2552
2553 DEBUGP("Applying relocate section %u to %u\n", relsec,
2554 sechdrs[relsec].sh_info);
2555 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
2556 /* This is where to make the change */
2557- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
2558- + rel[i].r_offset;
2559+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
2560+ location = (uint32_t)plocation;
2561+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
2562+ plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
2563 /* This is the symbol it is referring to. Note that all
2564 undefined symbols have been resolved. */
2565 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
2566@@ -79,11 +143,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2567 switch (ELF32_R_TYPE(rel[i].r_info)) {
2568 case R_386_32:
2569 /* We add the value into the location given */
2570- *location += sym->st_value;
2571+ *plocation += sym->st_value;
2572 break;
2573 case R_386_PC32:
2574 /* Add the value, subtract its postition */
2575- *location += sym->st_value - (uint32_t)location;
2576+ *plocation += sym->st_value - location;
2577 break;
2578 default:
2579 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
2580diff -urNp linux-2.6.22.1/arch/i386/kernel/paravirt.c linux-2.6.22.1/arch/i386/kernel/paravirt.c
2581--- linux-2.6.22.1/arch/i386/kernel/paravirt.c 2007-07-10 14:56:30.000000000 -0400
2582+++ linux-2.6.22.1/arch/i386/kernel/paravirt.c 2007-08-02 11:38:45.000000000 -0400
2583@@ -188,7 +188,7 @@ unsigned paravirt_patch_insns(void *site
2584 if (insn_len > len || start == NULL)
2585 insn_len = len;
2586 else
2587- memcpy(site, start, insn_len);
2588+ memcpy(site, start + __KERNEL_TEXT_OFFSET, insn_len);
2589
2590 return insn_len;
2591 }
2592@@ -228,7 +228,7 @@ static int __init print_banner(void)
2593 }
2594 core_initcall(print_banner);
2595
2596-struct paravirt_ops paravirt_ops = {
2597+struct paravirt_ops paravirt_ops __read_only = {
2598 .name = "bare hardware",
2599 .paravirt_enabled = 0,
2600 .kernel_rpl = 0,
2601diff -urNp linux-2.6.22.1/arch/i386/kernel/process.c linux-2.6.22.1/arch/i386/kernel/process.c
2602--- linux-2.6.22.1/arch/i386/kernel/process.c 2007-07-10 14:56:30.000000000 -0400
2603+++ linux-2.6.22.1/arch/i386/kernel/process.c 2007-08-02 11:38:45.000000000 -0400
2604@@ -68,15 +68,17 @@ EXPORT_SYMBOL(boot_option_idle_override)
2605 DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
2606 EXPORT_PER_CPU_SYMBOL(current_task);
2607
2608+#ifdef CONFIG_SMP
2609 DEFINE_PER_CPU(int, cpu_number);
2610 EXPORT_PER_CPU_SYMBOL(cpu_number);
2611+#endif
2612
2613 /*
2614 * Return saved PC of a blocked thread.
2615 */
2616 unsigned long thread_saved_pc(struct task_struct *tsk)
2617 {
2618- return ((unsigned long *)tsk->thread.esp)[3];
2619+ return tsk->thread.eip;
2620 }
2621
2622 /*
2623@@ -306,7 +308,7 @@ void show_regs(struct pt_regs * regs)
2624 0xffff & regs->xcs,regs->eip, smp_processor_id());
2625 print_symbol("EIP is at %s\n", regs->eip);
2626
2627- if (user_mode_vm(regs))
2628+ if (user_mode(regs))
2629 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
2630 printk(" EFLAGS: %08lx %s (%s %.*s)\n",
2631 regs->eflags, print_tainted(), init_utsname()->release,
2632@@ -346,8 +348,8 @@ int kernel_thread(int (*fn)(void *), voi
2633 regs.ebx = (unsigned long) fn;
2634 regs.edx = (unsigned long) arg;
2635
2636- regs.xds = __USER_DS;
2637- regs.xes = __USER_DS;
2638+ regs.xds = __KERNEL_DS;
2639+ regs.xes = __KERNEL_DS;
2640 regs.xfs = __KERNEL_PERCPU;
2641 regs.orig_eax = -1;
2642 regs.eip = (unsigned long) kernel_thread_helper;
2643@@ -369,7 +371,7 @@ void exit_thread(void)
2644 struct task_struct *tsk = current;
2645 struct thread_struct *t = &tsk->thread;
2646 int cpu = get_cpu();
2647- struct tss_struct *tss = &per_cpu(init_tss, cpu);
2648+ struct tss_struct *tss = init_tss + cpu;
2649
2650 kfree(t->io_bitmap_ptr);
2651 t->io_bitmap_ptr = NULL;
2652@@ -390,6 +392,7 @@ void flush_thread(void)
2653 {
2654 struct task_struct *tsk = current;
2655
2656+ __asm__("mov %0,%%gs\n" : : "r" (0) : "memory");
2657 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
2658 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
2659 clear_tsk_thread_flag(tsk, TIF_DEBUG);
2660@@ -423,7 +426,7 @@ int copy_thread(int nr, unsigned long cl
2661 struct task_struct *tsk;
2662 int err;
2663
2664- childregs = task_pt_regs(p);
2665+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
2666 *childregs = *regs;
2667 childregs->eax = 0;
2668 childregs->esp = esp;
2669@@ -465,6 +468,11 @@ int copy_thread(int nr, unsigned long cl
2670 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2671 goto out;
2672
2673+#ifdef CONFIG_PAX_SEGMEXEC
2674+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2675+ goto out;
2676+#endif
2677+
2678 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2679 desc->a = LDT_entry_a(&info);
2680 desc->b = LDT_entry_b(&info);
2681@@ -644,7 +652,7 @@ struct task_struct fastcall * __switch_t
2682 struct thread_struct *prev = &prev_p->thread,
2683 *next = &next_p->thread;
2684 int cpu = smp_processor_id();
2685- struct tss_struct *tss = &per_cpu(init_tss, cpu);
2686+ struct tss_struct *tss = init_tss + cpu;
2687
2688 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
2689
2690@@ -672,6 +680,11 @@ struct task_struct fastcall * __switch_t
2691 */
2692 savesegment(gs, prev->gs);
2693
2694+#ifdef CONFIG_PAX_MEMORY_UDEREF
2695+ if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
2696+ __set_fs(task_thread_info(next_p)->addr_limit, cpu);
2697+#endif
2698+
2699 /*
2700 * Load the per-thread Thread-Local Storage descriptor.
2701 */
2702@@ -838,6 +851,12 @@ asmlinkage int sys_set_thread_area(struc
2703
2704 if (copy_from_user(&info, u_info, sizeof(info)))
2705 return -EFAULT;
2706+
2707+#ifdef CONFIG_PAX_SEGMEXEC
2708+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2709+ return -EINVAL;
2710+#endif
2711+
2712 idx = info.entry_number;
2713
2714 /*
2715@@ -926,9 +945,28 @@ asmlinkage int sys_get_thread_area(struc
2716 return 0;
2717 }
2718
2719-unsigned long arch_align_stack(unsigned long sp)
2720+#ifdef CONFIG_PAX_RANDKSTACK
2721+asmlinkage void pax_randomize_kstack(void)
2722 {
2723- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
2724- sp -= get_random_int() % 8192;
2725- return sp & ~0xf;
2726+ struct tss_struct *tss;
2727+ unsigned long time;
2728+
2729+ if (!randomize_va_space)
2730+ return;
2731+
2732+ tss = init_tss + smp_processor_id();
2733+ rdtscl(time);
2734+
2735+ /* P4 seems to return a 0 LSB, ignore it */
2736+#ifdef CONFIG_MPENTIUM4
2737+ time &= 0x1EUL;
2738+ time <<= 2;
2739+#else
2740+ time &= 0xFUL;
2741+ time <<= 3;
2742+#endif
2743+
2744+ tss->x86_tss.esp0 ^= time;
2745+ current->thread.esp0 = tss->x86_tss.esp0;
2746 }
2747+#endif
2748diff -urNp linux-2.6.22.1/arch/i386/kernel/ptrace.c linux-2.6.22.1/arch/i386/kernel/ptrace.c
2749--- linux-2.6.22.1/arch/i386/kernel/ptrace.c 2007-07-10 14:56:30.000000000 -0400
2750+++ linux-2.6.22.1/arch/i386/kernel/ptrace.c 2007-08-02 11:38:45.000000000 -0400
3ba9fddb 2751@@ -161,17 +162,20 @@ static unsigned long convert_eip_to_line
2752 * and APM bios ones we just ignore here.
2753 */
2754 if (seg & LDT_SEGMENT) {
2755- u32 *desc;
2756+ struct desc_struct *desc;
2757 unsigned long base;
2758
2759 down(&child->mm->context.sem);
2760- desc = child->mm->context.ldt + (seg & ~7);
2761- base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
2762-
2763- /* 16-bit code segment? */
2764- if (!((desc[1] >> 22) & 1))
2765- addr &= 0xffff;
2766- addr += base;
2767+ if ((seg >> 3) < child->mm->context.size) {
2768+ desc = &child->mm->context.ldt[seg >> 3];
2769+ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
2770+
2771+ /* 16-bit code segment? */
2772+ if (!((desc->b >> 22) & 1))
2773+ addr &= 0xffff;
2774+ addr += base;
2775+ } else
2776+ addr = -EINVAL;
2777 up(&child->mm->context.sem);
2778 }
2779 return addr;
2780@@ -183,6 +187,9 @@ static inline int is_setting_trap_flag(s
2781 unsigned char opcode[15];
2782 unsigned long addr = convert_eip_to_linear(child, regs);
2783
2784+ if (addr == -EINVAL)
2785+ return 0;
2786+
2787 copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
2788 for (i = 0; i < copied; i++) {
2789 switch (opcode[i]) {
2790@@ -334,6 +341,11 @@ ptrace_set_thread_area(struct task_struc
2791 if (copy_from_user(&info, user_desc, sizeof(info)))
2792 return -EFAULT;
2793
2794+#ifdef CONFIG_PAX_SEGMEXEC
2795+ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2796+ return -EINVAL;
2797+#endif
2798+
2799 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2800 return -EINVAL;
2801
2802@@ -424,6 +436,17 @@ long arch_ptrace(struct task_struct *chi
2803 if(addr == (long) &dummy->u_debugreg[5]) break;
2804 if(addr < (long) &dummy->u_debugreg[4] &&
2805 ((unsigned long) data) >= TASK_SIZE-3) break;
2806+
2807+#ifdef CONFIG_GRKERNSEC
2808+ if(addr >= (long) &dummy->u_debugreg[0] &&
2809+ addr <= (long) &dummy->u_debugreg[3]){
2810+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
2811+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
2812+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
2813+ if((type & 1) && (data & align))
2814+ break;
2815+ }
2816+#endif
2817
2818 /* Sanity-check data. Take one half-byte at once with
2819 * check = (val >> (16 + 4*i)) & 0xf. It contains the
2820@@ -640,7 +663,7 @@ void send_sigtrap(struct task_struct *ts
2821 info.si_code = TRAP_BRKPT;
2822
2823 /* User-mode eip? */
2824- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2825+ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2826
2827 /* Send us the fakey SIGTRAP */
2828 force_sig_info(SIGTRAP, &info, tsk);
2829diff -urNp linux-2.6.22.1/arch/i386/kernel/reboot.c linux-2.6.22.1/arch/i386/kernel/reboot.c
2830--- linux-2.6.22.1/arch/i386/kernel/reboot.c 2007-07-10 14:56:30.000000000 -0400
2831+++ linux-2.6.22.1/arch/i386/kernel/reboot.c 2007-08-02 11:38:45.000000000 -0400
2832@@ -26,7 +26,7 @@
2833 void (*pm_power_off)(void);
2834 EXPORT_SYMBOL(pm_power_off);
2835
2836-static int reboot_mode;
2837+static unsigned short reboot_mode;
2838 static int reboot_thru_bios;
2839
2840 #ifdef CONFIG_SMP
2841@@ -129,7 +129,7 @@ static struct dmi_system_id __initdata r
2842 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
2843 },
2844 },
2845- { }
2846+ { NULL, NULL, {{0, NULL}}, NULL}
2847 };
2848
2849 static int __init reboot_init(void)
2850@@ -147,18 +147,18 @@ core_initcall(reboot_init);
2851 doesn't work with at least one type of 486 motherboard. It is easy
2852 to stop this code working; hence the copious comments. */
2853
2854-static unsigned long long
2855-real_mode_gdt_entries [3] =
2856+static struct desc_struct
2857+real_mode_gdt_entries [3] __read_only =
2858 {
2859- 0x0000000000000000ULL, /* Null descriptor */
2860- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2861- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2862+ {0x00000000, 0x00000000}, /* Null descriptor */
2863+ {0x0000ffff, 0x00009b00}, /* 16-bit real-mode 64k code at 0x00000000 */
2864+ {0x0100ffff, 0x00009300} /* 16-bit real-mode 64k data at 0x00000100 */
2865 };
2866
2867-static struct Xgt_desc_struct
2868-real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
2869-real_mode_idt = { 0x3ff, 0 },
2870-no_idt = { 0, 0 };
2871+static const struct Xgt_desc_struct
2872+real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (struct desc_struct *)__pa(real_mode_gdt_entries), 0 },
2873+real_mode_idt = { 0x3ff, NULL, 0 },
2874+no_idt = { 0, NULL, 0 };
2875
2876
2877 /* This is 16-bit protected mode code to disable paging and the cache,
2878@@ -180,7 +180,7 @@ no_idt = { 0, 0 };
2879 More could be done here to set up the registers as if a CPU reset had
2880 occurred; hopefully real BIOSs don't assume much. */
2881
2882-static unsigned char real_mode_switch [] =
2883+static const unsigned char real_mode_switch [] =
2884 {
2885 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
2886 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
2887@@ -194,7 +194,7 @@ static unsigned char real_mode_switch []
2888 0x24, 0x10, /* f: andb $0x10,al */
2889 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
2890 };
2891-static unsigned char jump_to_bios [] =
2892+static const unsigned char jump_to_bios [] =
2893 {
2894 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
2895 };
2896@@ -204,8 +204,13 @@ static unsigned char jump_to_bios [] =
2897 * specified by the code and length parameters.
2898 * We assume that length will aways be less that 100!
2899 */
2900-void machine_real_restart(unsigned char *code, int length)
2901+void machine_real_restart(const unsigned char *code, unsigned int length)
2902 {
2903+
2904+#ifdef CONFIG_PAX_KERNEXEC
2905+ unsigned long cr0;
2906+#endif
2907+
2908 local_irq_disable();
2909
2910 /* Write zero to CMOS register number 0x0f, which the BIOS POST
2911@@ -226,8 +231,16 @@ void machine_real_restart(unsigned char
2912 from the kernel segment. This assumes the kernel segment starts at
2913 virtual address PAGE_OFFSET. */
2914
2915- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2916- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2917+#ifdef CONFIG_PAX_KERNEXEC
2918+ pax_open_kernel(cr0);
2919+#endif
2920+
2921+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2922+ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
2923+
2924+#ifdef CONFIG_PAX_KERNEXEC
2925+ pax_close_kernel(cr0);
2926+#endif
2927
2928 /*
2929 * Use `swapper_pg_dir' as our page directory.
2930@@ -240,7 +253,7 @@ void machine_real_restart(unsigned char
2931 REBOOT.COM programs, and the previous reset routine did this
2932 too. */
2933
2934- *((unsigned short *)0x472) = reboot_mode;
2935+ *(unsigned short *)(__va(0x472)) = reboot_mode;
2936
2937 /* For the switch to real mode, copy some code to low memory. It has
2938 to be in the first 64k because it is running in 16-bit mode, and it
2939@@ -248,9 +261,8 @@ void machine_real_restart(unsigned char
2940 off paging. Copy it near the end of the first page, out of the way
2941 of BIOS variables. */
2942
2943- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2944- real_mode_switch, sizeof (real_mode_switch));
2945- memcpy ((void *) (0x1000 - 100), code, length);
2946+ memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
2947+ memcpy(__va(0x1000 - 100), code, length);
2948
2949 /* Set up the IDT for real mode. */
2950
2951@@ -336,7 +348,7 @@ static void native_machine_emergency_res
2952 __asm__ __volatile__("int3");
2953 }
2954 /* rebooting needs to touch the page at absolute addr 0 */
2955- *((unsigned short *)__va(0x472)) = reboot_mode;
2956+ *(unsigned short *)(__va(0x472)) = reboot_mode;
2957 for (;;) {
2958 mach_reboot_fixups(); /* for board specific fixups */
2959 mach_reboot();
2960diff -urNp linux-2.6.22.1/arch/i386/kernel/setup.c linux-2.6.22.1/arch/i386/kernel/setup.c
2961--- linux-2.6.22.1/arch/i386/kernel/setup.c 2007-07-10 14:56:30.000000000 -0400
2962+++ linux-2.6.22.1/arch/i386/kernel/setup.c 2007-08-02 11:38:45.000000000 -0400
2963@@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
2964 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2965 EXPORT_SYMBOL(boot_cpu_data);
2966
2967+#ifdef CONFIG_X86_PAE
2968+unsigned long mmu_cr4_features = X86_CR4_PAE;
2969+#else
2970 unsigned long mmu_cr4_features;
2971+#endif
2972
2973 /* for MCA, but anyone else can use it if they want */
2974 unsigned int machine_id;
2975@@ -404,8 +408,8 @@ void __init setup_bootmem_allocator(void
2976 * the (very unlikely) case of us accidentally initializing the
2977 * bootmem allocator with an invalid RAM area.
2978 */
2979- reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
2980- bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
2981+ reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
2982+ bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
2983
2984 /*
2985 * reserve physical page 0 - it's a special BIOS page on many boxes,
2986@@ -559,14 +563,14 @@ void __init setup_arch(char **cmdline_p)
2987
2988 if (!MOUNT_ROOT_RDONLY)
2989 root_mountflags &= ~MS_RDONLY;
2990- init_mm.start_code = (unsigned long) _text;
2991- init_mm.end_code = (unsigned long) _etext;
2992+ init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2993+ init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2994 init_mm.end_data = (unsigned long) _edata;
2995 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2996
2997- code_resource.start = virt_to_phys(_text);
2998- code_resource.end = virt_to_phys(_etext)-1;
2999- data_resource.start = virt_to_phys(_etext);
3000+ code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
3001+ code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
3002+ data_resource.start = virt_to_phys(_data);
3003 data_resource.end = virt_to_phys(_edata)-1;
3004
3005 parse_early_param();
3006@@ -658,3 +662,24 @@ void __init setup_arch(char **cmdline_p)
3007 #endif
3008 #endif
3009 }
3010+
3011+unsigned long __per_cpu_offset[NR_CPUS] __read_only;
3012+
3013+EXPORT_SYMBOL(__per_cpu_offset);
3014+
3015+void __init setup_per_cpu_areas(void)
3016+{
3017+ unsigned long size, i;
3018+ char *ptr;
3019+ unsigned long nr_possible_cpus = num_possible_cpus();
3020+
3021+ /* Copy section for each CPU (we discard the original) */
3022+ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
3023+ ptr = alloc_bootmem_pages(size * nr_possible_cpus);
3024+
3025+ for_each_possible_cpu(i) {
3026+ __per_cpu_offset[i] = (unsigned long)ptr;
3027+ memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
3028+ ptr += size;
3029+ }
3030+}
3031diff -urNp linux-2.6.22.1/arch/i386/kernel/signal.c linux-2.6.22.1/arch/i386/kernel/signal.c
3032--- linux-2.6.22.1/arch/i386/kernel/signal.c 2007-07-10 14:56:30.000000000 -0400
3033+++ linux-2.6.22.1/arch/i386/kernel/signal.c 2007-08-02 11:38:45.000000000 -0400
3034@@ -350,9 +350,9 @@ static int setup_frame(int sig, struct k
3035 }
3036
3037 if (current->binfmt->hasvdso)
3038- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
3039+ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
3040 else
3041- restorer = (void *)&frame->retcode;
3042+ restorer = (void __user *)&frame->retcode;
3043 if (ka->sa.sa_flags & SA_RESTORER)
3044 restorer = ka->sa.sa_restorer;
3045
3046@@ -448,7 +448,8 @@ static int setup_rt_frame(int sig, struc
3047 goto give_sigsegv;
3048
3049 /* Set up to return from userspace. */
3050- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
3051+
3052+ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
3053 if (ka->sa.sa_flags & SA_RESTORER)
3054 restorer = ka->sa.sa_restorer;
3055 err |= __put_user(restorer, &frame->pretcode);
3056@@ -581,7 +582,7 @@ static void fastcall do_signal(struct pt
3057 * before reaching here, so testing against kernel
3058 * CS suffices.
3059 */
3060- if (!user_mode(regs))
3061+ if (!user_mode_novm(regs))
3062 return;
3063
3064 if (test_thread_flag(TIF_RESTORE_SIGMASK))
3065diff -urNp linux-2.6.22.1/arch/i386/kernel/smpboot.c linux-2.6.22.1/arch/i386/kernel/smpboot.c
3066--- linux-2.6.22.1/arch/i386/kernel/smpboot.c 2007-07-10 14:56:30.000000000 -0400
3067+++ linux-2.6.22.1/arch/i386/kernel/smpboot.c 2007-08-03 12:34:39.000000000 -0400
3068@@ -118,7 +118,7 @@ DEFINE_PER_CPU(int, cpu_state) = { 0 };
3069 * has made sure it's suitably aligned.
3070 */
3071
3072-static unsigned long __devinit setup_trampoline(void)
3073+static unsigned long __cpuinit setup_trampoline(void)
3074 {
3075 memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data);
3076 return virt_to_phys(trampoline_base);
3077@@ -773,6 +773,10 @@ static int __cpuinit do_boot_cpu(int api
3078 unsigned long start_eip;
3079 unsigned short nmi_high = 0, nmi_low = 0;
3080
3081+#ifdef CONFIG_PAX_KERNEXEC
3082+ unsigned long cr0;
3083+#endif
3084+
3085 /*
3086 * Save current MTRR state in case it was changed since early boot
3087 * (e.g. by the ACPI SMI) to initialize new CPUs with MTRRs in sync:
3088@@ -789,7 +793,16 @@ static int __cpuinit do_boot_cpu(int api
3089
3090 init_gdt(cpu);
3091 per_cpu(current_task, cpu) = idle;
3092- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
3093+
3094+#ifdef CONFIG_PAX_KERNEXEC
3095+ pax_open_kernel(cr0);
3096+#endif
3097+
3098+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
3099+
3100+#ifdef CONFIG_PAX_KERNEXEC
3101+ pax_close_kernel(cr0);
3102+#endif
3103
3104 idle->thread.eip = (unsigned long) start_secondary;
3105 /* start_eip had better be page-aligned! */
3106diff -urNp linux-2.6.22.1/arch/i386/kernel/smp.c linux-2.6.22.1/arch/i386/kernel/smp.c
3107--- linux-2.6.22.1/arch/i386/kernel/smp.c 2007-07-10 14:56:30.000000000 -0400
3108+++ linux-2.6.22.1/arch/i386/kernel/smp.c 2007-08-02 11:38:45.000000000 -0400
3109@@ -103,7 +103,7 @@
3110 * about nothing of note with C stepping upwards.
3111 */
3112
3113-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
3114+DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
3115
3116 /*
3117 * the following functions deal with sending IPIs between CPUs.
3118diff -urNp linux-2.6.22.1/arch/i386/kernel/smpcommon.c linux-2.6.22.1/arch/i386/kernel/smpcommon.c
3119--- linux-2.6.22.1/arch/i386/kernel/smpcommon.c 2007-07-10 14:56:30.000000000 -0400
3120+++ linux-2.6.22.1/arch/i386/kernel/smpcommon.c 2007-08-03 12:34:39.000000000 -0400
3121@@ -3,6 +3,7 @@
3122 */
3123 #include <linux/module.h>
3124 #include <asm/smp.h>
3125+#include <asm/sections.h>
3126
3127 DEFINE_PER_CPU(unsigned long, this_cpu_off);
3128 EXPORT_PER_CPU_SYMBOL(this_cpu_off);
3129@@ -14,10 +15,29 @@ __cpuinit void init_gdt(int cpu)
3130 {
3131 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
3132
3133- pack_descriptor((u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3134- (u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3135- __per_cpu_offset[cpu], 0xFFFFF,
3136- 0x80 | DESCTYPE_S | 0x2, 0x8);
3137+#ifdef CONFIG_PAX_KERNEXEC
3138+ unsigned long cr0;
3139+
3140+ pax_open_kernel(cr0);
3141+#endif
3142+
3143+ if (cpu)
3144+ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
3145+
3146+ if (PERCPU_ENOUGH_ROOM <= 64*1024*1024)
3147+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3148+ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3149+ __per_cpu_offset[cpu], PERCPU_ENOUGH_ROOM-1,
3150+ 0x80 | DESCTYPE_S | 0x3, 0x4);
3151+ else
3152+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PERCPU].a,
3153+ (__u32 *)&gdt[GDT_ENTRY_PERCPU].b,
3154+ __per_cpu_offset[cpu], ((PERCPU_ENOUGH_ROOM-1) >> PAGE_SHIFT),
3155+ 0x80 | DESCTYPE_S | 0x3, 0xC);
3156+
3157+#ifdef CONFIG_PAX_KERNEXEC
3158+ pax_close_kernel(cr0);
3159+#endif
3160
3161 per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
3162 per_cpu(cpu_number, cpu) = cpu;
3163diff -urNp linux-2.6.22.1/arch/i386/kernel/syscall_table.S linux-2.6.22.1/arch/i386/kernel/syscall_table.S
3164--- linux-2.6.22.1/arch/i386/kernel/syscall_table.S 2007-07-10 14:56:30.000000000 -0400
3165+++ linux-2.6.22.1/arch/i386/kernel/syscall_table.S 2007-08-02 11:38:45.000000000 -0400
3166@@ -1,3 +1,4 @@
3167+.section .rodata,"a",@progbits
3168 ENTRY(sys_call_table)
3169 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
3170 .long sys_exit
3171diff -urNp linux-2.6.22.1/arch/i386/kernel/sysenter.c linux-2.6.22.1/arch/i386/kernel/sysenter.c
3172--- linux-2.6.22.1/arch/i386/kernel/sysenter.c 2007-07-10 14:56:30.000000000 -0400
3173+++ linux-2.6.22.1/arch/i386/kernel/sysenter.c 2007-08-02 11:38:45.000000000 -0400
3174@@ -176,7 +176,7 @@ static __init void relocate_vdso(Elf32_E
3175 void enable_sep_cpu(void)
3176 {
3177 int cpu = get_cpu();
3178- struct tss_struct *tss = &per_cpu(init_tss, cpu);
3179+ struct tss_struct *tss = init_tss + cpu;
3180
3181 if (!boot_cpu_has(X86_FEATURE_SEP)) {
3182 put_cpu();
3183@@ -199,7 +199,7 @@ static int __init gate_vma_init(void)
3184 gate_vma.vm_start = FIXADDR_USER_START;
3185 gate_vma.vm_end = FIXADDR_USER_END;
3186 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
3187- gate_vma.vm_page_prot = __P101;
3188+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
3189 /*
3190 * Make sure the vDSO gets into every core dump.
3191 * Dumping its contents makes post-mortem fully interpretable later
3192@@ -282,7 +282,7 @@ int arch_setup_additional_pages(struct l
3193 if (compat)
3194 addr = VDSO_HIGH_BASE;
3195 else {
3196- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
3197+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
3198 if (IS_ERR_VALUE(addr)) {
3199 ret = addr;
3200 goto up_fail;
3201@@ -307,7 +307,7 @@ int arch_setup_additional_pages(struct l
3202 goto up_fail;
3203 }
3204
3205- current->mm->context.vdso = (void *)addr;
3206+ current->mm->context.vdso = addr;
3207 current_thread_info()->sysenter_return =
3208 (void *)VDSO_SYM(&SYSENTER_RETURN);
3209
3210@@ -319,8 +319,14 @@ int arch_setup_additional_pages(struct l
3211
3212 const char *arch_vma_name(struct vm_area_struct *vma)
3213 {
3214- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
b5630f59 3215+ if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
3ba9fddb 3216 return "[vdso]";
3217+
3218+#ifdef CONFIG_PAX_SEGMEXEC
b5630f59 3219+ if (vma->vmm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
3ba9fddb 3220+ return "[vdso]";
3221+#endif
3222+
3223 return NULL;
3224 }
3225
3226@@ -329,7 +335,7 @@ struct vm_area_struct *get_gate_vma(stru
3227 struct mm_struct *mm = tsk->mm;
3228
3229 /* Check to see if this task was created in compat vdso mode */
3230- if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
3231+ if (mm && mm->context.vdso == VDSO_HIGH_BASE)
3232 return &gate_vma;
3233 return NULL;
3234 }
3235diff -urNp linux-2.6.22.1/arch/i386/kernel/sys_i386.c linux-2.6.22.1/arch/i386/kernel/sys_i386.c
3236--- linux-2.6.22.1/arch/i386/kernel/sys_i386.c 2007-07-10 14:56:30.000000000 -0400
3237+++ linux-2.6.22.1/arch/i386/kernel/sys_i386.c 2007-08-02 11:38:45.000000000 -0400
3238@@ -40,6 +40,21 @@ asmlinkage int sys_pipe(unsigned long __
3239 return error;
3240 }
3241
3242+int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
3243+{
3244+ unsigned long task_size = TASK_SIZE;
3245+
3246+#ifdef CONFIG_PAX_SEGMEXEC
3247+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
3248+ task_size = SEGMEXEC_TASK_SIZE;
3249+#endif
3250+
3251+ if (len > task_size || addr > task_size - len)
3252+ return -EINVAL;
3253+
3254+ return 0;
3255+}
3256+
3257 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
3258 unsigned long prot, unsigned long flags,
3259 unsigned long fd, unsigned long pgoff)
3260@@ -99,6 +114,205 @@ out:
3261 return err;
3262 }
3263
3264+unsigned long
3265+arch_get_unmapped_area(struct file *filp, unsigned long addr,
3266+ unsigned long len, unsigned long pgoff, unsigned long flags)
3267+{
3268+ struct mm_struct *mm = current->mm;
3269+ struct vm_area_struct *vma;
3270+ unsigned long start_addr, task_size = TASK_SIZE;
3271+
3272+#ifdef CONFIG_PAX_SEGMEXEC
3273+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3274+ task_size = SEGMEXEC_TASK_SIZE;
3275+#endif
3276+
3277+ if (len > task_size)
3278+ return -ENOMEM;
3279+
3280+ if (flags & MAP_FIXED)
3281+ return addr;
3282+
3283+#ifdef CONFIG_PAX_RANDMMAP
3284+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3285+#endif
3286+
3287+ if (addr) {
3288+ addr = PAGE_ALIGN(addr);
3289+ vma = find_vma(mm, addr);
3290+ if (task_size - len >= addr &&
3291+ (!vma || addr + len <= vma->vm_start))
3292+ return addr;
3293+ }
3294+ if (len > mm->cached_hole_size) {
3295+ start_addr = addr = mm->free_area_cache;
3296+ } else {
3297+ start_addr = addr = mm->mmap_base;
3298+ mm->cached_hole_size = 0;
3299+ }
3300+
3301+#ifdef CONFIG_PAX_PAGEEXEC
3302+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
3303+ start_addr = 0x00110000UL;
3304+
3305+#ifdef CONFIG_PAX_RANDMMAP
3306+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3307+ start_addr += mm->delta_mmap & 0x03FFF000UL;
3308+#endif
3309+
3310+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
3311+ start_addr = addr = mm->mmap_base;
3312+ else
3313+ addr = start_addr;
3314+ }
3315+#endif
3316+
3317+full_search:
3318+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3319+ /* At this point: (!vma || addr < vma->vm_end). */
3320+ if (task_size - len < addr) {
3321+ /*
3322+ * Start a new search - just in case we missed
3323+ * some holes.
3324+ */
3325+ if (start_addr != mm->mmap_base) {
3326+ start_addr = addr = mm->mmap_base;
3327+ mm->cached_hole_size = 0;
3328+ goto full_search;
3329+ }
3330+ return -ENOMEM;
3331+ }
3332+ if (!vma || addr + len <= vma->vm_start) {
3333+ /*
3334+ * Remember the place where we stopped the search:
3335+ */
3336+ mm->free_area_cache = addr + len;
3337+ return addr;
3338+ }
3339+ if (addr + mm->cached_hole_size < vma->vm_start)
3340+ mm->cached_hole_size = vma->vm_start - addr;
3341+ addr = vma->vm_end;
3342+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
3343+ start_addr = addr = mm->mmap_base;
3344+ mm->cached_hole_size = 0;
3345+ goto full_search;
3346+ }
3347+ }
3348+}
3349+
3350+unsigned long
3351+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
3352+ const unsigned long len, const unsigned long pgoff,
3353+ const unsigned long flags)
3354+{
3355+ struct vm_area_struct *vma;
3356+ struct mm_struct *mm = current->mm;
3357+ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
3358+
3359+#ifdef CONFIG_PAX_SEGMEXEC
3360+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3361+ task_size = SEGMEXEC_TASK_SIZE;
3362+#endif
3363+
3364+ /* requested length too big for entire address space */
3365+ if (len > task_size)
3366+ return -ENOMEM;
3367+
3368+ if (flags & MAP_FIXED)
3369+ return addr;
3370+
3371+#ifdef CONFIG_PAX_PAGEEXEC
3372+ if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
3373+ goto bottomup;
3374+#endif
3375+
3376+#ifdef CONFIG_PAX_RANDMMAP
3377+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3378+#endif
3379+
3380+ /* requesting a specific address */
3381+ if (addr) {
3382+ addr = PAGE_ALIGN(addr);
3383+ vma = find_vma(mm, addr);
3384+ if (task_size - len >= addr &&
3385+ (!vma || addr + len <= vma->vm_start))
3386+ return addr;
3387+ }
3388+
3389+ /* check if free_area_cache is useful for us */
3390+ if (len <= mm->cached_hole_size) {
3391+ mm->cached_hole_size = 0;
3392+ mm->free_area_cache = mm->mmap_base;
3393+ }
3394+
3395+ /* either no address requested or can't fit in requested address hole */
3396+ addr = mm->free_area_cache;
3397+
3398+ /* make sure it can fit in the remaining address space */
3399+ if (addr > len) {
3400+ vma = find_vma(mm, addr-len);
3401+ if (!vma || addr <= vma->vm_start)
3402+ /* remember the address as a hint for next time */
3403+ return (mm->free_area_cache = addr-len);
3404+ }
3405+
3406+ if (mm->mmap_base < len)
3407+ goto bottomup;
3408+
3409+ addr = mm->mmap_base-len;
3410+
3411+ do {
3412+ /*
3413+ * Lookup failure means no vma is above this address,
3414+ * else if new region fits below vma->vm_start,
3415+ * return with success:
3416+ */
3417+ vma = find_vma(mm, addr);
3418+ if (!vma || addr+len <= vma->vm_start)
3419+ /* remember the address as a hint for next time */
3420+ return (mm->free_area_cache = addr);
3421+
3422+ /* remember the largest hole we saw so far */
3423+ if (addr + mm->cached_hole_size < vma->vm_start)
3424+ mm->cached_hole_size = vma->vm_start - addr;
3425+
3426+ /* try just below the current vma->vm_start */
3427+ addr = vma->vm_start-len;
3428+ } while (len < vma->vm_start);
3429+
3430+bottomup:
3431+ /*
3432+ * A failed mmap() very likely causes application failure,
3433+ * so fall back to the bottom-up function here. This scenario
3434+ * can happen with large stack limits and large mmap()
3435+ * allocations.
3436+ */
3437+
3438+#ifdef CONFIG_PAX_SEGMEXEC
3439+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
3440+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
3441+ else
3442+#endif
3443+
3444+ mm->mmap_base = TASK_UNMAPPED_BASE;
3445+
3446+#ifdef CONFIG_PAX_RANDMMAP
3447+ if (mm->pax_flags & MF_PAX_RANDMMAP)
3448+ mm->mmap_base += mm->delta_mmap;
3449+#endif
3450+
3451+ mm->free_area_cache = mm->mmap_base;
3452+ mm->cached_hole_size = ~0UL;
3453+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
3454+ /*
3455+ * Restore the topdown base:
3456+ */
3457+ mm->mmap_base = base;
3458+ mm->free_area_cache = base;
3459+ mm->cached_hole_size = ~0UL;
3460+
3461+ return addr;
3462+}
3463
3464 struct sel_arg_struct {
3465 unsigned long n;
3466diff -urNp linux-2.6.22.1/arch/i386/kernel/time.c linux-2.6.22.1/arch/i386/kernel/time.c
3467--- linux-2.6.22.1/arch/i386/kernel/time.c 2007-07-10 14:56:30.000000000 -0400
3468+++ linux-2.6.22.1/arch/i386/kernel/time.c 2007-08-02 11:38:45.000000000 -0400
3469@@ -132,20 +132,30 @@ unsigned long profile_pc(struct pt_regs
3470 if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
3471 in_lock_functions(pc)) {
3472 #ifdef CONFIG_FRAME_POINTER
3473- return *(unsigned long *)(regs->ebp + 4);
3474+ return *(unsigned long *)(regs->ebp + 4) + __KERNEL_TEXT_OFFSET;
3475 #else
3476 unsigned long *sp = (unsigned long *)&regs->esp;
3477
3478 /* Return address is either directly at stack pointer
3479 or above a saved eflags. Eflags has bits 22-31 zero,
3480 kernel addresses don't. */
3481+
3482+#ifdef CONFIG_PAX_KERNEXEC
3483+ return sp[0] + __KERNEL_TEXT_OFFSET;
3484+#else
3485 if (sp[0] >> 22)
3486 return sp[0];
3487 if (sp[1] >> 22)
3488 return sp[1];
3489 #endif
3490+
3491+#endif
3492 }
3493 #endif
3494+
3495+ if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs))
3496+ pc += __KERNEL_TEXT_OFFSET;
3497+
3498 return pc;
3499 }
3500 EXPORT_SYMBOL(profile_pc);
3501diff -urNp linux-2.6.22.1/arch/i386/kernel/traps.c linux-2.6.22.1/arch/i386/kernel/traps.c
3502--- linux-2.6.22.1/arch/i386/kernel/traps.c 2007-07-10 14:56:30.000000000 -0400
3503+++ linux-2.6.22.1/arch/i386/kernel/traps.c 2007-08-02 11:38:45.000000000 -0400
3504@@ -31,6 +31,7 @@
3505 #include <linux/uaccess.h>
3506 #include <linux/nmi.h>
3507 #include <linux/bug.h>
3508+#include <linux/binfmts.h>
3509
3510 #ifdef CONFIG_EISA
3511 #include <linux/ioport.h>
3512@@ -66,12 +67,7 @@ asmlinkage int system_call(void);
3513 /* Do we ignore FPU interrupts ? */
3514 char ignore_fpu_irq = 0;
3515
3516-/*
3517- * The IDT has to be page-aligned to simplify the Pentium
3518- * F0 0F bug workaround.. We have a special link segment
3519- * for this.
3520- */
3521-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
3522+extern struct desc_struct idt_table[256];
3523
3524 asmlinkage void divide_error(void);
3525 asmlinkage void debug(void);
3526@@ -283,7 +279,7 @@ void show_registers(struct pt_regs *regs
3527 esp = (unsigned long) (&regs->esp);
3528 savesegment(ss, ss);
3529 savesegment(gs, gs);
3530- if (user_mode_vm(regs)) {
3531+ if (user_mode(regs)) {
3532 in_kernel = 0;
3533 esp = regs->esp;
3534 ss = regs->xss & 0xffff;
3535@@ -315,17 +311,18 @@ void show_registers(struct pt_regs *regs
3536 unsigned int code_prologue = code_bytes * 43 / 64;
3537 unsigned int code_len = code_bytes;
3538 unsigned char c;
3539+ unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->xcs) >> 3]);
3540
3541 printk("\n" KERN_EMERG "Stack: ");
3542 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
3543
3544 printk(KERN_EMERG "Code: ");
3545
3546- eip = (u8 *)regs->eip - code_prologue;
3547+ eip = (u8 *)regs->eip - code_prologue + cs_base;
3548 if (eip < (u8 *)PAGE_OFFSET ||
3549 probe_kernel_address(eip, c)) {
3550 /* try starting at EIP */
3551- eip = (u8 *)regs->eip;
3552+ eip = (u8 *)regs->eip + cs_base;
3553 code_len = code_len - code_prologue + 1;
3554 }
3555 for (i = 0; i < code_len; i++, eip++) {
3556@@ -334,7 +330,7 @@ void show_registers(struct pt_regs *regs
3557 printk(" Bad EIP value.");
3558 break;
3559 }
3560- if (eip == (u8 *)regs->eip)
3561+ if (eip == (u8 *)regs->eip + cs_base)
3562 printk("<%02x> ", c);
3563 else
3564 printk("%02x ", c);
3565@@ -347,6 +343,7 @@ int is_valid_bugaddr(unsigned long eip)
3566 {
3567 unsigned short ud2;
3568
3569+ eip += __KERNEL_TEXT_OFFSET;
3570 if (eip < PAGE_OFFSET)
3571 return 0;
3572 if (probe_kernel_address((unsigned short *)eip, ud2))
3573@@ -453,7 +450,7 @@ void die(const char * str, struct pt_reg
3574
3575 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
3576 {
3577- if (!user_mode_vm(regs))
3578+ if (!user_mode(regs))
3579 die(str, regs, err);
3580 }
3581
3582@@ -469,7 +466,7 @@ static void __kprobes do_trap(int trapnr
3583 goto trap_signal;
3584 }
3585
3586- if (!user_mode(regs))
3587+ if (!user_mode_novm(regs))
3588 goto kernel_trap;
3589
3590 trap_signal: {
3591@@ -572,7 +569,7 @@ fastcall void __kprobes do_general_prote
3592 long error_code)
3593 {
3594 int cpu = get_cpu();
3595- struct tss_struct *tss = &per_cpu(init_tss, cpu);
3596+ struct tss_struct *tss = &init_tss[cpu];
3597 struct thread_struct *thread = &current->thread;
3598
3599 /*
3600@@ -605,9 +602,25 @@ fastcall void __kprobes do_general_prote
3601 if (regs->eflags & VM_MASK)
3602 goto gp_in_vm86;
3603
3604- if (!user_mode(regs))
3605+ if (!user_mode_novm(regs))
3606 goto gp_in_kernel;
3607
3608+#ifdef CONFIG_PAX_PAGEEXEC
3609+ if (!nx_enabled && current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
3610+ struct mm_struct *mm = current->mm;
3611+ unsigned long limit;
3612+
3613+ down_write(&mm->mmap_sem);
3614+ limit = mm->context.user_cs_limit;
3615+ if (limit < TASK_SIZE) {
3616+ track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
3617+ up_write(&mm->mmap_sem);
3618+ return;
3619+ }
3620+ up_write(&mm->mmap_sem);
3621+ }
3622+#endif
3623+
3624 current->thread.error_code = error_code;
3625 current->thread.trap_no = 13;
3626 force_sig(SIGSEGV, current);
3627@@ -625,6 +638,13 @@ gp_in_kernel:
3628 if (notify_die(DIE_GPF, "general protection fault", regs,
3629 error_code, 13, SIGSEGV) == NOTIFY_STOP)
3630 return;
3631+
3632+#ifdef CONFIG_PAX_KERNEXEC
3633+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
3634+ die("PAX: suspicious general protection fault", regs, error_code);
3635+ else
3636+#endif
3637+
3638 die("general protection fault", regs, error_code);
3639 }
3640 }
3641@@ -706,7 +726,7 @@ void __kprobes die_nmi(struct pt_regs *r
3642 /* If we are in kernel we are probably nested up pretty bad
3643 * and might aswell get out now while we still can.
3644 */
3645- if (!user_mode_vm(regs)) {
3646+ if (!user_mode(regs)) {
3647 current->thread.trap_no = 2;
3648 crash_kexec(regs);
3649 }
3650@@ -838,7 +858,7 @@ fastcall void __kprobes do_debug(struct
3651 * check for kernel mode by just checking the CPL
3652 * of CS.
3653 */
3654- if (!user_mode(regs))
3655+ if (!user_mode_novm(regs))
3656 goto clear_TF_reenable;
3657 }
3658
3659@@ -1016,18 +1036,14 @@ fastcall void do_spurious_interrupt_bug(
3660 fastcall unsigned long patch_espfix_desc(unsigned long uesp,
3661 unsigned long kesp)
3662 {
3663- struct desc_struct *gdt = __get_cpu_var(gdt_page).gdt;
3664 unsigned long base = (kesp - uesp) & -THREAD_SIZE;
3665 unsigned long new_kesp = kesp - base;
3666 unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
3667- __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
3668+ __u32 a, b;
3669+
3670 /* Set up base for espfix segment */
3671- desc &= 0x00f0ff0000000000ULL;
3672- desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
3673- ((((__u64)base) << 32) & 0xff00000000000000ULL) |
3674- ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
3675- (lim_pages & 0xffff);
3676- *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
3677+ pack_descriptor(&a, &b, base, lim_pages, 0x93, 0xC);
3678+ write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, a, b);
3679 return new_kesp;
3680 }
3681
3682@@ -1075,7 +1091,7 @@ void __init trap_init_f00f_bug(void)
3683 * Update the IDT descriptor and reload the IDT so that
3684 * it uses the read-only mapped virtual address.
3685 */
3686- idt_descr.address = fix_to_virt(FIX_F00F_IDT);
3687+ idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
3688 load_idt(&idt_descr);
3689 }
3690 #endif
3691diff -urNp linux-2.6.22.1/arch/i386/kernel/tsc.c linux-2.6.22.1/arch/i386/kernel/tsc.c
3692--- linux-2.6.22.1/arch/i386/kernel/tsc.c 2007-07-10 14:56:30.000000000 -0400
3693+++ linux-2.6.22.1/arch/i386/kernel/tsc.c 2007-08-02 11:38:45.000000000 -0400
3694@@ -308,7 +308,7 @@ static struct dmi_system_id __initdata b
3695 DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
3696 },
3697 },
3698- {}
3699+ { NULL, NULL, {{0, NULL}}, NULL}
3700 };
3701
3702 /*
3703diff -urNp linux-2.6.22.1/arch/i386/kernel/vm86.c linux-2.6.22.1/arch/i386/kernel/vm86.c
3704--- linux-2.6.22.1/arch/i386/kernel/vm86.c 2007-07-10 14:56:30.000000000 -0400
3705+++ linux-2.6.22.1/arch/i386/kernel/vm86.c 2007-08-02 11:38:45.000000000 -0400
3706@@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state
3707 do_exit(SIGSEGV);
3708 }
3709
3710- tss = &per_cpu(init_tss, get_cpu());
3711+ tss = init_tss + get_cpu();
3712 current->thread.esp0 = current->thread.saved_esp0;
3713 current->thread.sysenter_cs = __KERNEL_CS;
3714 load_esp0(tss, &current->thread);
3715@@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
3716 tsk->thread.saved_fs = info->regs32->xfs;
3717 savesegment(gs, tsk->thread.saved_gs);
3718
3719- tss = &per_cpu(init_tss, get_cpu());
3720+ tss = init_tss + get_cpu();
3721 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
3722 if (cpu_has_sep)
3723 tsk->thread.sysenter_cs = 0;
3724diff -urNp linux-2.6.22/arch/i386/kernel/vmi.c linux-2.6.22/arch/i386/kernel/vmi.c
3725--- linux-2.6.22/arch/i386/kernel/vmi.c 2007-07-10 14:56:30.000000000 -0400
3726+++ linux-2.6.22/arch/i386/kernel/vmi.c 2007-07-10 14:56:30.000000000 -0400
3727@@ -96,18 +96,43 @@ static unsigned patch_internal(int call,
3728 {
3729 u64 reloc;
3730 struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
3731+
3732+#ifdef CONFIG_PAX_KERNEXEC
3733+ unsigned long cr0;
3734+#endif
3735+
3736 reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
3737 switch(rel->type) {
3738 case VMI_RELOCATION_CALL_REL:
3739 BUG_ON(len < 5);
3740+
3741+#ifdef CONFIG_PAX_KERNEXEC
3742+ pax_open_kernel(cr0);
3743+#endif
3744+
3745 *(char *)insns = MNEM_CALL;
3746 patch_offset(insns, rel->eip);
3747+
3748+#ifdef CONFIG_PAX_KERNEXEC
3749+ pax_close_kernel(cr0);
3750+#endif
3751+
3752 return 5;
3753
3754 case VMI_RELOCATION_JUMP_REL:
3755 BUG_ON(len < 5);
3756+
3757+#ifdef CONFIG_PAX_KERNEXEC
3758+ pax_open_kernel(cr0);
3759+#endif
3760+
3761 *(char *)insns = MNEM_JMP;
3762 patch_offset(insns, rel->eip);
3763+
3764+#ifdef CONFIG_PAX_KERNEXEC
3765+ pax_close_kernel(cr0);
3766+#endif
3767+
3768 return 5;
3769
3770 case VMI_RELOCATION_NOP:
3771@@ -485,14 +510,14 @@ static void vmi_set_pud(pud_t *pudp, pud
3772
3773 static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
3774 {
3775- const pte_t pte = { 0 };
3776+ const pte_t pte = __pte(0ULL);
3777 vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
3778 vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
3779 }
3780
3781 static void vmi_pmd_clear(pmd_t *pmd)
3782 {
3783- const pte_t pte = { 0 };
3784+ const pte_t pte = __pte(0ULL);
3785 vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
3786 vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
3787 }
3788@@ -521,8 +546,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
3789 ap.ss = __KERNEL_DS;
3790 ap.esp = (unsigned long) start_esp;
3791
3792- ap.ds = __USER_DS;
3793- ap.es = __USER_DS;
3794+ ap.ds = __KERNEL_DS;
3795+ ap.es = __KERNEL_DS;
3796 ap.fs = __KERNEL_PERCPU;
3797 ap.gs = 0;
3798
3799@@ -719,12 +744,20 @@ static inline int __init activate_vmi(vo
3800 u64 reloc;
3801 const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
3802
3803+#ifdef CONFIG_PAX_KERNEXEC
3804+ unsigned long cr0;
3805+#endif
3806+
3807 if (call_vrom_func(vmi_rom, vmi_init) != 0) {
3808 printk(KERN_ERR "VMI ROM failed to initialize!");
3809 return 0;
3810 }
3811 savesegment(cs, kernel_cs);
3812
3813+#ifdef CONFIG_PAX_KERNEXEC
3814+ pax_open_kernel(cr0);
3815+#endif
3816+
3817 paravirt_ops.paravirt_enabled = 1;
3818 paravirt_ops.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
3819
3820@@ -903,6 +936,10 @@ static inline int __init activate_vmi(vo
3821
3822 para_fill(safe_halt, Halt);
3823
3824+#ifdef CONFIG_PAX_KERNEXEC
3825+ pax_close_kernel(cr0);
3826+#endif
3827+
3828 /*
3829 * Alternative instruction rewriting doesn't happen soon enough
3830 * to convert VMI_IRET to a call instead of a jump; so we have
3831diff -urNp linux-2.6.22.1/arch/i386/kernel/vmlinux.lds.S linux-2.6.22.1/arch/i386/kernel/vmlinux.lds.S
3832--- linux-2.6.22.1/arch/i386/kernel/vmlinux.lds.S 2007-07-10 14:56:30.000000000 -0400
3833+++ linux-2.6.22.1/arch/i386/kernel/vmlinux.lds.S 2007-08-02 11:38:45.000000000 -0400
3834@@ -21,6 +21,13 @@
3835 #include <asm/page.h>
3836 #include <asm/cache.h>
3837 #include <asm/boot.h>
3838+#include <asm/segment.h>
3839+
3840+#ifdef CONFIG_X86_PAE
3841+#define PMD_SHIFT 21
3842+#else
3843+#define PMD_SHIFT 22
3844+#endif
3845
3846 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
3847 OUTPUT_ARCH(i386)
3848@@ -28,22 +35,124 @@ ENTRY(phys_startup_32)
3849 jiffies = jiffies_64;
3850
3851 PHDRS {
3852- text PT_LOAD FLAGS(5); /* R_E */
3853- data PT_LOAD FLAGS(7); /* RWE */
3854- note PT_NOTE FLAGS(0); /* ___ */
3855+ initdata PT_LOAD FLAGS(6); /* RW_ */
3856+ percpu PT_LOAD FLAGS(6); /* RW_ */
3857+ inittext PT_LOAD FLAGS(5); /* R_E */
3858+ text PT_LOAD FLAGS(5); /* R_E */
3859+ rodata PT_LOAD FLAGS(4); /* R__ */
3860+ data PT_LOAD FLAGS(6); /* RW_ */
3861+ note PT_NOTE FLAGS(0); /* ___ */
3862 }
3863 SECTIONS
3864 {
3865 . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
3866- phys_startup_32 = startup_32 - LOAD_OFFSET;
3867+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
3868+
3869+ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
3870+ BYTE(0xEA) /* jmp far */
3871+ LONG(phys_startup_32)
3872+ SHORT(__BOOT_CS)
3873+ } :initdata
3874
3875- .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
3876- _text = .; /* Text and read-only data */
3877+ /* might get freed after init */
3878+ . = ALIGN(4096);
3879+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
3880+ __smp_locks = .;
3881+ *(.smp_locks)
3882+ __smp_locks_end = .;
3883+ }
3884+ /* will be freed after init
3885+ * Following ALIGN() is required to make sure no other data falls on the
3886+ * same page where __smp_alt_end is pointing as that page might be freed
3887+ * after boot. Always make sure that ALIGN() directive is present after
3888+ * the section which contains __smp_alt_end.
3889+ */
3890+ . = ALIGN(4096);
3891+
3892+ /* will be freed after init */
3893+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
3894+ __init_begin = .;
3895+ *(.init.data)
3896+ }
3897+ . = ALIGN(16);
3898+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
3899+ __setup_start = .;
3900+ *(.init.setup)
3901+ __setup_end = .;
3902+ }
3903+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
3904+ __initcall_start = .;
3905+ INITCALLS
3906+ __initcall_end = .;
3907+ }
3908+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
3909+ __con_initcall_start = .;
3910+ *(.con_initcall.init)
3911+ __con_initcall_end = .;
3912+ }
3913+ SECURITY_INIT
3914+ . = ALIGN(4);
3915+ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
3916+ __alt_instructions = .;
3917+ *(.altinstructions)
3918+ __alt_instructions_end = .;
3919+ }
3920+ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
3921+ *(.altinstr_replacement)
3922+ }
3923+ . = ALIGN(4);
3924+ .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
3925+ __parainstructions = .;
3926+ *(.parainstructions)
3927+ __parainstructions_end = .;
3928+ }
3929+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3930+#if defined(CONFIG_BLK_DEV_INITRD)
3931+ . = ALIGN(4096);
3932+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
3933+ __initramfs_start = .;
3934+ *(.init.ramfs)
3935+ __initramfs_end = .;
3936+ }
3937+#endif
3938+ . = ALIGN(4096);
3939+ per_cpu_start = .;
3940+ .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
3941+ __per_cpu_start = . + per_cpu_start;
3942+ LONG(0)
3943+ *(.data.percpu)
3944+ __per_cpu_end = . + per_cpu_start;
3945+ } :percpu
3946+ . += per_cpu_start;
3947+
3948+ /* read-only */
3949+
3950+ . = ALIGN(4096); /* Init code and data */
3951+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3952+ _sinittext = .;
3953+ *(.init.text)
3954+ _einittext = .;
3955+ } :inittext
3956+
3957+ /* .exit.text is discard at runtime, not link time, to deal with references
3958+ from .altinstructions and .eh_frame */
3959+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
3960+
3961+ .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3962+ BYTE(0)
3963+ . = ALIGN(4*1024*1024) - 1;
3964+ }
3965+
3966+ /* freed after init ends here */
3967+
3968+ .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3969+ __init_end = . + __KERNEL_TEXT_OFFSET;
3970+ _text = .; /* Text and read-only data */
3971 *(.text.head)
3972 } :text = 0x9090
3973
3974 /* read-only */
3975- .text : AT(ADDR(.text) - LOAD_OFFSET) {
3976+ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3977 TEXT_TEXT
3978 SCHED_TEXT
3979 LOCK_TEXT
3980@@ -53,12 +162,13 @@ SECTIONS
3981 _etext = .; /* End of text section */
3982 } :text = 0x9090
3983
3984+ . += __KERNEL_TEXT_OFFSET;
3985 . = ALIGN(16); /* Exception table */
3986 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
3987 __start___ex_table = .;
3988 *(__ex_table)
3989 __stop___ex_table = .;
3990- }
3991+ } :rodata
3992
3993 BUG_TABLE
3994
3995@@ -71,9 +181,37 @@ SECTIONS
3996
3997 RODATA
3998
3999+ . = ALIGN(4096);
4000+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
4001+ *(.empty_zero_page)
4002+
4003+#ifdef CONFIG_X86_PAE
4004+ *(.swapper_pm_dir)
4005+#endif
4006+
4007+ *(.swapper_pg_dir)
4008+ *(.idt)
4009+ }
4010+
4011+#ifdef CONFIG_PAX_KERNEXEC
4012+ . = ALIGN(4096);
4013+
4014+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
4015+ MODULES_VADDR = .;
4016+ BYTE(0)
4017+ . += (4 * 1024 * 1024);
4018+ . = ALIGN(1 << PMD_SHIFT) - 1;
4019+ MODULES_END = .;
4020+ }
4021+
4022+#else
4023+ . = ALIGN(32);
4024+#endif
4025+
4026 /* writeable */
4027 . = ALIGN(4096);
4028 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
4029+ _data = .;
4030 DATA_DATA
4031 CONSTRUCTORS
4032 } :data
4033@@ -86,11 +224,6 @@ SECTIONS
4034 __nosave_end = .;
4035 }
4036
4037- . = ALIGN(4096);
4038- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
4039- *(.data.idt)
4040- }
4041-
4042 . = ALIGN(32);
4043 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
4044 *(.data.cacheline_aligned)
4045@@ -108,85 +241,9 @@ SECTIONS
4046 *(.data.init_task)
4047 }
4048
4049- /* might get freed after init */
4050- . = ALIGN(4096);
4051- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
4052- __smp_locks = .;
4053- *(.smp_locks)
4054- __smp_locks_end = .;
4055- }
4056- /* will be freed after init
4057- * Following ALIGN() is required to make sure no other data falls on the
4058- * same page where __smp_alt_end is pointing as that page might be freed
4059- * after boot. Always make sure that ALIGN() directive is present after
4060- * the section which contains __smp_alt_end.
4061- */
4062 . = ALIGN(4096);
4063
4064- /* will be freed after init */
4065- . = ALIGN(4096); /* Init code and data */
4066- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
4067- __init_begin = .;
4068- _sinittext = .;
4069- *(.init.text)
4070- _einittext = .;
4071- }
4072- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
4073- . = ALIGN(16);
4074- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
4075- __setup_start = .;
4076- *(.init.setup)
4077- __setup_end = .;
4078- }
4079- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
4080- __initcall_start = .;
4081- INITCALLS
4082- __initcall_end = .;
4083- }
4084- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
4085- __con_initcall_start = .;
4086- *(.con_initcall.init)
4087- __con_initcall_end = .;
4088- }
4089- SECURITY_INIT
4090- . = ALIGN(4);
4091- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
4092- __alt_instructions = .;
4093- *(.altinstructions)
4094- __alt_instructions_end = .;
4095- }
4096- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
4097- *(.altinstr_replacement)
4098- }
4099- . = ALIGN(4);
4100- .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
4101- __parainstructions = .;
4102- *(.parainstructions)
4103- __parainstructions_end = .;
4104- }
4105- /* .exit.text is discard at runtime, not link time, to deal with references
4106- from .altinstructions and .eh_frame */
4107- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
4108- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
4109-#if defined(CONFIG_BLK_DEV_INITRD)
4110- . = ALIGN(4096);
4111- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
4112- __initramfs_start = .;
4113- *(.init.ramfs)
4114- __initramfs_end = .;
4115- }
4116-#endif
4117- . = ALIGN(4096);
4118- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
4119- __per_cpu_start = .;
4120- *(.data.percpu)
4121- __per_cpu_end = .;
4122- }
4123- . = ALIGN(4096);
4124- /* freed after init ends here */
4125-
4126 .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
4127- __init_end = .;
4128 __bss_start = .; /* BSS */
4129 *(.bss.page_aligned)
4130 *(.bss)
4131diff -urNp linux-2.6.22.1/arch/i386/lib/checksum.S linux-2.6.22.1/arch/i386/lib/checksum.S
4132--- linux-2.6.22.1/arch/i386/lib/checksum.S 2007-07-10 14:56:30.000000000 -0400
4133+++ linux-2.6.22.1/arch/i386/lib/checksum.S 2007-08-02 11:38:45.000000000 -0400
4134@@ -28,7 +28,8 @@
4135 #include <linux/linkage.h>
4136 #include <asm/dwarf2.h>
4137 #include <asm/errno.h>
4138-
4139+#include <asm/segment.h>
4140+
4141 /*
4142 * computes a partial checksum, e.g. for TCP/UDP fragments
4143 */
4144@@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
4145
4146 #define ARGBASE 16
4147 #define FP 12
4148-
4149-ENTRY(csum_partial_copy_generic)
4150+
4151+ENTRY(csum_partial_copy_generic_to_user)
4152 CFI_STARTPROC
4153+ pushl $(__USER_DS)
4154+ CFI_ADJUST_CFA_OFFSET 4
4155+ popl %es
4156+ CFI_ADJUST_CFA_OFFSET -4
4157+ jmp csum_partial_copy_generic
4158+
4159+ENTRY(csum_partial_copy_generic_from_user)
4160+ pushl $(__USER_DS)
4161+ CFI_ADJUST_CFA_OFFSET 4
4162+ popl %ds
4163+ CFI_ADJUST_CFA_OFFSET -4
4164+
4165+ENTRY(csum_partial_copy_generic)
4166 subl $4,%esp
4167 CFI_ADJUST_CFA_OFFSET 4
4168 pushl %edi
4169@@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
4170 jmp 4f
4171 SRC(1: movw (%esi), %bx )
4172 addl $2, %esi
4173-DST( movw %bx, (%edi) )
4174+DST( movw %bx, %es:(%edi) )
4175 addl $2, %edi
4176 addw %bx, %ax
4177 adcl $0, %eax
4178@@ -343,30 +357,30 @@ DST( movw %bx, (%edi) )
4179 SRC(1: movl (%esi), %ebx )
4180 SRC( movl 4(%esi), %edx )
4181 adcl %ebx, %eax
4182-DST( movl %ebx, (%edi) )
4183+DST( movl %ebx, %es:(%edi) )
4184 adcl %edx, %eax
4185-DST( movl %edx, 4(%edi) )
4186+DST( movl %edx, %es:4(%edi) )
4187
4188 SRC( movl 8(%esi), %ebx )
4189 SRC( movl 12(%esi), %edx )
4190 adcl %ebx, %eax
4191-DST( movl %ebx, 8(%edi) )
4192+DST( movl %ebx, %es:8(%edi) )
4193 adcl %edx, %eax
4194-DST( movl %edx, 12(%edi) )
4195+DST( movl %edx, %es:12(%edi) )
4196
4197 SRC( movl 16(%esi), %ebx )
4198 SRC( movl 20(%esi), %edx )
4199 adcl %ebx, %eax
4200-DST( movl %ebx, 16(%edi) )
4201+DST( movl %ebx, %es:16(%edi) )
4202 adcl %edx, %eax
4203-DST( movl %edx, 20(%edi) )
4204+DST( movl %edx, %es:20(%edi) )
4205
4206 SRC( movl 24(%esi), %ebx )
4207 SRC( movl 28(%esi), %edx )
4208 adcl %ebx, %eax
4209-DST( movl %ebx, 24(%edi) )
4210+DST( movl %ebx, %es:24(%edi) )
4211 adcl %edx, %eax
4212-DST( movl %edx, 28(%edi) )
4213+DST( movl %edx, %es:28(%edi) )
4214
4215 lea 32(%esi), %esi
4216 lea 32(%edi), %edi
4217@@ -380,7 +394,7 @@ DST( movl %edx, 28(%edi) )
4218 shrl $2, %edx # This clears CF
4219 SRC(3: movl (%esi), %ebx )
4220 adcl %ebx, %eax
4221-DST( movl %ebx, (%edi) )
4222+DST( movl %ebx, %es:(%edi) )
4223 lea 4(%esi), %esi
4224 lea 4(%edi), %edi
4225 dec %edx
4226@@ -392,12 +406,12 @@ DST( movl %ebx, (%edi) )
4227 jb 5f
4228 SRC( movw (%esi), %cx )
4229 leal 2(%esi), %esi
4230-DST( movw %cx, (%edi) )
4231+DST( movw %cx, %es:(%edi) )
4232 leal 2(%edi), %edi
4233 je 6f
4234 shll $16,%ecx
4235 SRC(5: movb (%esi), %cl )
4236-DST( movb %cl, (%edi) )
4237+DST( movb %cl, %es:(%edi) )
4238 6: addl %ecx, %eax
4239 adcl $0, %eax
4240 7:
4241@@ -408,7 +422,7 @@ DST( movb %cl, (%edi) )
4242
4243 6001:
4244 movl ARGBASE+20(%esp), %ebx # src_err_ptr
4245- movl $-EFAULT, (%ebx)
4246+ movl $-EFAULT, %ss:(%ebx)
4247
4248 # zero the complete destination - computing the rest
4249 # is too much work
4250@@ -421,11 +435,19 @@ DST( movb %cl, (%edi) )
4251
4252 6002:
4253 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4254- movl $-EFAULT,(%ebx)
4255+ movl $-EFAULT,%ss:(%ebx)
4256 jmp 5000b
4257
4258 .previous
4259
4260+ pushl %ss
4261+ CFI_ADJUST_CFA_OFFSET 4
4262+ popl %ds
4263+ CFI_ADJUST_CFA_OFFSET -4
4264+ pushl %ss
4265+ CFI_ADJUST_CFA_OFFSET 4
4266+ popl %es
4267+ CFI_ADJUST_CFA_OFFSET -4
4268 popl %ebx
4269 CFI_ADJUST_CFA_OFFSET -4
4270 CFI_RESTORE ebx
4271@@ -439,26 +461,41 @@ DST( movb %cl, (%edi) )
4272 CFI_ADJUST_CFA_OFFSET -4
4273 ret
4274 CFI_ENDPROC
4275-ENDPROC(csum_partial_copy_generic)
4276+ENDPROC(csum_partial_copy_generic_to_user)
4277
4278 #else
4279
4280 /* Version for PentiumII/PPro */
4281
4282 #define ROUND1(x) \
4283+ nop; nop; nop; \
4284 SRC(movl x(%esi), %ebx ) ; \
4285 addl %ebx, %eax ; \
4286- DST(movl %ebx, x(%edi) ) ;
4287+ DST(movl %ebx, %es:x(%edi)) ;
4288
4289 #define ROUND(x) \
4290+ nop; nop; nop; \
4291 SRC(movl x(%esi), %ebx ) ; \
4292 adcl %ebx, %eax ; \
4293- DST(movl %ebx, x(%edi) ) ;
4294+ DST(movl %ebx, %es:x(%edi)) ;
4295
4296 #define ARGBASE 12
4297-
4298-ENTRY(csum_partial_copy_generic)
4299+
4300+ENTRY(csum_partial_copy_generic_to_user)
4301 CFI_STARTPROC
4302+ pushl $(__USER_DS)
4303+ CFI_ADJUST_CFA_OFFSET 4
4304+ popl %es
4305+ CFI_ADJUST_CFA_OFFSET -4
4306+ jmp csum_partial_copy_generic
4307+
4308+ENTRY(csum_partial_copy_generic_from_user)
4309+ pushl $(__USER_DS)
4310+ CFI_ADJUST_CFA_OFFSET 4
4311+ popl %ds
4312+ CFI_ADJUST_CFA_OFFSET -4
4313+
4314+ENTRY(csum_partial_copy_generic)
4315 pushl %ebx
4316 CFI_ADJUST_CFA_OFFSET 4
4317 CFI_REL_OFFSET ebx, 0
4318@@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
4319 subl %ebx, %edi
4320 lea -1(%esi),%edx
4321 andl $-32,%edx
4322- lea 3f(%ebx,%ebx), %ebx
4323+ lea 3f(%ebx,%ebx,2), %ebx
4324 testl %esi, %esi
4325 jmp *%ebx
4326 1: addl $64,%esi
4327@@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
4328 jb 5f
4329 SRC( movw (%esi), %dx )
4330 leal 2(%esi), %esi
4331-DST( movw %dx, (%edi) )
4332+DST( movw %dx, %es:(%edi) )
4333 leal 2(%edi), %edi
4334 je 6f
4335 shll $16,%edx
4336 5:
4337 SRC( movb (%esi), %dl )
4338-DST( movb %dl, (%edi) )
4339+DST( movb %dl, %es:(%edi) )
4340 6: addl %edx, %eax
4341 adcl $0, %eax
4342 7:
4343 .section .fixup, "ax"
4344 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
4345- movl $-EFAULT, (%ebx)
4346+ movl $-EFAULT, %ss:(%ebx)
4347 # zero the complete destination (computing the rest is too much work)
4348 movl ARGBASE+8(%esp),%edi # dst
4349 movl ARGBASE+12(%esp),%ecx # len
4350@@ -523,10 +560,18 @@ DST( movb %dl, (%edi) )
4351 rep; stosb
4352 jmp 7b
4353 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
4354- movl $-EFAULT, (%ebx)
4355+ movl $-EFAULT, %ss:(%ebx)
4356 jmp 7b
4357 .previous
4358
4359+ pushl %ss
4360+ CFI_ADJUST_CFA_OFFSET 4
4361+ popl %ds
4362+ CFI_ADJUST_CFA_OFFSET -4
4363+ pushl %ss
4364+ CFI_ADJUST_CFA_OFFSET 4
4365+ popl %es
4366+ CFI_ADJUST_CFA_OFFSET -4
4367 popl %esi
4368 CFI_ADJUST_CFA_OFFSET -4
4369 CFI_RESTORE esi
4370@@ -538,7 +583,7 @@ DST( movb %dl, (%edi) )
4371 CFI_RESTORE ebx
4372 ret
4373 CFI_ENDPROC
4374-ENDPROC(csum_partial_copy_generic)
4375+ENDPROC(csum_partial_copy_generic_to_user)
4376
4377 #undef ROUND
4378 #undef ROUND1
4379diff -urNp linux-2.6.22.1/arch/i386/lib/getuser.S linux-2.6.22.1/arch/i386/lib/getuser.S
4380--- linux-2.6.22.1/arch/i386/lib/getuser.S 2007-07-10 14:56:30.000000000 -0400
4381+++ linux-2.6.22.1/arch/i386/lib/getuser.S 2007-08-02 11:38:45.000000000 -0400
4382@@ -11,7 +11,7 @@
4383 #include <linux/linkage.h>
4384 #include <asm/dwarf2.h>
4385 #include <asm/thread_info.h>
4386-
4387+#include <asm/segment.h>
4388
4389 /*
4390 * __get_user_X
4391@@ -31,7 +31,11 @@ ENTRY(__get_user_1)
4392 GET_THREAD_INFO(%edx)
4393 cmpl TI_addr_limit(%edx),%eax
4394 jae bad_get_user
4395+ pushl $(__USER_DS)
4396+ popl %ds
4397 1: movzbl (%eax),%edx
4398+ pushl %ss
4399+ pop %ds
4400 xorl %eax,%eax
4401 ret
4402 CFI_ENDPROC
4403@@ -44,7 +48,11 @@ ENTRY(__get_user_2)
4404 GET_THREAD_INFO(%edx)
4405 cmpl TI_addr_limit(%edx),%eax
4406 jae bad_get_user
4407+ pushl $(__USER_DS)
4408+ popl %ds
4409 2: movzwl -1(%eax),%edx
4410+ pushl %ss
4411+ pop %ds
4412 xorl %eax,%eax
4413 ret
4414 CFI_ENDPROC
4415@@ -57,7 +65,11 @@ ENTRY(__get_user_4)
4416 GET_THREAD_INFO(%edx)
4417 cmpl TI_addr_limit(%edx),%eax
4418 jae bad_get_user
4419+ pushl $(__USER_DS)
4420+ popl %ds
4421 3: movl -3(%eax),%edx
4422+ pushl %ss
4423+ pop %ds
4424 xorl %eax,%eax
4425 ret
4426 CFI_ENDPROC
4427@@ -65,6 +77,8 @@ ENDPROC(__get_user_4)
4428
4429 bad_get_user:
4430 CFI_STARTPROC
4431+ pushl %ss
4432+ pop %ds
4433 xorl %edx,%edx
4434 movl $-14,%eax
4435 ret
4436diff -urNp linux-2.6.22.1/arch/i386/lib/mmx.c linux-2.6.22.1/arch/i386/lib/mmx.c
4437--- linux-2.6.22.1/arch/i386/lib/mmx.c 2007-07-10 14:56:30.000000000 -0400
4438+++ linux-2.6.22.1/arch/i386/lib/mmx.c 2007-08-02 11:38:45.000000000 -0400
4439@@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
4440 {
4441 void *p;
4442 int i;
4443+ unsigned long cr0;
4444
4445 if (unlikely(in_interrupt()))
4446 return __memcpy(to, from, len);
4447@@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
4448 kernel_fpu_begin();
4449
4450 __asm__ __volatile__ (
4451- "1: prefetch (%0)\n" /* This set is 28 bytes */
4452- " prefetch 64(%0)\n"
4453- " prefetch 128(%0)\n"
4454- " prefetch 192(%0)\n"
4455- " prefetch 256(%0)\n"
4456+ "1: prefetch (%1)\n" /* This set is 28 bytes */
4457+ " prefetch 64(%1)\n"
4458+ " prefetch 128(%1)\n"
4459+ " prefetch 192(%1)\n"
4460+ " prefetch 256(%1)\n"
4461 "2: \n"
4462 ".section .fixup, \"ax\"\n"
4463- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4464+ "3: \n"
4465+
4466+#ifdef CONFIG_PAX_KERNEXEC
4467+ " movl %%cr0, %0\n"
4468+ " movl %0, %%eax\n"
4469+ " andl $0xFFFEFFFF, %%eax\n"
4470+ " movl %%eax, %%cr0\n"
4471+#endif
4472+
4473+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4474+
4475+#ifdef CONFIG_PAX_KERNEXEC
4476+ " movl %0, %%cr0\n"
4477+#endif
4478+
4479 " jmp 2b\n"
4480 ".previous\n"
4481 ".section __ex_table,\"a\"\n"
4482 " .align 4\n"
4483 " .long 1b, 3b\n"
4484 ".previous"
4485- : : "r" (from) );
4486+ : "=&r" (cr0) : "r" (from) : "ax");
4487
4488
4489 for(; i>5; i--)
4490 {
4491 __asm__ __volatile__ (
4492- "1: prefetch 320(%0)\n"
4493- "2: movq (%0), %%mm0\n"
4494- " movq 8(%0), %%mm1\n"
4495- " movq 16(%0), %%mm2\n"
4496- " movq 24(%0), %%mm3\n"
4497- " movq %%mm0, (%1)\n"
4498- " movq %%mm1, 8(%1)\n"
4499- " movq %%mm2, 16(%1)\n"
4500- " movq %%mm3, 24(%1)\n"
4501- " movq 32(%0), %%mm0\n"
4502- " movq 40(%0), %%mm1\n"
4503- " movq 48(%0), %%mm2\n"
4504- " movq 56(%0), %%mm3\n"
4505- " movq %%mm0, 32(%1)\n"
4506- " movq %%mm1, 40(%1)\n"
4507- " movq %%mm2, 48(%1)\n"
4508- " movq %%mm3, 56(%1)\n"
4509+ "1: prefetch 320(%1)\n"
4510+ "2: movq (%1), %%mm0\n"
4511+ " movq 8(%1), %%mm1\n"
4512+ " movq 16(%1), %%mm2\n"
4513+ " movq 24(%1), %%mm3\n"
4514+ " movq %%mm0, (%2)\n"
4515+ " movq %%mm1, 8(%2)\n"
4516+ " movq %%mm2, 16(%2)\n"
4517+ " movq %%mm3, 24(%2)\n"
4518+ " movq 32(%1), %%mm0\n"
4519+ " movq 40(%1), %%mm1\n"
4520+ " movq 48(%1), %%mm2\n"
4521+ " movq 56(%1), %%mm3\n"
4522+ " movq %%mm0, 32(%2)\n"
4523+ " movq %%mm1, 40(%2)\n"
4524+ " movq %%mm2, 48(%2)\n"
4525+ " movq %%mm3, 56(%2)\n"
4526 ".section .fixup, \"ax\"\n"
4527- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4528+ "3:\n"
4529+
4530+#ifdef CONFIG_PAX_KERNEXEC
4531+ " movl %%cr0, %0\n"
4532+ " movl %0, %%eax\n"
4533+ " andl $0xFFFEFFFF, %%eax\n"
4534+ " movl %%eax, %%cr0\n"
4535+#endif
4536+
4537+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4538+
4539+#ifdef CONFIG_PAX_KERNEXEC
4540+ " movl %0, %%cr0\n"
4541+#endif
4542+
4543 " jmp 2b\n"
4544 ".previous\n"
4545 ".section __ex_table,\"a\"\n"
4546 " .align 4\n"
4547 " .long 1b, 3b\n"
4548 ".previous"
4549- : : "r" (from), "r" (to) : "memory");
4550+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4551 from+=64;
4552 to+=64;
4553 }
4554@@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
4555 static void fast_copy_page(void *to, void *from)
4556 {
4557 int i;
4558+ unsigned long cr0;
4559
4560 kernel_fpu_begin();
4561
4562@@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
4563 * but that is for later. -AV
4564 */
4565 __asm__ __volatile__ (
4566- "1: prefetch (%0)\n"
4567- " prefetch 64(%0)\n"
4568- " prefetch 128(%0)\n"
4569- " prefetch 192(%0)\n"
4570- " prefetch 256(%0)\n"
4571+ "1: prefetch (%1)\n"
4572+ " prefetch 64(%1)\n"
4573+ " prefetch 128(%1)\n"
4574+ " prefetch 192(%1)\n"
4575+ " prefetch 256(%1)\n"
4576 "2: \n"
4577 ".section .fixup, \"ax\"\n"
4578- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4579+ "3: \n"
4580+
4581+#ifdef CONFIG_PAX_KERNEXEC
4582+ " movl %%cr0, %0\n"
4583+ " movl %0, %%eax\n"
4584+ " andl $0xFFFEFFFF, %%eax\n"
4585+ " movl %%eax, %%cr0\n"
4586+#endif
4587+
4588+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4589+
4590+#ifdef CONFIG_PAX_KERNEXEC
4591+ " movl %0, %%cr0\n"
4592+#endif
4593+
4594 " jmp 2b\n"
4595 ".previous\n"
4596 ".section __ex_table,\"a\"\n"
4597 " .align 4\n"
4598 " .long 1b, 3b\n"
4599 ".previous"
4600- : : "r" (from) );
4601+ : "=&r" (cr0) : "r" (from) : "ax");
4602
4603 for(i=0; i<(4096-320)/64; i++)
4604 {
4605 __asm__ __volatile__ (
4606- "1: prefetch 320(%0)\n"
4607- "2: movq (%0), %%mm0\n"
4608- " movntq %%mm0, (%1)\n"
4609- " movq 8(%0), %%mm1\n"
4610- " movntq %%mm1, 8(%1)\n"
4611- " movq 16(%0), %%mm2\n"
4612- " movntq %%mm2, 16(%1)\n"
4613- " movq 24(%0), %%mm3\n"
4614- " movntq %%mm3, 24(%1)\n"
4615- " movq 32(%0), %%mm4\n"
4616- " movntq %%mm4, 32(%1)\n"
4617- " movq 40(%0), %%mm5\n"
4618- " movntq %%mm5, 40(%1)\n"
4619- " movq 48(%0), %%mm6\n"
4620- " movntq %%mm6, 48(%1)\n"
4621- " movq 56(%0), %%mm7\n"
4622- " movntq %%mm7, 56(%1)\n"
4623+ "1: prefetch 320(%1)\n"
4624+ "2: movq (%1), %%mm0\n"
4625+ " movntq %%mm0, (%2)\n"
4626+ " movq 8(%1), %%mm1\n"
4627+ " movntq %%mm1, 8(%2)\n"
4628+ " movq 16(%1), %%mm2\n"
4629+ " movntq %%mm2, 16(%2)\n"
4630+ " movq 24(%1), %%mm3\n"
4631+ " movntq %%mm3, 24(%2)\n"
4632+ " movq 32(%1), %%mm4\n"
4633+ " movntq %%mm4, 32(%2)\n"
4634+ " movq 40(%1), %%mm5\n"
4635+ " movntq %%mm5, 40(%2)\n"
4636+ " movq 48(%1), %%mm6\n"
4637+ " movntq %%mm6, 48(%2)\n"
4638+ " movq 56(%1), %%mm7\n"
4639+ " movntq %%mm7, 56(%2)\n"
4640 ".section .fixup, \"ax\"\n"
4641- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4642+ "3:\n"
4643+
4644+#ifdef CONFIG_PAX_KERNEXEC
4645+ " movl %%cr0, %0\n"
4646+ " movl %0, %%eax\n"
4647+ " andl $0xFFFEFFFF, %%eax\n"
4648+ " movl %%eax, %%cr0\n"
4649+#endif
4650+
4651+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4652+
4653+#ifdef CONFIG_PAX_KERNEXEC
4654+ " movl %0, %%cr0\n"
4655+#endif
4656+
4657 " jmp 2b\n"
4658 ".previous\n"
4659 ".section __ex_table,\"a\"\n"
4660 " .align 4\n"
4661 " .long 1b, 3b\n"
4662 ".previous"
4663- : : "r" (from), "r" (to) : "memory");
4664+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4665 from+=64;
4666 to+=64;
4667 }
4668@@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
4669 static void fast_copy_page(void *to, void *from)
4670 {
4671 int i;
4672-
4673-
4674+ unsigned long cr0;
4675+
4676 kernel_fpu_begin();
4677
4678 __asm__ __volatile__ (
4679- "1: prefetch (%0)\n"
4680- " prefetch 64(%0)\n"
4681- " prefetch 128(%0)\n"
4682- " prefetch 192(%0)\n"
4683- " prefetch 256(%0)\n"
4684+ "1: prefetch (%1)\n"
4685+ " prefetch 64(%1)\n"
4686+ " prefetch 128(%1)\n"
4687+ " prefetch 192(%1)\n"
4688+ " prefetch 256(%1)\n"
4689 "2: \n"
4690 ".section .fixup, \"ax\"\n"
4691- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4692+ "3: \n"
4693+
4694+#ifdef CONFIG_PAX_KERNEXEC
4695+ " movl %%cr0, %0\n"
4696+ " movl %0, %%eax\n"
4697+ " andl $0xFFFEFFFF, %%eax\n"
4698+ " movl %%eax, %%cr0\n"
4699+#endif
4700+
4701+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4702+
4703+#ifdef CONFIG_PAX_KERNEXEC
4704+ " movl %0, %%cr0\n"
4705+#endif
4706+
4707 " jmp 2b\n"
4708 ".previous\n"
4709 ".section __ex_table,\"a\"\n"
4710 " .align 4\n"
4711 " .long 1b, 3b\n"
4712 ".previous"
4713- : : "r" (from) );
4714+ : "=&r" (cr0) : "r" (from) : "ax");
4715
4716 for(i=0; i<4096/64; i++)
4717 {
4718 __asm__ __volatile__ (
4719- "1: prefetch 320(%0)\n"
4720- "2: movq (%0), %%mm0\n"
4721- " movq 8(%0), %%mm1\n"
4722- " movq 16(%0), %%mm2\n"
4723- " movq 24(%0), %%mm3\n"
4724- " movq %%mm0, (%1)\n"
4725- " movq %%mm1, 8(%1)\n"
4726- " movq %%mm2, 16(%1)\n"
4727- " movq %%mm3, 24(%1)\n"
4728- " movq 32(%0), %%mm0\n"
4729- " movq 40(%0), %%mm1\n"
4730- " movq 48(%0), %%mm2\n"
4731- " movq 56(%0), %%mm3\n"
4732- " movq %%mm0, 32(%1)\n"
4733- " movq %%mm1, 40(%1)\n"
4734- " movq %%mm2, 48(%1)\n"
4735- " movq %%mm3, 56(%1)\n"
4736+ "1: prefetch 320(%1)\n"
4737+ "2: movq (%1), %%mm0\n"
4738+ " movq 8(%1), %%mm1\n"
4739+ " movq 16(%1), %%mm2\n"
4740+ " movq 24(%1), %%mm3\n"
4741+ " movq %%mm0, (%2)\n"
4742+ " movq %%mm1, 8(%2)\n"
4743+ " movq %%mm2, 16(%2)\n"
4744+ " movq %%mm3, 24(%2)\n"
4745+ " movq 32(%1), %%mm0\n"
4746+ " movq 40(%1), %%mm1\n"
4747+ " movq 48(%1), %%mm2\n"
4748+ " movq 56(%1), %%mm3\n"
4749+ " movq %%mm0, 32(%2)\n"
4750+ " movq %%mm1, 40(%2)\n"
4751+ " movq %%mm2, 48(%2)\n"
4752+ " movq %%mm3, 56(%2)\n"
4753 ".section .fixup, \"ax\"\n"
4754- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4755+ "3:\n"
4756+
4757+#ifdef CONFIG_PAX_KERNEXEC
4758+ " movl %%cr0, %0\n"
4759+ " movl %0, %%eax\n"
4760+ " andl $0xFFFEFFFF, %%eax\n"
4761+ " movl %%eax, %%cr0\n"
4762+#endif
4763+
4764+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4765+
4766+#ifdef CONFIG_PAX_KERNEXEC
4767+ " movl %0, %%cr0\n"
4768+#endif
4769+
4770 " jmp 2b\n"
4771 ".previous\n"
4772 ".section __ex_table,\"a\"\n"
4773 " .align 4\n"
4774 " .long 1b, 3b\n"
4775 ".previous"
4776- : : "r" (from), "r" (to) : "memory");
4777+ : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4778 from+=64;
4779 to+=64;
4780 }
4781diff -urNp linux-2.6.22.1/arch/i386/lib/putuser.S linux-2.6.22.1/arch/i386/lib/putuser.S
4782--- linux-2.6.22.1/arch/i386/lib/putuser.S 2007-07-10 14:56:30.000000000 -0400
4783+++ linux-2.6.22.1/arch/i386/lib/putuser.S 2007-08-02 11:38:45.000000000 -0400
4784@@ -11,7 +11,7 @@
4785 #include <linux/linkage.h>
4786 #include <asm/dwarf2.h>
4787 #include <asm/thread_info.h>
4788-
4789+#include <asm/segment.h>
4790
4791 /*
4792 * __put_user_X
4793@@ -41,7 +41,11 @@ ENTRY(__put_user_1)
4794 ENTER
4795 cmpl TI_addr_limit(%ebx),%ecx
4796 jae bad_put_user
4797+ pushl $(__USER_DS)
4798+ popl %ds
4799 1: movb %al,(%ecx)
4800+ pushl %ss
4801+ popl %ds
4802 xorl %eax,%eax
4803 EXIT
4804 ENDPROC(__put_user_1)
4805@@ -52,7 +56,11 @@ ENTRY(__put_user_2)
4806 subl $1,%ebx
4807 cmpl %ebx,%ecx
4808 jae bad_put_user
4809+ pushl $(__USER_DS)
4810+ popl %ds
4811 2: movw %ax,(%ecx)
4812+ pushl %ss
4813+ popl %ds
4814 xorl %eax,%eax
4815 EXIT
4816 ENDPROC(__put_user_2)
4817@@ -63,7 +71,11 @@ ENTRY(__put_user_4)
4818 subl $3,%ebx
4819 cmpl %ebx,%ecx
4820 jae bad_put_user
4821+ pushl $(__USER_DS)
4822+ popl %ds
4823 3: movl %eax,(%ecx)
4824+ pushl %ss
4825+ popl %ds
4826 xorl %eax,%eax
4827 EXIT
4828 ENDPROC(__put_user_4)
4829@@ -74,8 +86,12 @@ ENTRY(__put_user_8)
4830 subl $7,%ebx
4831 cmpl %ebx,%ecx
4832 jae bad_put_user
4833+ pushl $(__USER_DS)
4834+ popl %ds
4835 4: movl %eax,(%ecx)
4836 5: movl %edx,4(%ecx)
4837+ pushl %ss
4838+ popl %ds
4839 xorl %eax,%eax
4840 EXIT
4841 ENDPROC(__put_user_8)
4842@@ -85,6 +101,10 @@ bad_put_user:
4843 CFI_DEF_CFA esp, 2*4
4844 CFI_OFFSET eip, -1*4
4845 CFI_OFFSET ebx, -2*4
4846+ pushl %ss
4847+ CFI_ADJUST_CFA_OFFSET 4
4848+ popl %ds
4849+ CFI_ADJUST_CFA_OFFSET -4
4850 movl $-14,%eax
4851 EXIT
4852 END(bad_put_user)
4853diff -urNp linux-2.6.22.1/arch/i386/lib/usercopy.c linux-2.6.22.1/arch/i386/lib/usercopy.c
4854--- linux-2.6.22.1/arch/i386/lib/usercopy.c 2007-07-10 14:56:30.000000000 -0400
4855+++ linux-2.6.22.1/arch/i386/lib/usercopy.c 2007-08-02 11:38:45.000000000 -0400
4856@@ -29,34 +29,41 @@ static inline int __movsl_is_ok(unsigned
4857 * Copy a null terminated string from userspace.
4858 */
4859
4860-#define __do_strncpy_from_user(dst,src,count,res) \
4861-do { \
4862- int __d0, __d1, __d2; \
4863- might_sleep(); \
4864- __asm__ __volatile__( \
4865- " testl %1,%1\n" \
4866- " jz 2f\n" \
4867- "0: lodsb\n" \
4868- " stosb\n" \
4869- " testb %%al,%%al\n" \
4870- " jz 1f\n" \
4871- " decl %1\n" \
4872- " jnz 0b\n" \
4873- "1: subl %1,%0\n" \
4874- "2:\n" \
4875- ".section .fixup,\"ax\"\n" \
4876- "3: movl %5,%0\n" \
4877- " jmp 2b\n" \
4878- ".previous\n" \
4879- ".section __ex_table,\"a\"\n" \
4880- " .align 4\n" \
4881- " .long 0b,3b\n" \
4882- ".previous" \
4883- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
4884- "=&D" (__d2) \
4885- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
4886- : "memory"); \
4887-} while (0)
4888+static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
4889+{
4890+ int __d0, __d1, __d2;
4891+ long res = -EFAULT;
4892+
4893+ might_sleep();
4894+ __asm__ __volatile__(
4895+ " movw %w10,%%ds\n"
4896+ " testl %1,%1\n"
4897+ " jz 2f\n"
4898+ "0: lodsb\n"
4899+ " stosb\n"
4900+ " testb %%al,%%al\n"
4901+ " jz 1f\n"
4902+ " decl %1\n"
4903+ " jnz 0b\n"
4904+ "1: subl %1,%0\n"
4905+ "2:\n"
4906+ " pushl %%ss\n"
4907+ " popl %%ds\n"
4908+ ".section .fixup,\"ax\"\n"
4909+ "3: movl %5,%0\n"
4910+ " jmp 2b\n"
4911+ ".previous\n"
4912+ ".section __ex_table,\"a\"\n"
4913+ " .align 4\n"
4914+ " .long 0b,3b\n"
4915+ ".previous"
4916+ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
4917+ "=&D" (__d2)
4918+ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
4919+ "r"(__USER_DS)
4920+ : "memory");
4921+ return res;
4922+}
4923
4924 /**
4925 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
4926@@ -81,9 +88,7 @@ do { \
4927 long
4928 __strncpy_from_user(char *dst, const char __user *src, long count)
4929 {
4930- long res;
4931- __do_strncpy_from_user(dst, src, count, res);
4932- return res;
4933+ return __do_strncpy_from_user(dst, src, count);
4934 }
4935 EXPORT_SYMBOL(__strncpy_from_user);
4936
4937@@ -110,7 +115,7 @@ strncpy_from_user(char *dst, const char
4938 {
4939 long res = -EFAULT;
4940 if (access_ok(VERIFY_READ, src, 1))
4941- __do_strncpy_from_user(dst, src, count, res);
4942+ res = __do_strncpy_from_user(dst, src, count);
4943 return res;
4944 }
4945 EXPORT_SYMBOL(strncpy_from_user);
4946@@ -119,27 +124,33 @@ EXPORT_SYMBOL(strncpy_from_user);
4947 * Zero Userspace
4948 */
4949
4950-#define __do_clear_user(addr,size) \
4951-do { \
4952- int __d0; \
4953- might_sleep(); \
4954- __asm__ __volatile__( \
4955- "0: rep; stosl\n" \
4956- " movl %2,%0\n" \
4957- "1: rep; stosb\n" \
4958- "2:\n" \
4959- ".section .fixup,\"ax\"\n" \
4960- "3: lea 0(%2,%0,4),%0\n" \
4961- " jmp 2b\n" \
4962- ".previous\n" \
4963- ".section __ex_table,\"a\"\n" \
4964- " .align 4\n" \
4965- " .long 0b,3b\n" \
4966- " .long 1b,2b\n" \
4967- ".previous" \
4968- : "=&c"(size), "=&D" (__d0) \
4969- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
4970-} while (0)
4971+static unsigned long __do_clear_user(void __user *addr, unsigned long size)
4972+{
4973+ int __d0;
4974+
4975+ might_sleep();
4976+ __asm__ __volatile__(
4977+ " movw %w6,%%es\n"
4978+ "0: rep; stosl\n"
4979+ " movl %2,%0\n"
4980+ "1: rep; stosb\n"
4981+ "2:\n"
4982+ " pushl %%ss\n"
4983+ " popl %%es\n"
4984+ ".section .fixup,\"ax\"\n"
4985+ "3: lea 0(%2,%0,4),%0\n"
4986+ " jmp 2b\n"
4987+ ".previous\n"
4988+ ".section __ex_table,\"a\"\n"
4989+ " .align 4\n"
4990+ " .long 0b,3b\n"
4991+ " .long 1b,2b\n"
4992+ ".previous"
4993+ : "=&c"(size), "=&D" (__d0)
4994+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
4995+ "r"(__USER_DS));
4996+ return size;
4997+}
4998
4999 /**
5000 * clear_user: - Zero a block of memory in user space.
5001@@ -156,7 +167,7 @@ clear_user(void __user *to, unsigned lon
5002 {
5003 might_sleep();
5004 if (access_ok(VERIFY_WRITE, to, n))
5005- __do_clear_user(to, n);
5006+ n = __do_clear_user(to, n);
5007 return n;
5008 }
5009 EXPORT_SYMBOL(clear_user);
5010@@ -175,8 +186,7 @@ EXPORT_SYMBOL(clear_user);
5011 unsigned long
5012 __clear_user(void __user *to, unsigned long n)
5013 {
5014- __do_clear_user(to, n);
5015- return n;
5016+ return __do_clear_user(to, n);
5017 }
5018 EXPORT_SYMBOL(__clear_user);
5019
5020@@ -199,14 +209,17 @@ long strnlen_user(const char __user *s,
5021 might_sleep();
5022
5023 __asm__ __volatile__(
5024+ " movw %w8,%%es\n"
5025 " testl %0, %0\n"
5026 " jz 3f\n"
5027- " andl %0,%%ecx\n"
5028+ " movl %0,%%ecx\n"
5029 "0: repne; scasb\n"
5030 " setne %%al\n"
5031 " subl %%ecx,%0\n"
5032 " addl %0,%%eax\n"
5033 "1:\n"
5034+ " pushl %%ss\n"
5035+ " popl %%es\n"
5036 ".section .fixup,\"ax\"\n"
5037 "2: xorl %%eax,%%eax\n"
5038 " jmp 1b\n"
5039@@ -218,7 +231,7 @@ long strnlen_user(const char __user *s,
5040 " .long 0b,2b\n"
5041 ".previous"
5042 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
5043- :"0" (n), "1" (s), "2" (0), "3" (mask)
5044+ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
5045 :"cc");
5046 return res & mask;
5047 }
5048@@ -226,10 +239,121 @@ EXPORT_SYMBOL(strnlen_user);
5049
5050 #ifdef CONFIG_X86_INTEL_USERCOPY
5051 static unsigned long
5052-__copy_user_intel(void __user *to, const void *from, unsigned long size)
5053+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
5054+{
5055+ int d0, d1;
5056+ __asm__ __volatile__(
5057+ " movw %w6, %%es\n"
5058+ " .align 2,0x90\n"
5059+ "1: movl 32(%4), %%eax\n"
5060+ " cmpl $67, %0\n"
5061+ " jbe 3f\n"
5062+ "2: movl 64(%4), %%eax\n"
5063+ " .align 2,0x90\n"
5064+ "3: movl 0(%4), %%eax\n"
5065+ "4: movl 4(%4), %%edx\n"
5066+ "5: movl %%eax, %%es:0(%3)\n"
5067+ "6: movl %%edx, %%es:4(%3)\n"
5068+ "7: movl 8(%4), %%eax\n"
5069+ "8: movl 12(%4),%%edx\n"
5070+ "9: movl %%eax, %%es:8(%3)\n"
5071+ "10: movl %%edx, %%es:12(%3)\n"
5072+ "11: movl 16(%4), %%eax\n"
5073+ "12: movl 20(%4), %%edx\n"
5074+ "13: movl %%eax, %%es:16(%3)\n"
5075+ "14: movl %%edx, %%es:20(%3)\n"
5076+ "15: movl 24(%4), %%eax\n"
5077+ "16: movl 28(%4), %%edx\n"
5078+ "17: movl %%eax, %%es:24(%3)\n"
5079+ "18: movl %%edx, %%es:28(%3)\n"
5080+ "19: movl 32(%4), %%eax\n"
5081+ "20: movl 36(%4), %%edx\n"
5082+ "21: movl %%eax, %%es:32(%3)\n"
5083+ "22: movl %%edx, %%es:36(%3)\n"
5084+ "23: movl 40(%4), %%eax\n"
5085+ "24: movl 44(%4), %%edx\n"
5086+ "25: movl %%eax, %%es:40(%3)\n"
5087+ "26: movl %%edx, %%es:44(%3)\n"
5088+ "27: movl 48(%4), %%eax\n"
5089+ "28: movl 52(%4), %%edx\n"
5090+ "29: movl %%eax, %%es:48(%3)\n"
5091+ "30: movl %%edx, %%es:52(%3)\n"
5092+ "31: movl 56(%4), %%eax\n"
5093+ "32: movl 60(%4), %%edx\n"
5094+ "33: movl %%eax, %%es:56(%3)\n"
5095+ "34: movl %%edx, %%es:60(%3)\n"
5096+ " addl $-64, %0\n"
5097+ " addl $64, %4\n"
5098+ " addl $64, %3\n"
5099+ " cmpl $63, %0\n"
5100+ " ja 1b\n"
5101+ "35: movl %0, %%eax\n"
5102+ " shrl $2, %0\n"
5103+ " andl $3, %%eax\n"
5104+ " cld\n"
5105+ "99: rep; movsl\n"
5106+ "36: movl %%eax, %0\n"
5107+ "37: rep; movsb\n"
5108+ "100:\n"
5109+ " pushl %%ss\n"
5110+ " popl %%es\n"
5111+ ".section .fixup,\"ax\"\n"
5112+ "101: lea 0(%%eax,%0,4),%0\n"
5113+ " jmp 100b\n"
5114+ ".previous\n"
5115+ ".section __ex_table,\"a\"\n"
5116+ " .align 4\n"
5117+ " .long 1b,100b\n"
5118+ " .long 2b,100b\n"
5119+ " .long 3b,100b\n"
5120+ " .long 4b,100b\n"
5121+ " .long 5b,100b\n"
5122+ " .long 6b,100b\n"
5123+ " .long 7b,100b\n"
5124+ " .long 8b,100b\n"
5125+ " .long 9b,100b\n"
5126+ " .long 10b,100b\n"
5127+ " .long 11b,100b\n"
5128+ " .long 12b,100b\n"
5129+ " .long 13b,100b\n"
5130+ " .long 14b,100b\n"
5131+ " .long 15b,100b\n"
5132+ " .long 16b,100b\n"
5133+ " .long 17b,100b\n"
5134+ " .long 18b,100b\n"
5135+ " .long 19b,100b\n"
5136+ " .long 20b,100b\n"
5137+ " .long 21b,100b\n"
5138+ " .long 22b,100b\n"
5139+ " .long 23b,100b\n"
5140+ " .long 24b,100b\n"
5141+ " .long 25b,100b\n"
5142+ " .long 26b,100b\n"
5143+ " .long 27b,100b\n"
5144+ " .long 28b,100b\n"
5145+ " .long 29b,100b\n"
5146+ " .long 30b,100b\n"
5147+ " .long 31b,100b\n"
5148+ " .long 32b,100b\n"
5149+ " .long 33b,100b\n"
5150+ " .long 34b,100b\n"
5151+ " .long 35b,100b\n"
5152+ " .long 36b,100b\n"
5153+ " .long 37b,100b\n"
5154+ " .long 99b,101b\n"
5155+ ".previous"
5156+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
5157+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5158+ : "eax", "edx", "memory");
5159+ return size;
5160+}
5161+
5162+static unsigned long
5163+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
5164 {
5165 int d0, d1;
5166 __asm__ __volatile__(
5167+ " movw %w6, %%ds\n"
5168 " .align 2,0x90\n"
5169 "1: movl 32(%4), %%eax\n"
5170 " cmpl $67, %0\n"
5171@@ -238,36 +362,36 @@ __copy_user_intel(void __user *to, const
5172 " .align 2,0x90\n"
5173 "3: movl 0(%4), %%eax\n"
5174 "4: movl 4(%4), %%edx\n"
5175- "5: movl %%eax, 0(%3)\n"
5176- "6: movl %%edx, 4(%3)\n"
5177+ "5: movl %%eax, %%es:0(%3)\n"
5178+ "6: movl %%edx, %%es:4(%3)\n"
5179 "7: movl 8(%4), %%eax\n"
5180 "8: movl 12(%4),%%edx\n"
5181- "9: movl %%eax, 8(%3)\n"
5182- "10: movl %%edx, 12(%3)\n"
5183+ "9: movl %%eax, %%es:8(%3)\n"
5184+ "10: movl %%edx, %%es:12(%3)\n"
5185 "11: movl 16(%4), %%eax\n"
5186 "12: movl 20(%4), %%edx\n"
5187- "13: movl %%eax, 16(%3)\n"
5188- "14: movl %%edx, 20(%3)\n"
5189+ "13: movl %%eax, %%es:16(%3)\n"
5190+ "14: movl %%edx, %%es:20(%3)\n"
5191 "15: movl 24(%4), %%eax\n"
5192 "16: movl 28(%4), %%edx\n"
5193- "17: movl %%eax, 24(%3)\n"
5194- "18: movl %%edx, 28(%3)\n"
5195+ "17: movl %%eax, %%es:24(%3)\n"
5196+ "18: movl %%edx, %%es:28(%3)\n"
5197 "19: movl 32(%4), %%eax\n"
5198 "20: movl 36(%4), %%edx\n"
5199- "21: movl %%eax, 32(%3)\n"
5200- "22: movl %%edx, 36(%3)\n"
5201+ "21: movl %%eax, %%es:32(%3)\n"
5202+ "22: movl %%edx, %%es:36(%3)\n"
5203 "23: movl 40(%4), %%eax\n"
5204 "24: movl 44(%4), %%edx\n"
5205- "25: movl %%eax, 40(%3)\n"
5206- "26: movl %%edx, 44(%3)\n"
5207+ "25: movl %%eax, %%es:40(%3)\n"
5208+ "26: movl %%edx, %%es:44(%3)\n"
5209 "27: movl 48(%4), %%eax\n"
5210 "28: movl 52(%4), %%edx\n"
5211- "29: movl %%eax, 48(%3)\n"
5212- "30: movl %%edx, 52(%3)\n"
5213+ "29: movl %%eax, %%es:48(%3)\n"
5214+ "30: movl %%edx, %%es:52(%3)\n"
5215 "31: movl 56(%4), %%eax\n"
5216 "32: movl 60(%4), %%edx\n"
5217- "33: movl %%eax, 56(%3)\n"
5218- "34: movl %%edx, 60(%3)\n"
5219+ "33: movl %%eax, %%es:56(%3)\n"
5220+ "34: movl %%edx, %%es:60(%3)\n"
5221 " addl $-64, %0\n"
5222 " addl $64, %4\n"
5223 " addl $64, %3\n"
5224@@ -281,6 +405,8 @@ __copy_user_intel(void __user *to, const
5225 "36: movl %%eax, %0\n"
5226 "37: rep; movsb\n"
5227 "100:\n"
5228+ " pushl %%ss\n"
5229+ " popl %%ds\n"
5230 ".section .fixup,\"ax\"\n"
5231 "101: lea 0(%%eax,%0,4),%0\n"
5232 " jmp 100b\n"
5233@@ -327,7 +453,7 @@ __copy_user_intel(void __user *to, const
5234 " .long 99b,101b\n"
5235 ".previous"
5236 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5237- : "1"(to), "2"(from), "0"(size)
5238+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5239 : "eax", "edx", "memory");
5240 return size;
5241 }
5242@@ -337,6 +463,7 @@ __copy_user_zeroing_intel(void *to, cons
5243 {
5244 int d0, d1;
5245 __asm__ __volatile__(
5246+ " movw %w6, %%ds\n"
5247 " .align 2,0x90\n"
5248 "0: movl 32(%4), %%eax\n"
5249 " cmpl $67, %0\n"
5250@@ -345,36 +472,36 @@ __copy_user_zeroing_intel(void *to, cons
5251 " .align 2,0x90\n"
5252 "2: movl 0(%4), %%eax\n"
5253 "21: movl 4(%4), %%edx\n"
5254- " movl %%eax, 0(%3)\n"
5255- " movl %%edx, 4(%3)\n"
5256+ " movl %%eax, %%es:0(%3)\n"
5257+ " movl %%edx, %%es:4(%3)\n"
5258 "3: movl 8(%4), %%eax\n"
5259 "31: movl 12(%4),%%edx\n"
5260- " movl %%eax, 8(%3)\n"
5261- " movl %%edx, 12(%3)\n"
5262+ " movl %%eax, %%es:8(%3)\n"
5263+ " movl %%edx, %%es:12(%3)\n"
5264 "4: movl 16(%4), %%eax\n"
5265 "41: movl 20(%4), %%edx\n"
5266- " movl %%eax, 16(%3)\n"
5267- " movl %%edx, 20(%3)\n"
5268+ " movl %%eax, %%es:16(%3)\n"
5269+ " movl %%edx, %%es:20(%3)\n"
5270 "10: movl 24(%4), %%eax\n"
5271 "51: movl 28(%4), %%edx\n"
5272- " movl %%eax, 24(%3)\n"
5273- " movl %%edx, 28(%3)\n"
5274+ " movl %%eax, %%es:24(%3)\n"
5275+ " movl %%edx, %%es:28(%3)\n"
5276 "11: movl 32(%4), %%eax\n"
5277 "61: movl 36(%4), %%edx\n"
5278- " movl %%eax, 32(%3)\n"
5279- " movl %%edx, 36(%3)\n"
5280+ " movl %%eax, %%es:32(%3)\n"
5281+ " movl %%edx, %%es:36(%3)\n"
5282 "12: movl 40(%4), %%eax\n"
5283 "71: movl 44(%4), %%edx\n"
5284- " movl %%eax, 40(%3)\n"
5285- " movl %%edx, 44(%3)\n"
5286+ " movl %%eax, %%es:40(%3)\n"
5287+ " movl %%edx, %%es:44(%3)\n"
5288 "13: movl 48(%4), %%eax\n"
5289 "81: movl 52(%4), %%edx\n"
5290- " movl %%eax, 48(%3)\n"
5291- " movl %%edx, 52(%3)\n"
5292+ " movl %%eax, %%es:48(%3)\n"
5293+ " movl %%edx, %%es:52(%3)\n"
5294 "14: movl 56(%4), %%eax\n"
5295 "91: movl 60(%4), %%edx\n"
5296- " movl %%eax, 56(%3)\n"
5297- " movl %%edx, 60(%3)\n"
5298+ " movl %%eax, %%es:56(%3)\n"
5299+ " movl %%edx, %%es:60(%3)\n"
5300 " addl $-64, %0\n"
5301 " addl $64, %4\n"
5302 " addl $64, %3\n"
5303@@ -388,6 +515,8 @@ __copy_user_zeroing_intel(void *to, cons
5304 " movl %%eax,%0\n"
5305 "7: rep; movsb\n"
5306 "8:\n"
5307+ " pushl %%ss\n"
5308+ " popl %%ds\n"
5309 ".section .fixup,\"ax\"\n"
5310 "9: lea 0(%%eax,%0,4),%0\n"
5311 "16: pushl %0\n"
5312@@ -422,7 +551,7 @@ __copy_user_zeroing_intel(void *to, cons
5313 " .long 7b,16b\n"
5314 ".previous"
5315 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5316- : "1"(to), "2"(from), "0"(size)
5317+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5318 : "eax", "edx", "memory");
5319 return size;
5320 }
5321@@ -438,6 +567,7 @@ static unsigned long __copy_user_zeroing
5322 int d0, d1;
5323
5324 __asm__ __volatile__(
5325+ " movw %w6, %%ds\n"
5326 " .align 2,0x90\n"
5327 "0: movl 32(%4), %%eax\n"
5328 " cmpl $67, %0\n"
5329@@ -446,36 +576,36 @@ static unsigned long __copy_user_zeroing
5330 " .align 2,0x90\n"
5331 "2: movl 0(%4), %%eax\n"
5332 "21: movl 4(%4), %%edx\n"
5333- " movnti %%eax, 0(%3)\n"
5334- " movnti %%edx, 4(%3)\n"
5335+ " movnti %%eax, %%es:0(%3)\n"
5336+ " movnti %%edx, %%es:4(%3)\n"
5337 "3: movl 8(%4), %%eax\n"
5338 "31: movl 12(%4),%%edx\n"
5339- " movnti %%eax, 8(%3)\n"
5340- " movnti %%edx, 12(%3)\n"
5341+ " movnti %%eax, %%es:8(%3)\n"
5342+ " movnti %%edx, %%es:12(%3)\n"
5343 "4: movl 16(%4), %%eax\n"
5344 "41: movl 20(%4), %%edx\n"
5345- " movnti %%eax, 16(%3)\n"
5346- " movnti %%edx, 20(%3)\n"
5347+ " movnti %%eax, %%es:16(%3)\n"
5348+ " movnti %%edx, %%es:20(%3)\n"
5349 "10: movl 24(%4), %%eax\n"
5350 "51: movl 28(%4), %%edx\n"
5351- " movnti %%eax, 24(%3)\n"
5352- " movnti %%edx, 28(%3)\n"
5353+ " movnti %%eax, %%es:24(%3)\n"
5354+ " movnti %%edx, %%es:28(%3)\n"
5355 "11: movl 32(%4), %%eax\n"
5356 "61: movl 36(%4), %%edx\n"
5357- " movnti %%eax, 32(%3)\n"
5358- " movnti %%edx, 36(%3)\n"
5359+ " movnti %%eax, %%es:32(%3)\n"
5360+ " movnti %%edx, %%es:36(%3)\n"
5361 "12: movl 40(%4), %%eax\n"
5362 "71: movl 44(%4), %%edx\n"
5363- " movnti %%eax, 40(%3)\n"
5364- " movnti %%edx, 44(%3)\n"
5365+ " movnti %%eax, %%es:40(%3)\n"
5366+ " movnti %%edx, %%es:44(%3)\n"
5367 "13: movl 48(%4), %%eax\n"
5368 "81: movl 52(%4), %%edx\n"
5369- " movnti %%eax, 48(%3)\n"
5370- " movnti %%edx, 52(%3)\n"
5371+ " movnti %%eax, %%es:48(%3)\n"
5372+ " movnti %%edx, %%es:52(%3)\n"
5373 "14: movl 56(%4), %%eax\n"
5374 "91: movl 60(%4), %%edx\n"
5375- " movnti %%eax, 56(%3)\n"
5376- " movnti %%edx, 60(%3)\n"
5377+ " movnti %%eax, %%es:56(%3)\n"
5378+ " movnti %%edx, %%es:60(%3)\n"
5379 " addl $-64, %0\n"
5380 " addl $64, %4\n"
5381 " addl $64, %3\n"
5382@@ -490,6 +620,8 @@ static unsigned long __copy_user_zeroing
5383 " movl %%eax,%0\n"
5384 "7: rep; movsb\n"
5385 "8:\n"
5386+ " pushl %%ss\n"
5387+ " popl %%ds\n"
5388 ".section .fixup,\"ax\"\n"
5389 "9: lea 0(%%eax,%0,4),%0\n"
5390 "16: pushl %0\n"
5391@@ -524,7 +656,7 @@ static unsigned long __copy_user_zeroing
5392 " .long 7b,16b\n"
5393 ".previous"
5394 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5395- : "1"(to), "2"(from), "0"(size)
5396+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5397 : "eax", "edx", "memory");
5398 return size;
5399 }
5400@@ -535,6 +667,7 @@ static unsigned long __copy_user_intel_n
5401 int d0, d1;
5402
5403 __asm__ __volatile__(
5404+ " movw %w6, %%ds\n"
5405 " .align 2,0x90\n"
5406 "0: movl 32(%4), %%eax\n"
5407 " cmpl $67, %0\n"
5408@@ -543,36 +676,36 @@ static unsigned long __copy_user_intel_n
5409 " .align 2,0x90\n"
5410 "2: movl 0(%4), %%eax\n"
5411 "21: movl 4(%4), %%edx\n"
5412- " movnti %%eax, 0(%3)\n"
5413- " movnti %%edx, 4(%3)\n"
5414+ " movnti %%eax, %%es:0(%3)\n"
5415+ " movnti %%edx, %%es:4(%3)\n"
5416 "3: movl 8(%4), %%eax\n"
5417 "31: movl 12(%4),%%edx\n"
5418- " movnti %%eax, 8(%3)\n"
5419- " movnti %%edx, 12(%3)\n"
5420+ " movnti %%eax, %%es:8(%3)\n"
5421+ " movnti %%edx, %%es:12(%3)\n"
5422 "4: movl 16(%4), %%eax\n"
5423 "41: movl 20(%4), %%edx\n"
5424- " movnti %%eax, 16(%3)\n"
5425- " movnti %%edx, 20(%3)\n"
5426+ " movnti %%eax, %%es:16(%3)\n"
5427+ " movnti %%edx, %%es:20(%3)\n"
5428 "10: movl 24(%4), %%eax\n"
5429 "51: movl 28(%4), %%edx\n"
5430- " movnti %%eax, 24(%3)\n"
5431- " movnti %%edx, 28(%3)\n"
5432+ " movnti %%eax, %%es:24(%3)\n"
5433+ " movnti %%edx, %%es:28(%3)\n"
5434 "11: movl 32(%4), %%eax\n"
5435 "61: movl 36(%4), %%edx\n"
5436- " movnti %%eax, 32(%3)\n"
5437- " movnti %%edx, 36(%3)\n"
5438+ " movnti %%eax, %%es:32(%3)\n"
5439+ " movnti %%edx, %%es:36(%3)\n"
5440 "12: movl 40(%4), %%eax\n"
5441 "71: movl 44(%4), %%edx\n"
5442- " movnti %%eax, 40(%3)\n"
5443- " movnti %%edx, 44(%3)\n"
5444+ " movnti %%eax, %%es:40(%3)\n"
5445+ " movnti %%edx, %%es:44(%3)\n"
5446 "13: movl 48(%4), %%eax\n"
5447 "81: movl 52(%4), %%edx\n"
5448- " movnti %%eax, 48(%3)\n"
5449- " movnti %%edx, 52(%3)\n"
5450+ " movnti %%eax, %%es:48(%3)\n"
5451+ " movnti %%edx, %%es:52(%3)\n"
5452 "14: movl 56(%4), %%eax\n"
5453 "91: movl 60(%4), %%edx\n"
5454- " movnti %%eax, 56(%3)\n"
5455- " movnti %%edx, 60(%3)\n"
5456+ " movnti %%eax, %%es:56(%3)\n"
5457+ " movnti %%edx, %%es:60(%3)\n"
5458 " addl $-64, %0\n"
5459 " addl $64, %4\n"
5460 " addl $64, %3\n"
5461@@ -587,6 +720,8 @@ static unsigned long __copy_user_intel_n
5462 " movl %%eax,%0\n"
5463 "7: rep; movsb\n"
5464 "8:\n"
5465+ " pushl %%ss\n"
5466+ " popl %%ds\n"
5467 ".section .fixup,\"ax\"\n"
5468 "9: lea 0(%%eax,%0,4),%0\n"
5469 "16: jmp 8b\n"
5470@@ -615,7 +750,7 @@ static unsigned long __copy_user_intel_n
5471 " .long 7b,16b\n"
5472 ".previous"
5473 : "=&c"(size), "=&D" (d0), "=&S" (d1)
5474- : "1"(to), "2"(from), "0"(size)
5475+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5476 : "eax", "edx", "memory");
5477 return size;
5478 }
5479@@ -628,90 +763,146 @@ static unsigned long __copy_user_intel_n
5480 */
5481 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
5482 unsigned long size);
5483-unsigned long __copy_user_intel(void __user *to, const void *from,
5484+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
5485+ unsigned long size);
5486+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
5487 unsigned long size);
5488 unsigned long __copy_user_zeroing_intel_nocache(void *to,
5489 const void __user *from, unsigned long size);
5490 #endif /* CONFIG_X86_INTEL_USERCOPY */
5491
5492 /* Generic arbitrary sized copy. */
5493-#define __copy_user(to,from,size) \
5494-do { \
5495- int __d0, __d1, __d2; \
5496- __asm__ __volatile__( \
5497- " cmp $7,%0\n" \
5498- " jbe 1f\n" \
5499- " movl %1,%0\n" \
5500- " negl %0\n" \
5501- " andl $7,%0\n" \
5502- " subl %0,%3\n" \
5503- "4: rep; movsb\n" \
5504- " movl %3,%0\n" \
5505- " shrl $2,%0\n" \
5506- " andl $3,%3\n" \
5507- " .align 2,0x90\n" \
5508- "0: rep; movsl\n" \
5509- " movl %3,%0\n" \
5510- "1: rep; movsb\n" \
5511- "2:\n" \
5512- ".section .fixup,\"ax\"\n" \
5513- "5: addl %3,%0\n" \
5514- " jmp 2b\n" \
5515- "3: lea 0(%3,%0,4),%0\n" \
5516- " jmp 2b\n" \
5517- ".previous\n" \
5518- ".section __ex_table,\"a\"\n" \
5519- " .align 4\n" \
5520- " .long 4b,5b\n" \
5521- " .long 0b,3b\n" \
5522- " .long 1b,2b\n" \
5523- ".previous" \
5524- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
5525- : "3"(size), "0"(size), "1"(to), "2"(from) \
5526- : "memory"); \
5527-} while (0)
5528-
5529-#define __copy_user_zeroing(to,from,size) \
5530-do { \
5531- int __d0, __d1, __d2; \
5532- __asm__ __volatile__( \
5533- " cmp $7,%0\n" \
5534- " jbe 1f\n" \
5535- " movl %1,%0\n" \
5536- " negl %0\n" \
5537- " andl $7,%0\n" \
5538- " subl %0,%3\n" \
5539- "4: rep; movsb\n" \
5540- " movl %3,%0\n" \
5541- " shrl $2,%0\n" \
5542- " andl $3,%3\n" \
5543- " .align 2,0x90\n" \
5544- "0: rep; movsl\n" \
5545- " movl %3,%0\n" \
5546- "1: rep; movsb\n" \
5547- "2:\n" \
5548- ".section .fixup,\"ax\"\n" \
5549- "5: addl %3,%0\n" \
5550- " jmp 6f\n" \
5551- "3: lea 0(%3,%0,4),%0\n" \
5552- "6: pushl %0\n" \
5553- " pushl %%eax\n" \
5554- " xorl %%eax,%%eax\n" \
5555- " rep; stosb\n" \
5556- " popl %%eax\n" \
5557- " popl %0\n" \
5558- " jmp 2b\n" \
5559- ".previous\n" \
5560- ".section __ex_table,\"a\"\n" \
5561- " .align 4\n" \
5562- " .long 4b,5b\n" \
5563- " .long 0b,3b\n" \
5564- " .long 1b,6b\n" \
5565- ".previous" \
5566- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
5567- : "3"(size), "0"(size), "1"(to), "2"(from) \
5568- : "memory"); \
5569-} while (0)
5570+static unsigned long
5571+__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
5572+{
5573+ int __d0, __d1, __d2;
5574+
5575+ __asm__ __volatile__(
5576+ " movw %w8,%%es\n"
5577+ " cmp $7,%0\n"
5578+ " jbe 1f\n"
5579+ " movl %1,%0\n"
5580+ " negl %0\n"
5581+ " andl $7,%0\n"
5582+ " subl %0,%3\n"
5583+ "4: rep; movsb\n"
5584+ " movl %3,%0\n"
5585+ " shrl $2,%0\n"
5586+ " andl $3,%3\n"
5587+ " .align 2,0x90\n"
5588+ "0: rep; movsl\n"
5589+ " movl %3,%0\n"
5590+ "1: rep; movsb\n"
5591+ "2:\n"
5592+ " pushl %%ss\n"
5593+ " popl %%es\n"
5594+ ".section .fixup,\"ax\"\n"
5595+ "5: addl %3,%0\n"
5596+ " jmp 2b\n"
5597+ "3: lea 0(%3,%0,4),%0\n"
5598+ " jmp 2b\n"
5599+ ".previous\n"
5600+ ".section __ex_table,\"a\"\n"
5601+ " .align 4\n"
5602+ " .long 4b,5b\n"
5603+ " .long 0b,3b\n"
5604+ " .long 1b,2b\n"
5605+ ".previous"
5606+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5607+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5608+ : "memory");
5609+ return size;
5610+}
5611+
5612+static unsigned long
5613+__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
5614+{
5615+ int __d0, __d1, __d2;
5616+
5617+ __asm__ __volatile__(
5618+ " movw %w8,%%ds\n"
5619+ " cmp $7,%0\n"
5620+ " jbe 1f\n"
5621+ " movl %1,%0\n"
5622+ " negl %0\n"
5623+ " andl $7,%0\n"
5624+ " subl %0,%3\n"
5625+ "4: rep; movsb\n"
5626+ " movl %3,%0\n"
5627+ " shrl $2,%0\n"
5628+ " andl $3,%3\n"
5629+ " .align 2,0x90\n"
5630+ "0: rep; movsl\n"
5631+ " movl %3,%0\n"
5632+ "1: rep; movsb\n"
5633+ "2:\n"
5634+ " pushl %%ss\n"
5635+ " popl %%ds\n"
5636+ ".section .fixup,\"ax\"\n"
5637+ "5: addl %3,%0\n"
5638+ " jmp 2b\n"
5639+ "3: lea 0(%3,%0,4),%0\n"
5640+ " jmp 2b\n"
5641+ ".previous\n"
5642+ ".section __ex_table,\"a\"\n"
5643+ " .align 4\n"
5644+ " .long 4b,5b\n"
5645+ " .long 0b,3b\n"
5646+ " .long 1b,2b\n"
5647+ ".previous"
5648+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5649+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5650+ : "memory");
5651+ return size;
5652+}
5653+
5654+static unsigned long
5655+__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
5656+{
5657+ int __d0, __d1, __d2;
5658+
5659+ __asm__ __volatile__(
5660+ " movw %w8,%%ds\n"
5661+ " cmp $7,%0\n"
5662+ " jbe 1f\n"
5663+ " movl %1,%0\n"
5664+ " negl %0\n"
5665+ " andl $7,%0\n"
5666+ " subl %0,%3\n"
5667+ "4: rep; movsb\n"
5668+ " movl %3,%0\n"
5669+ " shrl $2,%0\n"
5670+ " andl $3,%3\n"
5671+ " .align 2,0x90\n"
5672+ "0: rep; movsl\n"
5673+ " movl %3,%0\n"
5674+ "1: rep; movsb\n"
5675+ "2:\n"
5676+ " pushl %%ss\n"
5677+ " popl %%ds\n"
5678+ ".section .fixup,\"ax\"\n"
5679+ "5: addl %3,%0\n"
5680+ " jmp 6f\n"
5681+ "3: lea 0(%3,%0,4),%0\n"
5682+ "6: pushl %0\n"
5683+ " pushl %%eax\n"
5684+ " xorl %%eax,%%eax\n"
5685+ " rep; stosb\n"
5686+ " popl %%eax\n"
5687+ " popl %0\n"
5688+ " jmp 2b\n"
5689+ ".previous\n"
5690+ ".section __ex_table,\"a\"\n"
5691+ " .align 4\n"
5692+ " .long 4b,5b\n"
5693+ " .long 0b,3b\n"
5694+ " .long 1b,6b\n"
5695+ ".previous"
5696+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5697+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5698+ : "memory");
5699+ return size;
5700+}
5701
5702 unsigned long __copy_to_user_ll(void __user *to, const void *from,
5703 unsigned long n)
5704@@ -774,9 +965,9 @@ survive:
5705 }
5706 #endif
5707 if (movsl_is_ok(to, from, n))
5708- __copy_user(to, from, n);
5709+ n = __generic_copy_to_user(to, from, n);
5710 else
5711- n = __copy_user_intel(to, from, n);
5712+ n = __generic_copy_to_user_intel(to, from, n);
5713 return n;
5714 }
5715 EXPORT_SYMBOL(__copy_to_user_ll);
5716@@ -785,7 +976,7 @@ unsigned long __copy_from_user_ll(void *
5717 unsigned long n)
5718 {
5719 if (movsl_is_ok(to, from, n))
5720- __copy_user_zeroing(to, from, n);
5721+ n = __copy_user_zeroing(to, from, n);
5722 else
5723 n = __copy_user_zeroing_intel(to, from, n);
5724 return n;
5725@@ -796,9 +987,9 @@ unsigned long __copy_from_user_ll_nozero
5726 unsigned long n)
5727 {
5728 if (movsl_is_ok(to, from, n))
5729- __copy_user(to, from, n);
5730+ n = __generic_copy_from_user(to, from, n);
5731 else
5732- n = __copy_user_intel((void __user *)to,
5733+ n = __generic_copy_from_user_intel((void __user *)to,
5734 (const void *)from, n);
5735 return n;
5736 }
5737@@ -809,11 +1000,11 @@ unsigned long __copy_from_user_ll_nocach
5738 {
5739 #ifdef CONFIG_X86_INTEL_USERCOPY
5740 if ( n > 64 && cpu_has_xmm2)
5741- n = __copy_user_zeroing_intel_nocache(to, from, n);
5742+ n = __copy_user_zeroing_intel_nocache(to, from, n);
5743 else
5744- __copy_user_zeroing(to, from, n);
5745+ n = __copy_user_zeroing(to, from, n);
5746 #else
5747- __copy_user_zeroing(to, from, n);
5748+ n = __copy_user_zeroing(to, from, n);
5749 #endif
5750 return n;
5751 }
5752@@ -823,11 +1014,11 @@ unsigned long __copy_from_user_ll_nocach
5753 {
5754 #ifdef CONFIG_X86_INTEL_USERCOPY
5755 if ( n > 64 && cpu_has_xmm2)
5756- n = __copy_user_intel_nocache(to, from, n);
5757+ n = __copy_user_intel_nocache(to, from, n);
5758 else
5759- __copy_user(to, from, n);
5760+ n = __generic_copy_from_user(to, from, n);
5761 #else
5762- __copy_user(to, from, n);
5763+ n = __generic_copy_from_user(to, from, n);
5764 #endif
5765 return n;
5766 }
5767@@ -880,3 +1071,30 @@ copy_from_user(void *to, const void __us
5768 return n;
5769 }
5770 EXPORT_SYMBOL(copy_from_user);
5771+
5772+#ifdef CONFIG_PAX_MEMORY_UDEREF
5773+void __set_fs(mm_segment_t x, int cpu)
5774+{
5775+ unsigned long limit = x.seg;
5776+ __u32 a, b;
5777+
5778+ current_thread_info()->addr_limit = x;
5779+ if (likely(limit))
5780+ limit = (limit - 1UL) >> PAGE_SHIFT;
5781+ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
5782+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
5783+}
5784+
5785+void set_fs(mm_segment_t x)
5786+{
5787+ __set_fs(x, get_cpu());
5788+ put_cpu_no_resched();
5789+}
5790+#else
5791+void set_fs(mm_segment_t x)
5792+{
5793+ current_thread_info()->addr_limit = x;
5794+}
5795+#endif
5796+
5797+EXPORT_SYMBOL(set_fs);
5798diff -urNp linux-2.6.22.1/arch/i386/mach-default/setup.c linux-2.6.22.1/arch/i386/mach-default/setup.c
5799--- linux-2.6.22.1/arch/i386/mach-default/setup.c 2007-07-10 14:56:30.000000000 -0400
5800+++ linux-2.6.22.1/arch/i386/mach-default/setup.c 2007-08-02 11:38:45.000000000 -0400
5801@@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void)
5802 /*
5803 * IRQ2 is cascade interrupt to second interrupt controller
5804 */
5805-static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
5806+static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
5807
5808 /**
5809 * intr_init_hook - post gate setup interrupt initialisation
5810diff -urNp linux-2.6.22.1/arch/i386/mach-voyager/voyager_basic.c linux-2.6.22.1/arch/i386/mach-voyager/voyager_basic.c
5811--- linux-2.6.22.1/arch/i386/mach-voyager/voyager_basic.c 2007-07-10 14:56:30.000000000 -0400
5812+++ linux-2.6.22.1/arch/i386/mach-voyager/voyager_basic.c 2007-08-02 11:38:45.000000000 -0400
5813@@ -130,7 +130,7 @@ voyager_memory_detect(int region, __u32
5814 __u8 cmos[4];
5815 ClickMap_t *map;
5816 unsigned long map_addr;
5817- unsigned long old;
5818+ pte_t old;
5819
5820 if(region >= CLICK_ENTRIES) {
5821 printk("Voyager: Illegal ClickMap region %d\n", region);
5822@@ -144,7 +144,7 @@ voyager_memory_detect(int region, __u32
5823
5824 /* steal page 0 for this */
5825 old = pg0[0];
5826- pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
5827+ pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
5828 local_flush_tlb();
5829 /* now clear everything out but page 0 */
5830 map = (ClickMap_t *)(map_addr & (~PAGE_MASK));
5831diff -urNp linux-2.6.22.1/arch/i386/mach-voyager/voyager_smp.c linux-2.6.22.1/arch/i386/mach-voyager/voyager_smp.c
5832--- linux-2.6.22.1/arch/i386/mach-voyager/voyager_smp.c 2007-07-10 14:56:30.000000000 -0400
5833+++ linux-2.6.22.1/arch/i386/mach-voyager/voyager_smp.c 2007-08-02 11:38:45.000000000 -0400
5834@@ -554,6 +554,10 @@ do_boot_cpu(__u8 cpu)
5835 __u32 *hijack_vector;
5836 __u32 start_phys_address = setup_trampoline();
5837
5838+#ifdef CONFIG_PAX_KERNEXEC
5839+ unsigned long cr0;
5840+#endif
5841+
5842 /* There's a clever trick to this: The linux trampoline is
5843 * compiled to begin at absolute location zero, so make the
5844 * address zero but have the data segment selector compensate
5845@@ -573,7 +577,17 @@ do_boot_cpu(__u8 cpu)
5846
5847 init_gdt(cpu);
5848 per_cpu(current_task, cpu) = idle;
5849- early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
5850+
5851+#ifdef CONFIG_PAX_KERNEXEC
5852+ pax_open_kernel(cr0);
5853+#endif
5854+
5855+ early_gdt_descr.address = get_cpu_gdt_table(cpu);
5856+
5857+#ifdef CONFIG_PAX_KERNEXEC
5858+ pax_close_kernel(cr0);
5859+#endif
5860+
5861 irq_ctx_init(cpu);
5862
5863 /* Note: Don't modify initial ss override */
5864@@ -1276,7 +1290,7 @@ smp_local_timer_interrupt(void)
5865 per_cpu(prof_counter, cpu);
5866 }
5867
5868- update_process_times(user_mode_vm(get_irq_regs()));
5869+ update_process_times(user_mode(get_irq_regs()));
5870 }
5871
5872 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
5873diff -urNp linux-2.6.22/arch/i386/mm/boot_ioremap.c linux-2.6.22/arch/i386/mm/boot_ioremap.c
5874--- linux-2.6.22/arch/i386/mm/boot_ioremap.c 2007-07-10 14:56:30.000000000 -0400
5875+++ linux-2.6.22/arch/i386/mm/boot_ioremap.c 2007-07-10 14:56:30.000000000 -0400
5876@@ -7,57 +7,37 @@
5877 * Written by Dave Hansen <haveblue@us.ibm.com>
5878 */
5879
5880-
5881-/*
5882- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
5883- * keeps that from happenning. If anyone has a better way, I'm listening.
5884- *
5885- * boot_pte_t is defined only if this all works correctly
5886- */
5887-
5888-#undef CONFIG_X86_PAE
5889 #undef CONFIG_PARAVIRT
5890 #include <asm/page.h>
5891 #include <asm/pgtable.h>
5892 #include <asm/tlbflush.h>
5893 #include <linux/init.h>
5894 #include <linux/stddef.h>
5895-
5896-/*
5897- * I'm cheating here. It is known that the two boot PTE pages are
5898- * allocated next to each other. I'm pretending that they're just
5899- * one big array.
5900- */
5901-
5902-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
5903-
5904-static unsigned long boot_pte_index(unsigned long vaddr)
5905-{
5906- return __pa(vaddr) >> PAGE_SHIFT;
5907-}
5908-
5909-static inline boot_pte_t* boot_vaddr_to_pte(void *address)
5910-{
5911- boot_pte_t* boot_pg = (boot_pte_t*)pg0;
5912- return &boot_pg[boot_pte_index((unsigned long)address)];
5913-}
5914+#include <linux/sched.h>
5915
5916 /*
5917 * This is only for a caller who is clever enough to page-align
5918 * phys_addr and virtual_source, and who also has a preference
5919 * about which virtual address from which to steal ptes
5920 */
5921-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
5922- void* virtual_source)
5923+static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
5924+ char* virtual_source)
5925 {
5926- boot_pte_t* pte;
5927- int i;
5928- char *vaddr = virtual_source;
5929+ pgd_t *pgd;
5930+ pud_t *pud;
5931+ pmd_t *pmd;
5932+ pte_t* pte;
5933+ unsigned int i;
5934+ unsigned long vaddr = (unsigned long)virtual_source;
5935+
5936+ pgd = pgd_offset_k(vaddr);
5937+ pud = pud_offset(pgd, vaddr);
5938+ pmd = pmd_offset(pud, vaddr);
5939+ pte = pte_offset_kernel(pmd, vaddr);
5940
5941- pte = boot_vaddr_to_pte(virtual_source);
5942 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
5943 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
5944- __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
5945+ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
5946 }
5947 }
5948
5949diff -urNp linux-2.6.22.1/arch/i386/mm/extable.c linux-2.6.22.1/arch/i386/mm/extable.c
5950--- linux-2.6.22.1/arch/i386/mm/extable.c 2007-07-10 14:56:30.000000000 -0400
5951+++ linux-2.6.22.1/arch/i386/mm/extable.c 2007-08-02 11:38:45.000000000 -0400
5952@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
5953 const struct exception_table_entry *fixup;
5954
5955 #ifdef CONFIG_PNPBIOS
5956- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
5957+ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
5958 {
5959 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
5960 extern u32 pnp_bios_is_utter_crap;
5961diff -urNp linux-2.6.22.1/arch/i386/mm/fault.c linux-2.6.22.1/arch/i386/mm/fault.c
5962--- linux-2.6.22.1/arch/i386/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
5963+++ linux-2.6.22.1/arch/i386/mm/fault.c 2007-08-02 11:45:43.000000000 -0400
5964@@ -26,10 +26,14 @@
5965 #include <linux/uaccess.h>
5966 #include <linux/kdebug.h>
5967 #include <linux/suspend.h>
5968+#include <linux/unistd.h>
5969+#include <linux/compiler.h>
5970+#include <linux/binfmts.h>
5971
5972 #include <asm/system.h>
5973 #include <asm/desc.h>
5974 #include <asm/segment.h>
5975+#include <asm/tlbflush.h>
5976
5977 extern void die(const char *,struct pt_regs *,long);
5978
5979@@ -79,7 +83,8 @@ static inline unsigned long get_segment_
5980 {
5981 unsigned long eip = regs->eip;
5982 unsigned seg = regs->xcs & 0xffff;
5983- u32 seg_ar, seg_limit, base, *desc;
5984+ u32 seg_ar, seg_limit, base;
5985+ struct desc_struct *desc;
5986
5987 /* Unlikely, but must come before segment checks. */
5988 if (unlikely(regs->eflags & VM_MASK)) {
5989@@ -93,7 +98,7 @@ static inline unsigned long get_segment_
5990
5991 /* By far the most common cases. */
5992 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
5993- return eip;
5994+ return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
5995
5996 /* Check the segment exists, is within the current LDT/GDT size,
5997 that kernel/user (ring 0..3) has the appropriate privilege,
5998@@ -111,16 +116,19 @@ static inline unsigned long get_segment_
5999 if (seg & (1<<2)) {
6000 /* Must lock the LDT while reading it. */
6001 down(&current->mm->context.sem);
6002- desc = current->mm->context.ldt;
6003- desc = (void *)desc + (seg & ~7);
6004+ if ((seg >> 3) >= current->mm->context.size) {
6005+ up(&current->mm->context.sem);
6006+ *eip_limit = 0;
6007+ return 1; /* So that returned eip > *eip_limit. */
6008+ }
6009+ desc = &current->mm->context.ldt[seg >> 3];
6010 } else {
6011 /* Must disable preemption while reading the GDT. */
6012- desc = (u32 *)get_cpu_gdt_table(get_cpu());
6013- desc = (void *)desc + (seg & ~7);
6014+ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
6015 }
6016
6017 /* Decode the code segment base from the descriptor */
6018- base = get_desc_base((unsigned long *)desc);
6019+ base = get_desc_base(desc);
6020
6021 if (seg & (1<<2)) {
6022 up(&current->mm->context.sem);
6023@@ -221,6 +229,30 @@ static noinline void force_sig_info_faul
6024
6025 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
6026
6027+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6028+static int pax_handle_fetch_fault(struct pt_regs *regs);
6029+#endif
6030+
6031+#ifdef CONFIG_PAX_PAGEEXEC
6032+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
6033+{
6034+ pgd_t *pgd;
6035+ pud_t *pud;
6036+ pmd_t *pmd;
6037+
6038+ pgd = pgd_offset(mm, address);
6039+ if (!pgd_present(*pgd))
6040+ return NULL;
6041+ pud = pud_offset(pgd, address);
6042+ if (!pud_present(*pud))
6043+ return NULL;
6044+ pmd = pmd_offset(pud, address);
6045+ if (!pmd_present(*pmd))
6046+ return NULL;
6047+ return pmd;
6048+}
6049+#endif
6050+
6051 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
6052 {
6053 unsigned index = pgd_index(address);
6054@@ -301,13 +333,20 @@ fastcall void __kprobes do_page_fault(st
6055 struct task_struct *tsk;
6056 struct mm_struct *mm;
6057 struct vm_area_struct * vma;
6058- unsigned long address;
6059 int write, si_code;
6060+ pte_t *pte;
6061+
6062+#ifdef CONFIG_PAX_PAGEEXEC
6063+ pmd_t *pmd;
6064+ spinlock_t *ptl;
6065+ unsigned char pte_mask;
6066+#endif
6067
6068 /* get the address */
6069- address = read_cr2();
6070+ const unsigned long address = read_cr2();
6071
6072 tsk = current;
6073+ mm = tsk->mm;
6074
6075 si_code = SEGV_MAPERR;
6076
6077@@ -344,14 +383,12 @@ fastcall void __kprobes do_page_fault(st
6078 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
6079 local_irq_enable();
6080
6081- mm = tsk->mm;
6082-
6083 /*
6084 * If we're in an interrupt, have no user context or are running in an
6085 * atomic region then we must not take the fault..
6086 */
6087 if (in_atomic() || !mm)
6088- goto bad_area_nosemaphore;
6089+ goto bad_area_nopax;
6090
6091 /* When running in the kernel we expect faults to occur only to
6092 * addresses in user space. All other faults represent errors in the
6093@@ -371,10 +408,104 @@ fastcall void __kprobes do_page_fault(st
6094 if (!down_read_trylock(&mm->mmap_sem)) {
6095 if ((error_code & 4) == 0 &&
6096 !search_exception_tables(regs->eip))
6097- goto bad_area_nosemaphore;
6098+ goto bad_area_nopax;
6099 down_read(&mm->mmap_sem);
6100 }
6101
6102+#ifdef CONFIG_PAX_PAGEEXEC
6103+ if (nx_enabled || (error_code & 5) != 5 || (regs->eflags & X86_EFLAGS_VM) ||
6104+ !(mm->pax_flags & MF_PAX_PAGEEXEC))
6105+ goto not_pax_fault;
6106+
6107+ /* PaX: it's our fault, let's handle it if we can */
6108+
6109+ /* PaX: take a look at read faults before acquiring any locks */
6110+ if (unlikely(!(error_code & 2) && (regs->eip == address))) {
6111+ /* instruction fetch attempt from a protected page in user mode */
6112+ up_read(&mm->mmap_sem);
6113+
6114+#ifdef CONFIG_PAX_EMUTRAMP
6115+ switch (pax_handle_fetch_fault(regs)) {
6116+ case 2:
6117+ return;
6118+ }
6119+#endif
6120+
6121+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6122+ do_exit(SIGKILL);
6123+ }
6124+
6125+ pmd = pax_get_pmd(mm, address);
6126+ if (unlikely(!pmd))
6127+ goto not_pax_fault;
6128+
6129+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
6130+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
6131+ pte_unmap_unlock(pte, ptl);
6132+ goto not_pax_fault;
6133+ }
6134+
6135+ if (unlikely((error_code & 2) && !pte_write(*pte))) {
6136+ /* write attempt to a protected page in user mode */
6137+ pte_unmap_unlock(pte, ptl);
6138+ goto not_pax_fault;
6139+ }
6140+
6141+#ifdef CONFIG_SMP
6142+ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
6143+#else
6144+ if (likely(address > get_limit(regs->xcs)))
6145+#endif
6146+ {
6147+ set_pte(pte, pte_mkread(*pte));
6148+ __flush_tlb_one(address);
6149+ pte_unmap_unlock(pte, ptl);
6150+ up_read(&mm->mmap_sem);
6151+ return;
6152+ }
6153+
6154+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
6155+
6156+ /*
6157+ * PaX: fill DTLB with user rights and retry
6158+ */
6159+ __asm__ __volatile__ (
6160+#ifdef CONFIG_PAX_MEMORY_UDEREF
6161+ "movw %w4,%%es\n"
6162+#endif
6163+ "orb %2,(%1)\n"
6164+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
6165+/*
6166+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
6167+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
6168+ * page fault when examined during a TLB load attempt. this is true not only
6169+ * for PTEs holding a non-present entry but also present entries that will
6170+ * raise a page fault (such as those set up by PaX, or the copy-on-write
6171+ * mechanism). in effect it means that we do *not* need to flush the TLBs
6172+ * for our target pages since their PTEs are simply not in the TLBs at all.
6173+
6174+ * the best thing in omitting it is that we gain around 15-20% speed in the
6175+ * fast path of the page fault handler and can get rid of tracing since we
6176+ * can no longer flush unintended entries.
6177+ */
6178+ "invlpg (%0)\n"
6179+#endif
6180+ "testb $0,%%es:(%0)\n"
6181+ "xorb %3,(%1)\n"
6182+#ifdef CONFIG_PAX_MEMORY_UDEREF
6183+ "pushl %%ss\n"
6184+ "popl %%es\n"
6185+#endif
6186+ :
6187+ : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
6188+ : "memory", "cc");
6189+ pte_unmap_unlock(pte, ptl);
6190+ up_read(&mm->mmap_sem);
6191+ return;
6192+
6193+not_pax_fault:
6194+#endif
6195+
6196 vma = find_vma(mm, address);
6197 if (!vma)
6198 goto bad_area;
6199@@ -392,6 +523,12 @@ fastcall void __kprobes do_page_fault(st
6200 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
6201 goto bad_area;
6202 }
6203+
6204+#ifdef CONFIG_PAX_SEGMEXEC
6205+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
6206+ goto bad_area;
6207+#endif
6208+
6209 if (expand_stack(vma, address))
6210 goto bad_area;
6211 /*
6212@@ -401,6 +538,8 @@ fastcall void __kprobes do_page_fault(st
6213 good_area:
6214 si_code = SEGV_ACCERR;
6215 write = 0;
6216+ if (nx_enabled && (error_code & 16) && !(vma->vm_flags & VM_EXEC))
6217+ goto bad_area;
6218 switch (error_code & 3) {
6219 default: /* 3: write, present */
6220 /* fall through */
6221@@ -456,6 +595,41 @@ bad_area:
6222 up_read(&mm->mmap_sem);
6223
6224 bad_area_nosemaphore:
6225+
6226+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6227+ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
6228+ /*
6229+ * It's possible to have interrupts off here.
6230+ */
6231+ local_irq_enable();
6232+
6233+#ifdef CONFIG_PAX_PAGEEXEC
6234+ if ((nx_enabled && (error_code & 16)) ||
6235+ ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address))) {
6236+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6237+ do_exit(SIGKILL);
6238+ }
6239+#endif
6240+
6241+#ifdef CONFIG_PAX_SEGMEXEC
6242+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
6243+
6244+#ifdef CONFIG_PAX_EMUTRAMP
6245+ switch (pax_handle_fetch_fault(regs)) {
6246+ case 2:
6247+ return;
6248+ }
6249+#endif
6250+
6251+ pax_report_fault(regs, (void *)regs->eip, (void *)regs->esp);
6252+ do_exit(SIGKILL);
6253+ }
6254+#endif
6255+
6256+ }
6257+#endif
6258+
6259+bad_area_nopax:
6260 /* User mode accesses just cause a SIGSEGV */
6261 if (error_code & 4) {
6262 /*
6263@@ -485,7 +659,7 @@ bad_area_nosemaphore:
6264 if (boot_cpu_data.f00f_bug) {
6265 unsigned long nr;
6266
6267- nr = (address - idt_descr.address) >> 3;
6268+ nr = (address - (unsigned long)idt_descr.address) >> 3;
6269
6270 if (nr == 6) {
6271 do_invalid_op(regs, 0);
6272@@ -518,18 +692,34 @@ no_context:
6273 __typeof__(pte_val(__pte(0))) page;
6274
6275 #ifdef CONFIG_X86_PAE
6276- if (error_code & 16) {
6277- pte_t *pte = lookup_address(address);
6278+ if (nx_enabled && (error_code & 16)) {
6279+ pte = lookup_address(address);
6280
6281 if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
6282 printk(KERN_CRIT "kernel tried to execute "
6283 "NX-protected page - exploit attempt? "
6284- "(uid: %d)\n", current->uid);
6285+ "(uid: %d, task: %s, pid: %d)\n",
6286+ current->uid, current->comm, current->pid);
6287 }
6288 #endif
6289 if (address < PAGE_SIZE)
6290 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
6291 "pointer dereference");
6292+
6293+#ifdef CONFIG_PAX_KERNEXEC
6294+#ifdef CONFIG_MODULES
6295+ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
6296+#else
6297+ else if (init_mm.start_code <= address && address < init_mm.end_code)
6298+#endif
6299+ if (tsk->signal->curr_ip)
6300+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
6301+ NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
6302+ else
6303+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
6304+ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
6305+#endif
6306+
6307 else
6308 printk(KERN_ALERT "BUG: unable to handle kernel paging"
6309 " request");
6310@@ -560,7 +750,7 @@ no_context:
6311 * it's allocated already.
6312 */
6313 if ((page >> PAGE_SHIFT) < max_low_pfn
6314- && (page & _PAGE_PRESENT)) {
6315+ && (page & (_PAGE_PRESENT | _PAGE_PSE)) == _PAGE_PRESENT) {
6316 page &= PAGE_MASK;
6317 page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
6318 & (PTRS_PER_PTE - 1)];
6319@@ -645,3 +835,109 @@ void vmalloc_sync_all(void)
6320 start = address + PGDIR_SIZE;
6321 }
6322 }
6323+
6324+#ifdef CONFIG_PAX_EMUTRAMP
6325+/*
6326+ * PaX: decide what to do with offenders (regs->eip = fault address)
6327+ *
6328+ * returns 1 when task should be killed
6329+ * 2 when gcc trampoline was detected
6330+ */
6331+static int pax_handle_fetch_fault(struct pt_regs *regs)
6332+{
6333+ static const unsigned char trans[8] = {
6334+ offsetof(struct pt_regs, eax) / 4,
6335+ offsetof(struct pt_regs, ecx) / 4,
6336+ offsetof(struct pt_regs, edx) / 4,
6337+ offsetof(struct pt_regs, ebx) / 4,
6338+ offsetof(struct pt_regs, esp) / 4,
6339+ offsetof(struct pt_regs, ebp) / 4,
6340+ offsetof(struct pt_regs, esi) / 4,
6341+ offsetof(struct pt_regs, edi) / 4,
6342+ };
6343+ int err;
6344+
6345+ if (regs->eflags & X86_EFLAGS_VM)
6346+ return 1;
6347+
6348+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6349+ return 1;
6350+
6351+ do { /* PaX: gcc trampoline emulation #1 */
6352+ unsigned char mov1, mov2;
6353+ unsigned short jmp;
6354+ unsigned long addr1, addr2;
6355+
6356+ err = get_user(mov1, (unsigned char __user *)regs->eip);
6357+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6358+ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
6359+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6360+ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
6361+
6362+ if (err)
6363+ break;
6364+
6365+ if ((mov1 & 0xF8) == 0xB8 &&
6366+ (mov2 & 0xF8) == 0xB8 &&
6367+ (mov1 & 0x07) != (mov2 & 0x07) &&
6368+ (jmp & 0xF8FF) == 0xE0FF &&
6369+ (mov2 & 0x07) == ((jmp>>8) & 0x07))
6370+ {
6371+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
6372+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
6373+ regs->eip = addr2;
6374+ return 2;
6375+ }
6376+ } while (0);
6377+
6378+ do { /* PaX: gcc trampoline emulation #2 */
6379+ unsigned char mov, jmp;
6380+ unsigned long addr1, addr2;
6381+
6382+ err = get_user(mov, (unsigned char __user *)regs->eip);
6383+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6384+ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
6385+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6386+
6387+ if (err)
6388+ break;
6389+
6390+ if ((mov & 0xF8) == 0xB8 &&
6391+ jmp == 0xE9)
6392+ {
6393+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
6394+ regs->eip += addr2 + 10;
6395+ return 2;
6396+ }
6397+ } while (0);
6398+
6399+ return 1; /* PaX in action */
6400+}
6401+#endif
6402+
6403+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6404+void pax_report_insns(void *pc, void *sp)
6405+{
6406+ long i;
6407+
6408+ printk(KERN_ERR "PAX: bytes at PC: ");
6409+ for (i = 0; i < 20; i++) {
6410+ unsigned char c;
6411+ if (get_user(c, (unsigned char __user *)pc+i))
6412+ printk("?? ");
6413+ else
6414+ printk("%02x ", c);
6415+ }
6416+ printk("\n");
6417+
6418+ printk(KERN_ERR "PAX: bytes at SP-4: ");
6419+ for (i = -1; i < 20; i++) {
6420+ unsigned long c;
6421+ if (get_user(c, (unsigned long __user *)sp+i))
6422+ printk("???????? ");
6423+ else
6424+ printk("%08lx ", c);
6425+ }
6426+ printk("\n");
6427+}
6428+#endif
6429diff -urNp linux-2.6.22.1/arch/i386/mm/hugetlbpage.c linux-2.6.22.1/arch/i386/mm/hugetlbpage.c
6430--- linux-2.6.22.1/arch/i386/mm/hugetlbpage.c 2007-07-10 14:56:30.000000000 -0400
6431+++ linux-2.6.22.1/arch/i386/mm/hugetlbpage.c 2007-08-02 11:38:45.000000000 -0400
6432@@ -229,13 +229,18 @@ static unsigned long hugetlb_get_unmappe
6433 {
6434 struct mm_struct *mm = current->mm;
6435 struct vm_area_struct *vma;
6436- unsigned long start_addr;
6437+ unsigned long start_addr, task_size = TASK_SIZE;
6438+
6439+#ifdef CONFIG_PAX_SEGMEXEC
6440+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6441+ task_size = SEGMEXEC_TASK_SIZE;
6442+#endif
6443
6444 if (len > mm->cached_hole_size) {
6445- start_addr = mm->free_area_cache;
6446+ start_addr = mm->free_area_cache;
6447 } else {
6448- start_addr = TASK_UNMAPPED_BASE;
6449- mm->cached_hole_size = 0;
6450+ start_addr = mm->mmap_base;
6451+ mm->cached_hole_size = 0;
6452 }
6453
6454 full_search:
6455@@ -243,13 +248,13 @@ full_search:
6456
6457 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6458 /* At this point: (!vma || addr < vma->vm_end). */
6459- if (TASK_SIZE - len < addr) {
6460+ if (task_size - len < addr) {
6461 /*
6462 * Start a new search - just in case we missed
6463 * some holes.
6464 */
6465- if (start_addr != TASK_UNMAPPED_BASE) {
6466- start_addr = TASK_UNMAPPED_BASE;
6467+ if (start_addr != mm->mmap_base) {
6468+ start_addr = mm->mmap_base;
6469 mm->cached_hole_size = 0;
6470 goto full_search;
6471 }
6472@@ -271,9 +276,8 @@ static unsigned long hugetlb_get_unmappe
6473 {
6474 struct mm_struct *mm = current->mm;
6475 struct vm_area_struct *vma, *prev_vma;
6476- unsigned long base = mm->mmap_base, addr = addr0;
6477+ unsigned long base = mm->mmap_base, addr;
6478 unsigned long largest_hole = mm->cached_hole_size;
6479- int first_time = 1;
6480
6481 /* don't allow allocations above current base */
6482 if (mm->free_area_cache > base)
6483@@ -283,7 +287,7 @@ static unsigned long hugetlb_get_unmappe
6484 largest_hole = 0;
6485 mm->free_area_cache = base;
6486 }
6487-try_again:
6488+
6489 /* make sure it can fit in the remaining address space */
6490 if (mm->free_area_cache < len)
6491 goto fail;
6492@@ -325,22 +329,26 @@ try_again:
6493
6494 fail:
6495 /*
6496- * if hint left us with no space for the requested
6497- * mapping then try again:
6498- */
6499- if (first_time) {
6500- mm->free_area_cache = base;
6501- largest_hole = 0;
6502- first_time = 0;
6503- goto try_again;
6504- }
6505- /*
6506 * A failed mmap() very likely causes application failure,
6507 * so fall back to the bottom-up function here. This scenario
6508 * can happen with large stack limits and large mmap()
6509 * allocations.
6510 */
6511- mm->free_area_cache = TASK_UNMAPPED_BASE;
6512+
6513+#ifdef CONFIG_PAX_SEGMEXEC
6514+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6515+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6516+ else
6517+#endif
6518+
6519+ mm->mmap_base = TASK_UNMAPPED_BASE;
6520+
6521+#ifdef CONFIG_PAX_RANDMMAP
6522+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6523+ mm->mmap_base += mm->delta_mmap;
6524+#endif
6525+
6526+ mm->free_area_cache = mm->mmap_base;
6527 mm->cached_hole_size = ~0UL;
6528 addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
6529 len, pgoff, flags);
6530@@ -348,6 +343,7 @@ fail:
6531 /*
6532 * Restore the topdown base:
6533 */
6534+ mm->mmap_base = base;
6535 mm->free_area_cache = base;
6536 mm->cached_hole_size = ~0UL;
6537
6538@@ -360,10 +356,17 @@ hugetlb_get_unmapped_area(struct file *f
6539 {
6540 struct mm_struct *mm = current->mm;
6541 struct vm_area_struct *vma;
6542+ unsigned long task_size = TASK_SIZE;
6543
6544 if (len & ~HPAGE_MASK)
6545 return -EINVAL;
6546- if (len > TASK_SIZE)
6547+
6548+#ifdef CONFIG_PAX_SEGMEXEC
6549+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6550+ task_size = SEGMEXEC_TASK_SIZE;
6551+#endif
6552+
6553+ if (len > task_size)
6554 return -ENOMEM;
6555
6556 if (flags & MAP_FIXED) {
6557@@ -375,7 +378,7 @@ hugetlb_get_unmapped_area(struct file *f
6558 if (addr) {
6559 addr = ALIGN(addr, HPAGE_SIZE);
6560 vma = find_vma(mm, addr);
6561- if (TASK_SIZE - len >= addr &&
6562+ if (task_size - len >= addr &&
6563 (!vma || addr + len <= vma->vm_start))
6564 return addr;
6565 }
6566diff -urNp linux-2.6.22.1/arch/i386/mm/init.c linux-2.6.22.1/arch/i386/mm/init.c
6567--- linux-2.6.22.1/arch/i386/mm/init.c 2007-07-10 14:56:30.000000000 -0400
6568+++ linux-2.6.22.1/arch/i386/mm/init.c 2007-08-02 11:38:45.000000000 -0400
6569@@ -44,6 +44,7 @@
6570 #include <asm/tlbflush.h>
6571 #include <asm/sections.h>
6572 #include <asm/paravirt.h>
6573+#include <asm/desc.h>
6574
6575 unsigned int __VMALLOC_RESERVE = 128 << 20;
6576
6577@@ -53,32 +54,6 @@ unsigned long highstart_pfn, highend_pfn
6578 static int noinline do_test_wp_bit(void);
6579
6580 /*
6581- * Creates a middle page table and puts a pointer to it in the
6582- * given global directory entry. This only returns the gd entry
6583- * in non-PAE compilation mode, since the middle layer is folded.
6584- */
6585-static pmd_t * __init one_md_table_init(pgd_t *pgd)
6586-{
6587- pud_t *pud;
6588- pmd_t *pmd_table;
6589-
6590-#ifdef CONFIG_X86_PAE
6591- if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
6592- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6593-
6594- paravirt_alloc_pd(__pa(pmd_table) >> PAGE_SHIFT);
6595- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
6596- pud = pud_offset(pgd, 0);
6597- if (pmd_table != pmd_offset(pud, 0))
6598- BUG();
6599- }
6600-#endif
6601- pud = pud_offset(pgd, 0);
6602- pmd_table = pmd_offset(pud, 0);
6603- return pmd_table;
6604-}
6605-
6606-/*
6607 * Create a page table and place a pointer to it in a middle page
6608 * directory entry.
6609 */
6610@@ -88,7 +63,11 @@ static pte_t * __init one_page_table_ini
6611 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6612
6613 paravirt_alloc_pt(__pa(page_table) >> PAGE_SHIFT);
6614+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6615+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
6616+#else
6617 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
6618+#endif
6619 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
6620 }
6621
6622@@ -109,6 +88,7 @@ static pte_t * __init one_page_table_ini
6623 static void __init page_table_range_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
6624 {
6625 pgd_t *pgd;
6626+ pud_t *pud;
6627 pmd_t *pmd;
6628 int pgd_idx, pmd_idx;
6629 unsigned long vaddr;
6630@@ -119,8 +99,13 @@ static void __init page_table_range_init
6631 pgd = pgd_base + pgd_idx;
6632
6633 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
6634- pmd = one_md_table_init(pgd);
6635- pmd = pmd + pmd_index(vaddr);
6636+ pud = pud_offset(pgd, vaddr);
6637+ pmd = pmd_offset(pud, vaddr);
6638+
6639+#ifdef CONFIG_X86_PAE
6640+ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
6641+#endif
6642+
6643 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
6644 one_page_table_init(pmd);
6645
6646@@ -130,11 +115,23 @@ static void __init page_table_range_init
6647 }
6648 }
6649
6650-static inline int is_kernel_text(unsigned long addr)
6651+static inline int is_kernel_text(unsigned long start, unsigned long end)
6652 {
6653- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
6654- return 1;
6655- return 0;
6656+ unsigned long etext;
6657+
6658+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
6659+ etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6660+#else
6661+ etext = (unsigned long)&_etext;
6662+#endif
6663+
6664+ if ((start > etext + __KERNEL_TEXT_OFFSET ||
6665+ end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
6666+ (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
6667+ end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET) &&
6668+ (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
6669+ return 0;
6670+ return 1;
6671 }
6672
6673 /*
6674@@ -146,25 +143,29 @@ static void __init kernel_physical_mappi
6675 {
6676 unsigned long pfn;
6677 pgd_t *pgd;
6678+ pud_t *pud;
6679 pmd_t *pmd;
6680 pte_t *pte;
6681- int pgd_idx, pmd_idx, pte_ofs;
6682+ unsigned int pgd_idx, pmd_idx, pte_ofs;
6683
6684 pgd_idx = pgd_index(PAGE_OFFSET);
6685 pgd = pgd_base + pgd_idx;
6686 pfn = 0;
6687
6688- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
6689- pmd = one_md_table_init(pgd);
6690- if (pfn >= max_low_pfn)
6691- continue;
6692+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
6693+ pud = pud_offset(pgd, 0);
6694+ pmd = pmd_offset(pud, 0);
6695+
6696+#ifdef CONFIG_X86_PAE
6697+ paravirt_alloc_pd(__pa(pmd) >> PAGE_SHIFT);
6698+#endif
6699+
6700 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
6701- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
6702+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
6703
6704 /* Map with big pages if possible, otherwise create normal page tables. */
6705- if (cpu_has_pse) {
6706- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
6707- if (is_kernel_text(address) || is_kernel_text(address2))
6708+ if (cpu_has_pse && address >= (unsigned long)__va(0x100000)) {
6709+ if (is_kernel_text(address, address + PMD_SIZE))
6710 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
6711 else
6712 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
6713@@ -176,7 +177,7 @@ static void __init kernel_physical_mappi
6714 for (pte_ofs = 0;
6715 pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn;
6716 pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
6717- if (is_kernel_text(address))
6718+ if (is_kernel_text(address, address + PAGE_SIZE))
6719 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
6720 else
6721 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
6722@@ -326,9 +327,9 @@ static void __init set_highmem_pages_ini
6723 #define set_highmem_pages_init(bad_ppro) do { } while (0)
6724 #endif /* CONFIG_HIGHMEM */
6725
6726-unsigned long long __PAGE_KERNEL = _PAGE_KERNEL;
6727+unsigned long long __PAGE_KERNEL __read_only = _PAGE_KERNEL;
6728 EXPORT_SYMBOL(__PAGE_KERNEL);
6729-unsigned long long __PAGE_KERNEL_EXEC = _PAGE_KERNEL_EXEC;
6730+unsigned long long __PAGE_KERNEL_EXEC __read_only = _PAGE_KERNEL_EXEC;
6731
6732 #ifdef CONFIG_NUMA
6733 extern void __init remap_numa_kva(void);
6734@@ -339,26 +340,10 @@ extern void __init remap_numa_kva(void);
6735 void __init native_pagetable_setup_start(pgd_t *base)
6736 {
6737 #ifdef CONFIG_X86_PAE
6738- int i;
6739+ unsigned int i;
6740
6741- /*
6742- * Init entries of the first-level page table to the
6743- * zero page, if they haven't already been set up.
6744- *
6745- * In a normal native boot, we'll be running on a
6746- * pagetable rooted in swapper_pg_dir, but not in PAE
6747- * mode, so this will end up clobbering the mappings
6748- * for the lower 24Mbytes of the address space,
6749- * without affecting the kernel address space.
6750- */
6751- for (i = 0; i < USER_PTRS_PER_PGD; i++)
6752- set_pgd(&base[i],
6753- __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
6754-
6755- /* Make sure kernel address space is empty so that a pagetable
6756- will be allocated for it. */
6757- memset(&base[USER_PTRS_PER_PGD], 0,
6758- KERNEL_PGD_PTRS * sizeof(pgd_t));
6759+ for (i = 0; i < PTRS_PER_PGD; i++)
6760+ paravirt_alloc_pd(__pa(swapper_pm_dir + i) >> PAGE_SHIFT);
6761 #else
6762 paravirt_alloc_pd(__pa(swapper_pg_dir) >> PAGE_SHIFT);
6763 #endif
6764@@ -366,16 +351,6 @@ void __init native_pagetable_setup_start
6765
6766 void __init native_pagetable_setup_done(pgd_t *base)
6767 {
6768-#ifdef CONFIG_X86_PAE
6769- /*
6770- * Add low memory identity-mappings - SMP needs it when
6771- * starting up on an AP from real-mode. In the non-PAE
6772- * case we already have these mappings through head.S.
6773- * All user-space mappings are explicitly cleared after
6774- * SMP startup.
6775- */
6776- set_pgd(&base[0], base[USER_PTRS_PER_PGD]);
6777-#endif
6778 }
6779
6780 /*
6781@@ -437,12 +412,12 @@ static void __init pagetable_init (void)
6782 * Swap suspend & friends need this for resume because things like the intel-agp
6783 * driver might have split up a kernel 4MB mapping.
6784 */
6785-char __nosavedata swsusp_pg_dir[PAGE_SIZE]
6786+pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
6787 __attribute__ ((aligned (PAGE_SIZE)));
6788
6789 static inline void save_pg_dir(void)
6790 {
6791- memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
6792+ clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
6793 }
6794 #else
6795 static inline void save_pg_dir(void)
6796@@ -471,8 +446,7 @@ void zap_low_mappings (void)
6797 flush_tlb_all();
6798 }
6799
6800-static int disable_nx __initdata = 0;
6801-u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
6802+u64 __supported_pte_mask __read_only = ~_PAGE_NX;
6803
6804 /*
6805 * noexec = on|off
6806@@ -482,39 +456,34 @@ u64 __supported_pte_mask __read_mostly =
6807 * on Enable
6808 * off Disable
6809 */
6810+#if !defined(CONFIG_PAX_PAGEEXEC)
6811 static int __init noexec_setup(char *str)
6812 {
6813 if (!str || !strcmp(str, "on")) {
6814- if (cpu_has_nx) {
6815- __supported_pte_mask |= _PAGE_NX;
6816- disable_nx = 0;
6817- }
6818+ if (cpu_has_nx)
6819+ nx_enabled = 1;
6820 } else if (!strcmp(str,"off")) {
6821- disable_nx = 1;
6822- __supported_pte_mask &= ~_PAGE_NX;
6823+ nx_enabled = 0;
6824 } else
6825 return -EINVAL;
6826
6827 return 0;
6828 }
6829 early_param("noexec", noexec_setup);
6830+#endif
6831
6832 int nx_enabled = 0;
6833 #ifdef CONFIG_X86_PAE
6834
6835 static void __init set_nx(void)
6836 {
6837- unsigned int v[4], l, h;
6838+ if (!nx_enabled && cpu_has_nx) {
6839+ unsigned l, h;
6840
6841- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
6842- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
6843- if ((v[3] & (1 << 20)) && !disable_nx) {
6844- rdmsr(MSR_EFER, l, h);
6845- l |= EFER_NX;
6846- wrmsr(MSR_EFER, l, h);
6847- nx_enabled = 1;
6848- __supported_pte_mask |= _PAGE_NX;
6849- }
6850+ __supported_pte_mask &= ~_PAGE_NX;
6851+ rdmsr(MSR_EFER, l, h);
6852+ l &= ~EFER_NX;
6853+ wrmsr(MSR_EFER, l, h);
6854 }
6855 }
6856
6857@@ -567,14 +536,6 @@ void __init paging_init(void)
6858
6859 load_cr3(swapper_pg_dir);
6860
6861-#ifdef CONFIG_X86_PAE
6862- /*
6863- * We will bail out later - printk doesn't work right now so
6864- * the user would just see a hanging kernel.
6865- */
6866- if (cpu_has_pae)
6867- set_in_cr4(X86_CR4_PAE);
6868-#endif
6869 __flush_tlb_all();
6870
6871 kmap_init();
6872@@ -645,7 +606,7 @@ void __init mem_init(void)
6873 set_highmem_pages_init(bad_ppro);
6874
6875 codesize = (unsigned long) &_etext - (unsigned long) &_text;
6876- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
6877+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
6878 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
6879
6880 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
6881@@ -690,10 +651,10 @@ void __init mem_init(void)
6882 (unsigned long)&__init_begin, (unsigned long)&__init_end,
6883 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
6884
6885- (unsigned long)&_etext, (unsigned long)&_edata,
6886- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
6887+ (unsigned long)&_data, (unsigned long)&_edata,
6888+ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
6889
6890- (unsigned long)&_text, (unsigned long)&_etext,
6891+ (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
6892 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
6893
6894 #ifdef CONFIG_HIGHMEM
6895@@ -704,10 +665,6 @@ void __init mem_init(void)
6896 BUG_ON((unsigned long)high_memory > VMALLOC_START);
6897 #endif /* double-sanity-check paranoia */
6898
6899-#ifdef CONFIG_X86_PAE
6900- if (!cpu_has_pae)
6901- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
6902-#endif
6903 if (boot_cpu_data.wp_works_ok < 0)
6904 test_wp_bit();
6905
6906@@ -843,6 +800,38 @@ void free_init_pages(char *what, unsigne
6907
6908 void free_initmem(void)
6909 {
6910+
6911+#ifdef CONFIG_PAX_KERNEXEC
6912+ /* PaX: limit KERNEL_CS to actual size */
6913+ unsigned long addr, limit;
6914+ __u32 a, b;
6915+ int cpu;
6916+ pgd_t *pgd;
6917+ pud_t *pud;
6918+ pmd_t *pmd;
6919+
6920+#ifdef CONFIG_MODULES
6921+ limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6922+#else
6923+ limit = (unsigned long)&_etext;
6924+#endif
6925+ limit = (limit - 1UL) >> PAGE_SHIFT;
6926+
6927+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
6928+ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
6929+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
6930+ }
6931+
6932+ /* PaX: make KERNEL_CS read-only */
6933+ for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
6934+ pgd = pgd_offset_k(addr);
6935+ pud = pud_offset(pgd, addr);
6936+ pmd = pmd_offset(pud, addr);
6937+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
6938+ }
6939+ flush_tlb_all();
6940+#endif
6941+
6942 free_init_pages("unused kernel memory",
6943 (unsigned long)(&__init_begin),
6944 (unsigned long)(&__init_end));
6945diff -urNp linux-2.6.22.1/arch/i386/mm/mmap.c linux-2.6.22.1/arch/i386/mm/mmap.c
6946--- linux-2.6.22.1/arch/i386/mm/mmap.c 2007-07-10 14:56:30.000000000 -0400
6947+++ linux-2.6.22.1/arch/i386/mm/mmap.c 2007-08-02 11:38:45.000000000 -0400
6948@@ -35,12 +35,18 @@
6949 * Leave an at least ~128 MB hole.
6950 */
6951 #define MIN_GAP (128*1024*1024)
6952-#define MAX_GAP (TASK_SIZE/6*5)
6953+#define MAX_GAP (task_size/6*5)
6954
6955 static inline unsigned long mmap_base(struct mm_struct *mm)
6956 {
6957 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
6958 unsigned long random_factor = 0;
6959+ unsigned long task_size = TASK_SIZE;
6960+
6961+#ifdef CONFIG_PAX_SEGMEXEC
6962+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6963+ task_size = SEGMEXEC_TASK_SIZE;
6964+#endif
6965
6966 if (current->flags & PF_RANDOMIZE)
6967 random_factor = get_random_int() % (1024*1024);
6968@@ -50,7 +56,7 @@ static inline unsigned long mmap_base(st
6969 else if (gap > MAX_GAP)
6970 gap = MAX_GAP;
6971
6972- return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
6973+ return PAGE_ALIGN(task_size - gap - random_factor);
6974 }
6975
6976 /*
6977@@ -66,11 +72,30 @@ void arch_pick_mmap_layout(struct mm_str
6978 if (sysctl_legacy_va_layout ||
6979 (current->personality & ADDR_COMPAT_LAYOUT) ||
6980 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
6981+
6982+#ifdef CONFIG_PAX_SEGMEXEC
6983+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
6984+ mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6985+ else
6986+#endif
6987+
6988 mm->mmap_base = TASK_UNMAPPED_BASE;
6989+
6990+#ifdef CONFIG_PAX_RANDMMAP
6991+ if (mm->pax_flags & MF_PAX_RANDMMAP)
6992+ mm->mmap_base += mm->delta_mmap;
6993+#endif
6994+
6995 mm->get_unmapped_area = arch_get_unmapped_area;
6996 mm->unmap_area = arch_unmap_area;
6997 } else {
6998 mm->mmap_base = mmap_base(mm);
6999+
7000+#ifdef CONFIG_PAX_RANDMMAP
7001+ if (mm->pax_flags & MF_PAX_RANDMMAP)
7002+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7003+#endif
7004+
7005 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7006 mm->unmap_area = arch_unmap_area_topdown;
7007 }
7008diff -urNp linux-2.6.22.1/arch/i386/mm/pageattr.c linux-2.6.22.1/arch/i386/mm/pageattr.c
7009--- linux-2.6.22.1/arch/i386/mm/pageattr.c 2007-07-10 14:56:30.000000000 -0400
7010+++ linux-2.6.22.1/arch/i386/mm/pageattr.c 2007-08-02 11:38:45.000000000 -0400
7011@@ -13,6 +13,7 @@
7012 #include <asm/tlbflush.h>
7013 #include <asm/pgalloc.h>
7014 #include <asm/sections.h>
7015+#include <asm/desc.h>
7016
7017 static DEFINE_SPINLOCK(cpa_lock);
7018 static struct list_head df_list = LIST_HEAD_INIT(df_list);
7019@@ -37,16 +38,16 @@ pte_t *lookup_address(unsigned long addr
7020 }
7021
7022 static struct page *split_large_page(unsigned long address, pgprot_t prot,
7023- pgprot_t ref_prot)
7024+ pgprot_t ref_prot, unsigned long flags)
7025 {
7026 int i;
7027 unsigned long addr;
7028 struct page *base;
7029 pte_t *pbase;
7030
7031- spin_unlock_irq(&cpa_lock);
7032+ spin_unlock_irqrestore(&cpa_lock, flags);
7033 base = alloc_pages(GFP_KERNEL, 0);
7034- spin_lock_irq(&cpa_lock);
7035+ spin_lock_irqsave(&cpa_lock, flags);
7036 if (!base)
7037 return NULL;
7038
7039@@ -99,7 +100,18 @@ static void set_pmd_pte(pte_t *kpte, uns
7040 struct page *page;
7041 unsigned long flags;
7042
7043+#ifdef CONFIG_PAX_KERNEXEC
7044+ unsigned long cr0;
7045+
7046+ pax_open_kernel(cr0);
7047+#endif
7048+
7049 set_pte_atomic(kpte, pte); /* change init_mm */
7050+
7051+#ifdef CONFIG_PAX_KERNEXEC
7052+ pax_close_kernel(cr0);
7053+#endif
7054+
7055 if (SHARED_KERNEL_PMD)
7056 return;
7057
7058@@ -126,7 +138,7 @@ static inline void revert_page(struct pa
7059 pte_t *linear;
7060
7061 ref_prot =
7062- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
7063+ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
7064 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
7065
7066 linear = (pte_t *)
7067@@ -137,7 +149,7 @@ static inline void revert_page(struct pa
7068 }
7069
7070 static int
7071-__change_page_attr(struct page *page, pgprot_t prot)
7072+__change_page_attr(struct page *page, pgprot_t prot, unsigned long flags)
7073 {
7074 pte_t *kpte;
7075 unsigned long address;
7076@@ -158,13 +170,20 @@ __change_page_attr(struct page *page, pg
7077 struct page *split;
7078
7079 ref_prot =
7080- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
7081+ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
7082 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
7083- split = split_large_page(address, prot, ref_prot);
7084+ split = split_large_page(address, prot, ref_prot, flags);
7085 if (!split)
7086 return -ENOMEM;
7087- set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
7088- kpte_page = split;
7089+ if (pte_huge(*kpte)) {
7090+ set_pmd_pte(kpte,address,mk_pte(split, ref_prot));
7091+ kpte_page = split;
7092+ } else {
7093+ __free_pages(split, 0);
7094+ kpte = lookup_address(address);
7095+ kpte_page = virt_to_page(kpte);
7096+ set_pte_atomic(kpte, mk_pte(page, prot));
7097+ }
7098 }
7099 page_private(kpte_page)++;
7100 } else if (!pte_huge(*kpte)) {
7101@@ -216,7 +235,7 @@ int change_page_attr(struct page *page,
7102
7103 spin_lock_irqsave(&cpa_lock, flags);
7104 for (i = 0; i < numpages; i++, page++) {
7105- err = __change_page_attr(page, prot);
7106+ err = __change_page_attr(page, prot, flags);
7107 if (err)
7108 break;
7109 }
7110diff -urNp linux-2.6.22.1/arch/i386/oprofile/backtrace.c linux-2.6.22.1/arch/i386/oprofile/backtrace.c
7111--- linux-2.6.22.1/arch/i386/oprofile/backtrace.c 2007-07-10 14:56:30.000000000 -0400
7112+++ linux-2.6.22.1/arch/i386/oprofile/backtrace.c 2007-08-02 11:38:45.000000000 -0400
7113@@ -22,7 +22,7 @@ struct frame_head {
7114 static struct frame_head *
7115 dump_kernel_backtrace(struct frame_head * head)
7116 {
7117- oprofile_add_trace(head->ret);
7118+ oprofile_add_trace(head->ret + __KERNEL_TEXT_OFFSET);
7119
7120 /* frame pointers should strictly progress back up the stack
7121 * (towards higher addresses) */
7122@@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
7123 head = (struct frame_head *)regs->ebp;
7124 #endif
7125
7126- if (!user_mode_vm(regs)) {
7127+ if (!user_mode(regs)) {
7128 while (depth-- && valid_kernel_stack(head, regs))
7129 head = dump_kernel_backtrace(head);
7130 return;
7131diff -urNp linux-2.6.22.1/arch/i386/oprofile/op_model_p4.c linux-2.6.22.1/arch/i386/oprofile/op_model_p4.c
7132--- linux-2.6.22.1/arch/i386/oprofile/op_model_p4.c 2007-07-10 14:56:30.000000000 -0400
7133+++ linux-2.6.22.1/arch/i386/oprofile/op_model_p4.c 2007-08-02 11:38:45.000000000 -0400
7134@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
7135 #endif
7136 }
7137
7138-static int inline addr_increment(void)
7139+static inline int addr_increment(void)
7140 {
7141 #ifdef CONFIG_SMP
7142 return smp_num_siblings == 2 ? 2 : 1;
7143diff -urNp linux-2.6.22.1/arch/i386/pci/common.c linux-2.6.22.1/arch/i386/pci/common.c
7144--- linux-2.6.22.1/arch/i386/pci/common.c 2007-07-10 14:56:30.000000000 -0400
7145+++ linux-2.6.22.1/arch/i386/pci/common.c 2007-08-02 11:38:45.000000000 -0400
7146@@ -287,7 +287,7 @@ static struct dmi_system_id __devinitdat
7147 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
7148 },
7149 },
7150- {}
7151+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
7152 };
7153
7154 struct pci_bus * __devinit pcibios_scan_root(int busnum)
7155diff -urNp linux-2.6.22.1/arch/i386/pci/early.c linux-2.6.22.1/arch/i386/pci/early.c
7156--- linux-2.6.22.1/arch/i386/pci/early.c 2007-07-10 14:56:30.000000000 -0400
7157+++ linux-2.6.22.1/arch/i386/pci/early.c 2007-08-02 11:38:45.000000000 -0400
7158@@ -7,7 +7,7 @@
7159 /* Direct PCI access. This is used for PCI accesses in early boot before
7160 the PCI subsystem works. */
7161
7162-#define PDprintk(x...)
7163+#define PDprintk(x...) do {} while (0)
7164
7165 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
7166 {
7167diff -urNp linux-2.6.22.1/arch/i386/pci/fixup.c linux-2.6.22.1/arch/i386/pci/fixup.c
7168--- linux-2.6.22.1/arch/i386/pci/fixup.c 2007-07-10 14:56:30.000000000 -0400
7169+++ linux-2.6.22.1/arch/i386/pci/fixup.c 2007-08-02 11:38:45.000000000 -0400
7170@@ -389,7 +389,7 @@ static struct dmi_system_id __devinitdat
7171 DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
7172 },
7173 },
7174- { }
7175+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7176 };
7177
7178 static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
7179diff -urNp linux-2.6.22.1/arch/i386/pci/irq.c linux-2.6.22.1/arch/i386/pci/irq.c
7180--- linux-2.6.22.1/arch/i386/pci/irq.c 2007-07-10 14:56:30.000000000 -0400
7181+++ linux-2.6.22.1/arch/i386/pci/irq.c 2007-08-02 11:38:45.000000000 -0400
7182@@ -507,7 +507,7 @@ static __init int intel_router_probe(str
7183 static struct pci_device_id __initdata pirq_440gx[] = {
7184 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
7185 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
7186- { },
7187+ { PCI_DEVICE(0, 0) }
7188 };
7189
7190 /* 440GX has a proprietary PIRQ router -- don't use it */
7191@@ -1049,7 +1049,7 @@ static struct dmi_system_id __initdata p
7192 DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
7193 },
7194 },
7195- { }
7196+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
7197 };
7198
7199 static int __init pcibios_irq_init(void)
7200diff -urNp linux-2.6.22/arch/i386/pci/pcbios.c linux-2.6.22/arch/i386/pci/pcbios.c
7201--- linux-2.6.22/arch/i386/pci/pcbios.c 2007-07-10 14:56:30.000000000 -0400
7202+++ linux-2.6.22/arch/i386/pci/pcbios.c 2007-07-10 14:56:30.000000000 -0400
7203@@ -57,50 +57,120 @@ union bios32 {
7204 static struct {
7205 unsigned long address;
7206 unsigned short segment;
7207-} bios32_indirect = { 0, __KERNEL_CS };
7208+} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
7209
7210 /*
7211 * Returns the entry point for the given service, NULL on error
7212 */
7213
7214-static unsigned long bios32_service(unsigned long service)
7215+static unsigned long __devinit bios32_service(unsigned long service)
7216 {
7217 unsigned char return_code; /* %al */
7218 unsigned long address; /* %ebx */
7219 unsigned long length; /* %ecx */
7220 unsigned long entry; /* %edx */
7221 unsigned long flags;
7222+ struct desc_struct *gdt;
7223+
7224+#ifdef CONFIG_PAX_KERNEXEC
7225+ unsigned long cr0;
7226+#endif
7227
7228 local_irq_save(flags);
7229- __asm__("lcall *(%%edi); cld"
7230+
7231+ gdt = get_cpu_gdt_table(smp_processor_id());
7232+
7233+#ifdef CONFIG_PAX_KERNEXEC
7234+ pax_open_kernel(cr0);
7235+#endif
7236+
7237+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
7238+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
7239+ 0UL, 0xFFFFFUL, 0x9B, 0xC);
7240+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
7241+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
7242+ 0UL, 0xFFFFFUL, 0x93, 0xC);
7243+
7244+#ifdef CONFIG_PAX_KERNEXEC
7245+ pax_close_kernel(cr0);
7246+#endif
7247+
7248+ __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
7249 : "=a" (return_code),
7250 "=b" (address),
7251 "=c" (length),
7252 "=d" (entry)
7253 : "0" (service),
7254 "1" (0),
7255- "D" (&bios32_indirect));
7256+ "D" (&bios32_indirect),
7257+ "r"(__PCIBIOS_DS)
7258+ : "memory");
7259+
7260+#ifdef CONFIG_PAX_KERNEXEC
7261+ pax_open_kernel(cr0);
7262+#endif
7263+
7264+ gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
7265+ gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
7266+ gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
7267+ gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
7268+
7269+#ifdef CONFIG_PAX_KERNEXEC
7270+ pax_close_kernel(cr0);
7271+#endif
7272+
7273 local_irq_restore(flags);
7274
7275 switch (return_code) {
7276- case 0:
7277- return address + entry;
7278- case 0x80: /* Not present */
7279- printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
7280- return 0;
7281- default: /* Shouldn't happen */
7282- printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
7283- service, return_code);
7284- return 0;
7285+ case 0: {
7286+ int cpu;
7287+ unsigned char flags;
7288+
7289+ printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
7290+ address = address + PAGE_OFFSET;
7291+ length += 16UL; /* some BIOSs underreport this... */
7292+ flags = 4;
7293+ if (length >= 64*1024*1024) {
7294+ length >>= PAGE_SHIFT;
7295+ flags |= 8;
7296+ }
7297+
7298+#ifdef CONFIG_PAX_KERNEXEC
7299+ pax_open_kernel(cr0);
7300+#endif
7301+
7302+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
7303+ gdt = get_cpu_gdt_table(cpu);
7304+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].a,
7305+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_CS].b,
7306+ address, length, 0x9b, flags);
7307+ pack_descriptor((__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].a,
7308+ (__u32 *)&gdt[GDT_ENTRY_PCIBIOS_DS].b,
7309+ address, length, 0x93, flags);
7310+ }
7311+
7312+#ifdef CONFIG_PAX_KERNEXEC
7313+ pax_close_kernel(cr0);
7314+#endif
7315+
7316+ return entry;
7317+ }
7318+ case 0x80: /* Not present */
7319+ printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
7320+ return 0;
7321+ default: /* Shouldn't happen */
7322+ printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
7323+ service, return_code);
7324+ return 0;
7325 }
7326 }
7327
7328 static struct {
7329 unsigned long address;
7330 unsigned short segment;
7331-} pci_indirect = { 0, __KERNEL_CS };
7332+} pci_indirect __read_only = { 0, __PCIBIOS_CS };
7333
7334-static int pci_bios_present;
7335+static int pci_bios_present __read_only;
7336
7337 static int __devinit check_pcibios(void)
7338 {
7339@@ -109,11 +178,13 @@ static int __devinit check_pcibios(void)
7340 unsigned long flags, pcibios_entry;
7341
7342 if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
7343- pci_indirect.address = pcibios_entry + PAGE_OFFSET;
7344+ pci_indirect.address = pcibios_entry;
7345
7346 local_irq_save(flags);
7347- __asm__(
7348- "lcall *(%%edi); cld\n\t"
7349+ __asm__("movw %w6, %%ds\n\t"
7350+ "lcall *%%ss:(%%edi); cld\n\t"
7351+ "push %%ss\n\t"
7352+ "pop %%ds\n\t"
7353 "jc 1f\n\t"
7354 "xor %%ah, %%ah\n"
7355 "1:"
7356@@ -122,7 +193,8 @@ static int __devinit check_pcibios(void)
7357 "=b" (ebx),
7358 "=c" (ecx)
7359 : "1" (PCIBIOS_PCI_BIOS_PRESENT),
7360- "D" (&pci_indirect)
7361+ "D" (&pci_indirect),
7362+ "r" (__PCIBIOS_DS)
7363 : "memory");
7364 local_irq_restore(flags);
7365
7366@@ -158,7 +230,10 @@ static int __devinit pci_bios_find_devic
7367 unsigned short bx;
7368 unsigned short ret;
7369
7370- __asm__("lcall *(%%edi); cld\n\t"
7371+ __asm__("movw %w7, %%ds\n\t"
7372+ "lcall *%%ss:(%%edi); cld\n\t"
7373+ "push %%ss\n\t"
7374+ "pop %%ds\n\t"
7375 "jc 1f\n\t"
7376 "xor %%ah, %%ah\n"
7377 "1:"
7378@@ -168,7 +243,8 @@ static int __devinit pci_bios_find_devic
7379 "c" (device_id),
7380 "d" (vendor),
7381 "S" ((int) index),
7382- "D" (&pci_indirect));
7383+ "D" (&pci_indirect),
7384+ "r" (__PCIBIOS_DS));
7385 *bus = (bx >> 8) & 0xff;
7386 *device_fn = bx & 0xff;
7387 return (int) (ret & 0xff00) >> 8;
7388@@ -188,7 +264,10 @@ static int pci_bios_read(unsigned int se
7389
7390 switch (len) {
7391 case 1:
7392- __asm__("lcall *(%%esi); cld\n\t"
7393+ __asm__("movw %w6, %%ds\n\t"
7394+ "lcall *%%ss:(%%esi); cld\n\t"
7395+ "push %%ss\n\t"
7396+ "pop %%ds\n\t"
7397 "jc 1f\n\t"
7398 "xor %%ah, %%ah\n"
7399 "1:"
7400@@ -197,10 +276,14 @@ static int pci_bios_read(unsigned int se
7401 : "1" (PCIBIOS_READ_CONFIG_BYTE),
7402 "b" (bx),
7403 "D" ((long)reg),
7404- "S" (&pci_indirect));
7405+ "S" (&pci_indirect),
7406+ "r" (__PCIBIOS_DS));
7407 break;
7408 case 2:
7409- __asm__("lcall *(%%esi); cld\n\t"
7410+ __asm__("movw %w6, %%ds\n\t"
7411+ "lcall *%%ss:(%%esi); cld\n\t"
7412+ "push %%ss\n\t"
7413+ "pop %%ds\n\t"
7414 "jc 1f\n\t"
7415 "xor %%ah, %%ah\n"
7416 "1:"
7417@@ -209,10 +292,14 @@ static int pci_bios_read(unsigned int se
7418 : "1" (PCIBIOS_READ_CONFIG_WORD),
7419 "b" (bx),
7420 "D" ((long)reg),
7421- "S" (&pci_indirect));
7422+ "S" (&pci_indirect),
7423+ "r" (__PCIBIOS_DS));
7424 break;
7425 case 4:
7426- __asm__("lcall *(%%esi); cld\n\t"
7427+ __asm__("movw %w6, %%ds\n\t"
7428+ "lcall *%%ss:(%%esi); cld\n\t"
7429+ "push %%ss\n\t"
7430+ "pop %%ds\n\t"
7431 "jc 1f\n\t"
7432 "xor %%ah, %%ah\n"
7433 "1:"
7434@@ -221,7 +308,8 @@ static int pci_bios_read(unsigned int se
7435 : "1" (PCIBIOS_READ_CONFIG_DWORD),
7436 "b" (bx),
7437 "D" ((long)reg),
7438- "S" (&pci_indirect));
7439+ "S" (&pci_indirect),
7440+ "r" (__PCIBIOS_DS));
7441 break;
7442 }
7443
7444@@ -244,7 +332,10 @@ static int pci_bios_write(unsigned int s
7445
7446 switch (len) {
7447 case 1:
7448- __asm__("lcall *(%%esi); cld\n\t"
7449+ __asm__("movw %w6, %%ds\n\t"
7450+ "lcall *%%ss:(%%esi); cld\n\t"
7451+ "push %%ss\n\t"
7452+ "pop %%ds\n\t"
7453 "jc 1f\n\t"
7454 "xor %%ah, %%ah\n"
7455 "1:"
7456@@ -253,10 +344,14 @@ static int pci_bios_write(unsigned int s
7457 "c" (value),
7458 "b" (bx),
7459 "D" ((long)reg),
7460- "S" (&pci_indirect));
7461+ "S" (&pci_indirect),
7462+ "r" (__PCIBIOS_DS));
7463 break;
7464 case 2:
7465- __asm__("lcall *(%%esi); cld\n\t"
7466+ __asm__("movw %w6, %%ds\n\t"
7467+ "lcall *%%ss:(%%esi); cld\n\t"
7468+ "push %%ss\n\t"
7469+ "pop %%ds\n\t"
7470 "jc 1f\n\t"
7471 "xor %%ah, %%ah\n"
7472 "1:"
7473@@ -265,10 +360,14 @@ static int pci_bios_write(unsigned int s
7474 "c" (value),
7475 "b" (bx),
7476 "D" ((long)reg),
7477- "S" (&pci_indirect));
7478+ "S" (&pci_indirect),
7479+ "r" (__PCIBIOS_DS));
7480 break;
7481 case 4:
7482- __asm__("lcall *(%%esi); cld\n\t"
7483+ __asm__("movw %w6, %%ds\n\t"
7484+ "lcall *%%ss:(%%esi); cld\n\t"
7485+ "push %%ss\n\t"
7486+ "pop %%ds\n\t"
7487 "jc 1f\n\t"
7488 "xor %%ah, %%ah\n"
7489 "1:"
7490@@ -277,7 +376,8 @@ static int pci_bios_write(unsigned int s
7491 "c" (value),
7492 "b" (bx),
7493 "D" ((long)reg),
7494- "S" (&pci_indirect));
7495+ "S" (&pci_indirect),
7496+ "r" (__PCIBIOS_DS));
7497 break;
7498 }
7499
7500@@ -430,10 +530,13 @@ struct irq_routing_table * __devinit pci
7501
7502 DBG("PCI: Fetching IRQ routing table... ");
7503 __asm__("push %%es\n\t"
7504+ "movw %w8, %%ds\n\t"
7505 "push %%ds\n\t"
7506 "pop %%es\n\t"
7507- "lcall *(%%esi); cld\n\t"
7508+ "lcall *%%ss:(%%esi); cld\n\t"
7509 "pop %%es\n\t"
7510+ "push %%ss\n\t"
7511+ "pop %%ds\n"
7512 "jc 1f\n\t"
7513 "xor %%ah, %%ah\n"
7514 "1:"
7515@@ -444,7 +547,8 @@ struct irq_routing_table * __devinit pci
7516 "1" (0),
7517 "D" ((long) &opt),
7518 "S" (&pci_indirect),
7519- "m" (opt)
7520+ "m" (opt),
7521+ "r" (__PCIBIOS_DS)
7522 : "memory");
7523 DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
7524 if (ret & 0xff00)
7525@@ -468,7 +572,10 @@ int pcibios_set_irq_routing(struct pci_d
7526 {
7527 int ret;
7528
7529- __asm__("lcall *(%%esi); cld\n\t"
7530+ __asm__("movw %w5, %%ds\n\t"
7531+ "lcall *%%ss:(%%esi); cld\n\t"
7532+ "push %%ss\n\t"
7533+ "pop %%ds\n"
7534 "jc 1f\n\t"
7535 "xor %%ah, %%ah\n"
7536 "1:"
7537@@ -476,7 +583,8 @@ int pcibios_set_irq_routing(struct pci_d
7538 : "0" (PCIBIOS_SET_PCI_HW_INT),
7539 "b" ((dev->bus->number << 8) | dev->devfn),
7540 "c" ((irq << 8) | (pin + 10)),
7541- "S" (&pci_indirect));
7542+ "S" (&pci_indirect),
7543+ "r" (__PCIBIOS_DS));
7544 return !(ret & 0xff00);
7545 }
7546 EXPORT_SYMBOL(pcibios_set_irq_routing);
7547diff -urNp linux-2.6.22.1/arch/i386/power/cpu.c linux-2.6.22.1/arch/i386/power/cpu.c
7548--- linux-2.6.22.1/arch/i386/power/cpu.c 2007-07-10 14:56:30.000000000 -0400
7549+++ linux-2.6.22.1/arch/i386/power/cpu.c 2007-08-02 11:38:45.000000000 -0400
7550@@ -64,7 +64,7 @@ static void do_fpu_end(void)
7551 static void fix_processor_context(void)
7552 {
7553 int cpu = smp_processor_id();
7554- struct tss_struct * t = &per_cpu(init_tss, cpu);
7555+ struct tss_struct *t = init_tss + cpu;
7556
7557 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. */
7558
7559diff -urNp linux-2.6.22.1/arch/ia64/ia32/binfmt_elf32.c linux-2.6.22.1/arch/ia64/ia32/binfmt_elf32.c
7560--- linux-2.6.22.1/arch/ia64/ia32/binfmt_elf32.c 2007-07-10 14:56:30.000000000 -0400
7561+++ linux-2.6.22.1/arch/ia64/ia32/binfmt_elf32.c 2007-08-02 11:38:45.000000000 -0400
7562@@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
7563
7564 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
7565
7566+#ifdef CONFIG_PAX_ASLR
7567+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
7568+
7569+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
7570+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
7571+#endif
7572+
7573 /* Ugly but avoids duplication */
7574 #include "../../../fs/binfmt_elf.c"
7575
7576@@ -226,8 +233,20 @@ ia32_setup_arg_pages (struct linux_binpr
7577 mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
7578 else
7579 mpnt->vm_flags = VM_STACK_FLAGS;
7580- mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC)?
7581- PAGE_COPY_EXEC: PAGE_COPY;
7582+
7583+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
b5630f59 7584+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
3ba9fddb 7585+ mpnt->vm_flags &= ~VM_EXEC;
7586+
7587+#ifdef CONFIG_PAX_MPROTECT
7588+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
7589+ mpnt->vm_flags &= ~VM_MAYEXEC;
7590+#endif
7591+
7592+ }
7593+#endif
7594+
7595+ mpnt->vm_page_prot = vm_get_page_prot(mpnt->vm_flags);
7596 if ((ret = insert_vm_struct(current->mm, mpnt))) {
7597 up_write(&current->mm->mmap_sem);
7598 kmem_cache_free(vm_area_cachep, mpnt);
7599diff -urNp linux-2.6.22.1/arch/ia64/ia32/ia32priv.h linux-2.6.22.1/arch/ia64/ia32/ia32priv.h
7600--- linux-2.6.22.1/arch/ia64/ia32/ia32priv.h 2007-07-10 14:56:30.000000000 -0400
7601+++ linux-2.6.22.1/arch/ia64/ia32/ia32priv.h 2007-08-02 11:38:45.000000000 -0400
7602@@ -304,7 +304,14 @@ struct old_linux32_dirent {
7603 #define ELF_DATA ELFDATA2LSB
7604 #define ELF_ARCH EM_386
7605
7606-#define IA32_STACK_TOP IA32_PAGE_OFFSET
7607+#ifdef CONFIG_PAX_RANDUSTACK
7608+#define __IA32_DELTA_STACK (current->mm->delta_stack)
7609+#else
7610+#define __IA32_DELTA_STACK 0UL
7611+#endif
7612+
7613+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
7614+
7615 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
7616 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
7617
7618diff -urNp linux-2.6.22.1/arch/ia64/kernel/module.c linux-2.6.22.1/arch/ia64/kernel/module.c
7619--- linux-2.6.22.1/arch/ia64/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
7620+++ linux-2.6.22.1/arch/ia64/kernel/module.c 2007-08-02 11:38:45.000000000 -0400
7621@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
7622 void
7623 module_free (struct module *mod, void *module_region)
7624 {
7625- if (mod->arch.init_unw_table && module_region == mod->module_init) {
7626+ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
7627 unw_remove_unwind_table(mod->arch.init_unw_table);
7628 mod->arch.init_unw_table = NULL;
7629 }
7630@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
7631 }
7632
7633 static inline int
7634+in_init_rx (const struct module *mod, uint64_t addr)
7635+{
7636+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
7637+}
7638+
7639+static inline int
7640+in_init_rw (const struct module *mod, uint64_t addr)
7641+{
7642+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
7643+}
7644+
7645+static inline int
7646 in_init (const struct module *mod, uint64_t addr)
7647 {
7648- return addr - (uint64_t) mod->module_init < mod->init_size;
7649+ return in_init_rx(mod, value) || in_init_rw(mod, value);
7650+}
7651+
7652+static inline int
7653+in_core_rx (const struct module *mod, uint64_t addr)
7654+{
7655+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
7656+}
7657+
7658+static inline int
7659+in_core_rw (const struct module *mod, uint64_t addr)
7660+{
7661+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
7662 }
7663
7664 static inline int
7665 in_core (const struct module *mod, uint64_t addr)
7666 {
7667- return addr - (uint64_t) mod->module_core < mod->core_size;
7668+ return in_core_rx(mod, value) || in_core_rw(mod, value);
7669 }
7670
7671 static inline int
7672@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
7673 break;
7674
7675 case RV_BDREL:
7676- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
7677+ if (in_init_rx(mod, val))
7678+ val -= (uint64_t) mod->module_init_rx;
7679+ else if (in_init_rw(mod, val))
7680+ val -= (uint64_t) mod->module_init_rw;
7681+ else if (in_core_rx(mod, val))
7682+ val -= (uint64_t) mod->module_core_rx;
7683+ else if (in_core_rw(mod, val))
7684+ val -= (uint64_t) mod->module_core_rw;
7685 break;
7686
7687 case RV_LTV:
7688@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
7689 * addresses have been selected...
7690 */
7691 uint64_t gp;
7692- if (mod->core_size > MAX_LTOFF)
7693+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
7694 /*
7695 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
7696 * at the end of the module.
7697 */
7698- gp = mod->core_size - MAX_LTOFF / 2;
7699+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
7700 else
7701- gp = mod->core_size / 2;
7702- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
7703+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
7704+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
7705 mod->arch.gp = gp;
7706 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
7707 }
7708diff -urNp linux-2.6.22.1/arch/ia64/kernel/ptrace.c linux-2.6.22.1/arch/ia64/kernel/ptrace.c
7709--- linux-2.6.22.1/arch/ia64/kernel/ptrace.c 2007-07-10 14:56:30.000000000 -0400
7710+++ linux-2.6.22.1/arch/ia64/kernel/ptrace.c 2007-08-02 11:09:14.000000000 -0400
7711@@ -18,6 +18,7 @@
7712 #include <linux/audit.h>
7713 #include <linux/signal.h>
7714 #include <linux/vs_base.h>
7715+#include <linux/grsecurity.h>
7716
7717 #include <asm/pgtable.h>
7718 #include <asm/processor.h>
7719@@ -1447,6 +1448,9 @@ sys_ptrace (long request, pid_t pid, uns
7720 if (pid == 1) /* no messing around with init! */
7721 goto out_tsk;
7722
7723+ if (gr_handle_ptrace(child, request))
7724+ goto out_tsk;
7725+
7726 if (request == PTRACE_ATTACH) {
7727 ret = ptrace_attach(child);
7728 goto out_tsk;
7729diff -urNp linux-2.6.22.1/arch/ia64/kernel/sys_ia64.c linux-2.6.22.1/arch/ia64/kernel/sys_ia64.c
7730--- linux-2.6.22.1/arch/ia64/kernel/sys_ia64.c 2007-07-10 14:56:30.000000000 -0400
7731+++ linux-2.6.22.1/arch/ia64/kernel/sys_ia64.c 2007-08-02 11:38:45.000000000 -0400
7732@@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
7733 if (REGION_NUMBER(addr) == RGN_HPAGE)
7734 addr = 0;
7735 #endif
7736+
7737+#ifdef CONFIG_PAX_RANDMMAP
7738+ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
7739+ addr = mm->free_area_cache;
7740+ else
7741+#endif
7742+
7743 if (!addr)
7744 addr = mm->free_area_cache;
7745
7746@@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
7747 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
7748 /* At this point: (!vma || addr < vma->vm_end). */
7749 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
7750- if (start_addr != TASK_UNMAPPED_BASE) {
7751+ if (start_addr != mm->mmap_base) {
7752 /* Start a new search --- just in case we missed some holes. */
7753- addr = TASK_UNMAPPED_BASE;
7754+ addr = mm->mmap_base;
7755 goto full_search;
7756 }
7757 return -ENOMEM;
7758diff -urNp linux-2.6.22.1/arch/ia64/mm/fault.c linux-2.6.22.1/arch/ia64/mm/fault.c
7759--- linux-2.6.22.1/arch/ia64/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
7760+++ linux-2.6.22.1/arch/ia64/mm/fault.c 2007-08-02 11:38:45.000000000 -0400
7761@@ -11,6 +11,7 @@
7762 #include <linux/kprobes.h>
7763 #include <linux/kdebug.h>
7764 #include <linux/vs_memory.h>
7765+#include <linux/binfmts.h>
7766
7767 #include <asm/pgtable.h>
7768 #include <asm/processor.h>
7769@@ -72,6 +73,23 @@ mapped_kernel_page_is_present (unsigned
7770 return pte_present(pte);
7771 }
7772
7773+#ifdef CONFIG_PAX_PAGEEXEC
7774+void pax_report_insns(void *pc, void *sp)
7775+{
7776+ unsigned long i;
7777+
7778+ printk(KERN_ERR "PAX: bytes at PC: ");
7779+ for (i = 0; i < 8; i++) {
7780+ unsigned int c;
7781+ if (get_user(c, (unsigned int *)pc+i))
7782+ printk("???????? ");
7783+ else
7784+ printk("%08x ", c);
7785+ }
7786+ printk("\n");
7787+}
7788+#endif
7789+
7790 void __kprobes
7791 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
7792 {
7793@@ -138,9 +156,23 @@ ia64_do_page_fault (unsigned long addres
7794 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
7795 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
7796
7797- if ((vma->vm_flags & mask) != mask)
7798+ if ((vma->vm_flags & mask) != mask) {
7799+
7800+#ifdef CONFIG_PAX_PAGEEXEC
7801+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
7802+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
7803+ goto bad_area;
7804+
7805+ up_read(&mm->mmap_sem);
7806+ pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
7807+ do_exit(SIGKILL);
7808+ }
7809+#endif
7810+
7811 goto bad_area;
7812
7813+ }
7814+
7815 survive:
7816 /*
7817 * If for any reason at all we couldn't handle the fault, make
7818diff -urNp linux-2.6.22.1/arch/ia64/mm/init.c linux-2.6.22.1/arch/ia64/mm/init.c
7819--- linux-2.6.22.1/arch/ia64/mm/init.c 2007-07-10 14:56:30.000000000 -0400
7820+++ linux-2.6.22.1/arch/ia64/mm/init.c 2007-08-02 11:38:45.000000000 -0400
7821@@ -20,8 +20,8 @@
7822 #include <linux/proc_fs.h>
7823 #include <linux/bitops.h>
7824 #include <linux/kexec.h>
7825+#include <linux/a.out.h>
7826
7827-#include <asm/a.out.h>
7828 #include <asm/dma.h>
7829 #include <asm/ia32.h>
7830 #include <asm/io.h>
7831@@ -130,8 +130,21 @@ ia64_init_addr_space (void)
7832 vma->vm_mm = current->mm;
7833 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
7834 vma->vm_end = vma->vm_start + PAGE_SIZE;
7835- vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
7836 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
7837+
7838+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
7839+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
7840+ vma->vm_flags &= ~VM_EXEC;
7841+
7842+#ifdef CONFIG_PAX_MPROTECT
7843+ if (current->mm->pax_flags & MF_PAX_MPROTECT)
7844+ vma->vm_flags &= ~VM_MAYEXEC;
7845+#endif
7846+
7847+ }
7848+#endif
7849+
7850+ vma->vm_page_prot = vm_get_page_prot(VM_DATA_DEFAULT_FLAGS);
7851 down_write(&current->mm->mmap_sem);
7852 if (insert_vm_struct(current->mm, vma)) {
7853 up_write(&current->mm->mmap_sem);
7854diff -urNp linux-2.6.22.1/arch/mips/kernel/binfmt_elfn32.c linux-2.6.22.1/arch/mips/kernel/binfmt_elfn32.c
7855--- linux-2.6.22.1/arch/mips/kernel/binfmt_elfn32.c 2007-07-10 14:56:30.000000000 -0400
7856+++ linux-2.6.22.1/arch/mips/kernel/binfmt_elfn32.c 2007-08-02 11:38:45.000000000 -0400
7857@@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
7858 #undef ELF_ET_DYN_BASE
7859 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
7860
7861+#ifdef CONFIG_PAX_ASLR
7862+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
7863+
7864+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7865+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7866+#endif
7867+
7868 #include <asm/processor.h>
7869 #include <linux/module.h>
7870 #include <linux/elfcore.h>
7871diff -urNp linux-2.6.22.1/arch/mips/kernel/binfmt_elfo32.c linux-2.6.22.1/arch/mips/kernel/binfmt_elfo32.c
7872--- linux-2.6.22.1/arch/mips/kernel/binfmt_elfo32.c 2007-07-10 14:56:30.000000000 -0400
7873+++ linux-2.6.22.1/arch/mips/kernel/binfmt_elfo32.c 2007-08-02 11:38:45.000000000 -0400
7874@@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
7875 #undef ELF_ET_DYN_BASE
7876 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
7877
7878+#ifdef CONFIG_PAX_ASLR
7879+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
7880+
7881+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7882+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7883+#endif
7884+
7885 #include <asm/processor.h>
7886 #include <linux/module.h>
7887 #include <linux/elfcore.h>
7888diff -urNp linux-2.6.22.1/arch/mips/kernel/syscall.c linux-2.6.22.1/arch/mips/kernel/syscall.c
7889--- linux-2.6.22.1/arch/mips/kernel/syscall.c 2007-07-10 14:56:30.000000000 -0400
7890+++ linux-2.6.22.1/arch/mips/kernel/syscall.c 2007-08-02 11:38:45.000000000 -0400
7891@@ -87,6 +87,11 @@ unsigned long arch_get_unmapped_area(str
7892 do_color_align = 0;
7893 if (filp || (flags & MAP_SHARED))
7894 do_color_align = 1;
7895+
7896+#ifdef CONFIG_PAX_RANDMMAP
7897+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7898+#endif
7899+
7900 if (addr) {
7901 if (do_color_align)
7902 addr = COLOUR_ALIGN(addr, pgoff);
7903@@ -97,7 +102,7 @@ unsigned long arch_get_unmapped_area(str
7904 (!vmm || addr + len <= vmm->vm_start))
7905 return addr;
7906 }
7907- addr = TASK_UNMAPPED_BASE;
7908+ addr = current->mm->mmap_base;
7909 if (do_color_align)
7910 addr = COLOUR_ALIGN(addr, pgoff);
7911 else
7912diff -urNp linux-2.6.22.1/arch/mips/mm/fault.c linux-2.6.22.1/arch/mips/mm/fault.c
7913--- linux-2.6.22.1/arch/mips/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
7914+++ linux-2.6.22.1/arch/mips/mm/fault.c 2007-08-02 11:38:45.000000000 -0400
7915@@ -26,6 +26,23 @@
7916 #include <asm/ptrace.h>
7917 #include <asm/highmem.h> /* For VMALLOC_END */
7918
7919+#ifdef CONFIG_PAX_PAGEEXEC
7920+void pax_report_insns(void *pc)
7921+{
7922+ unsigned long i;
7923+
7924+ printk(KERN_ERR "PAX: bytes at PC: ");
7925+ for (i = 0; i < 5; i++) {
7926+ unsigned int c;
7927+ if (get_user(c, (unsigned int *)pc+i))
7928+ printk("???????? ");
7929+ else
7930+ printk("%08x ", c);
7931+ }
7932+ printk("\n");
7933+}
7934+#endif
7935+
7936 /*
7937 * This routine handles page faults. It determines the address,
7938 * and the problem, and then passes it off to one of the appropriate
7939diff -urNp linux-2.6.22.1/arch/parisc/kernel/module.c linux-2.6.22.1/arch/parisc/kernel/module.c
7940--- linux-2.6.22.1/arch/parisc/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
7941+++ linux-2.6.22.1/arch/parisc/kernel/module.c 2007-08-02 11:38:45.000000000 -0400
7942@@ -73,16 +73,38 @@
7943
7944 /* three functions to determine where in the module core
7945 * or init pieces the location is */
7946+static inline int in_init_rx(struct module *me, void *loc)
7947+{
7948+ return (loc >= me->module_init_rx &&
7949+ loc < (me->module_init_rx + me->init_size_rx));
7950+}
7951+
7952+static inline int in_init_rw(struct module *me, void *loc)
7953+{
7954+ return (loc >= me->module_init_rw &&
7955+ loc < (me->module_init_rw + me->init_size_rw));
7956+}
7957+
7958 static inline int in_init(struct module *me, void *loc)
7959 {
7960- return (loc >= me->module_init &&
7961- loc <= (me->module_init + me->init_size));
7962+ return in_init_rx(me, loc) || in_init_rw(me, loc);
7963+}
7964+
7965+static inline int in_core_rx(struct module *me, void *loc)
7966+{
7967+ return (loc >= me->module_core_rx &&
7968+ loc < (me->module_core_rx + me->core_size_rx));
7969+}
7970+
7971+static inline int in_core_rw(struct module *me, void *loc)
7972+{
7973+ return (loc >= me->module_core_rw &&
7974+ loc < (me->module_core_rw + me->core_size_rw));
7975 }
7976
7977 static inline int in_core(struct module *me, void *loc)
7978 {
7979- return (loc >= me->module_core &&
7980- loc <= (me->module_core + me->core_size));
7981+ return in_core_rx(me, loc) || in_core_rw(me, loc);
7982 }
7983
7984 static inline int in_local(struct module *me, void *loc)
7985@@ -296,21 +318,21 @@ int module_frob_arch_sections(CONST Elf_
7986 }
7987
7988 /* align things a bit */
7989- me->core_size = ALIGN(me->core_size, 16);
7990- me->arch.got_offset = me->core_size;
7991- me->core_size += gots * sizeof(struct got_entry);
7992-
7993- me->core_size = ALIGN(me->core_size, 16);
7994- me->arch.fdesc_offset = me->core_size;
7995- me->core_size += fdescs * sizeof(Elf_Fdesc);
7996-
7997- me->core_size = ALIGN(me->core_size, 16);
7998- me->arch.stub_offset = me->core_size;
7999- me->core_size += stubs * sizeof(struct stub_entry);
8000-
8001- me->init_size = ALIGN(me->init_size, 16);
8002- me->arch.init_stub_offset = me->init_size;
8003- me->init_size += init_stubs * sizeof(struct stub_entry);
8004+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
8005+ me->arch.got_offset = me->core_size_rw;
8006+ me->core_size_rw += gots * sizeof(struct got_entry);
8007+
8008+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
8009+ me->arch.fdesc_offset = me->core_size_rw;
8010+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
8011+
8012+ me->core_size_rx = ALIGN(me->core_size_rx, 16);
8013+ me->arch.stub_offset = me->core_size_rx;
8014+ me->core_size_rx += stubs * sizeof(struct stub_entry);
8015+
8016+ me->init_size_rx = ALIGN(me->init_size_rx, 16);
8017+ me->arch.init_stub_offset = me->init_size_rx;
8018+ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
8019
8020 me->arch.got_max = gots;
8021 me->arch.fdesc_max = fdescs;
8022@@ -330,7 +352,7 @@ static Elf64_Word get_got(struct module
8023
8024 BUG_ON(value == 0);
8025
8026- got = me->module_core + me->arch.got_offset;
8027+ got = me->module_core_rw + me->arch.got_offset;
8028 for (i = 0; got[i].addr; i++)
8029 if (got[i].addr == value)
8030 goto out;
8031@@ -348,7 +370,7 @@ static Elf64_Word get_got(struct module
8032 #ifdef CONFIG_64BIT
8033 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
8034 {
8035- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
8036+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
8037
8038 if (!value) {
8039 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
8040@@ -366,7 +388,7 @@ static Elf_Addr get_fdesc(struct module
8041
8042 /* Create new one */
8043 fdesc->addr = value;
8044- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
8045+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
8046 return (Elf_Addr)fdesc;
8047 }
8048 #endif /* CONFIG_64BIT */
8049@@ -386,12 +408,12 @@ static Elf_Addr get_stub(struct module *
8050 if(init_section) {
8051 i = me->arch.init_stub_count++;
8052 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
8053- stub = me->module_init + me->arch.init_stub_offset +
8054+ stub = me->module_init_rx + me->arch.init_stub_offset +
8055 i * sizeof(struct stub_entry);
8056 } else {
8057 i = me->arch.stub_count++;
8058 BUG_ON(me->arch.stub_count > me->arch.stub_max);
8059- stub = me->module_core + me->arch.stub_offset +
8060+ stub = me->module_core_rx + me->arch.stub_offset +
8061 i * sizeof(struct stub_entry);
8062 }
8063
8064@@ -759,7 +781,7 @@ register_unwind_table(struct module *me,
8065
8066 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
8067 end = table + sechdrs[me->arch.unwind_section].sh_size;
8068- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
8069+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
8070
8071 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
8072 me->arch.unwind_section, table, end, gp);
3ba9fddb 8073diff -urNp linux-2.6.22.1/arch/parisc/kernel/sys_parisc.c linux-2.6.22.1/arch/parisc/kernel/sys_parisc.c
8074--- linux-2.6.22.1/arch/parisc/kernel/sys_parisc.c 2007-07-10 14:56:30.000000000 -0400
8075+++ linux-2.6.22.1/arch/parisc/kernel/sys_parisc.c 2007-08-02 11:38:46.000000000 -0400
8076@@ -111,7 +111,7 @@ unsigned long arch_get_unmapped_area(str
8077 if (flags & MAP_FIXED)
8078 return addr;
8079 if (!addr)
8080- addr = TASK_UNMAPPED_BASE;
8081+ addr = current->mm->mmap_base;
8082
8083 if (filp) {
8084 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
8085diff -urNp linux-2.6.22.1/arch/parisc/kernel/traps.c linux-2.6.22.1/arch/parisc/kernel/traps.c
8086--- linux-2.6.22.1/arch/parisc/kernel/traps.c 2007-07-10 14:56:30.000000000 -0400
8087+++ linux-2.6.22.1/arch/parisc/kernel/traps.c 2007-08-02 11:38:46.000000000 -0400
8088@@ -712,9 +712,7 @@ void handle_interruption(int code, struc
8089
8090 down_read(&current->mm->mmap_sem);
8091 vma = find_vma(current->mm,regs->iaoq[0]);
8092- if (vma && (regs->iaoq[0] >= vma->vm_start)
8093- && (vma->vm_flags & VM_EXEC)) {
8094-
8095+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
8096 fault_address = regs->iaoq[0];
8097 fault_space = regs->iasq[0];
8098
8099diff -urNp linux-2.6.22.1/arch/parisc/mm/fault.c linux-2.6.22.1/arch/parisc/mm/fault.c
8100--- linux-2.6.22.1/arch/parisc/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
8101+++ linux-2.6.22.1/arch/parisc/mm/fault.c 2007-08-02 11:38:46.000000000 -0400
8102@@ -16,6 +16,8 @@
8103 #include <linux/sched.h>
8104 #include <linux/interrupt.h>
8105 #include <linux/module.h>
8106+#include <linux/unistd.h>
8107+#include <linux/binfmts.h>
8108
8109 #include <asm/uaccess.h>
8110 #include <asm/traps.h>
8111@@ -53,7 +55,7 @@ DEFINE_PER_CPU(struct exception_data, ex
8112 static unsigned long
8113 parisc_acctyp(unsigned long code, unsigned int inst)
8114 {
8115- if (code == 6 || code == 16)
8116+ if (code == 6 || code == 7 || code == 16)
8117 return VM_EXEC;
8118
8119 switch (inst & 0xf0000000) {
8120@@ -139,6 +141,116 @@ parisc_acctyp(unsigned long code, unsign
8121 }
8122 #endif
8123
8124+#ifdef CONFIG_PAX_PAGEEXEC
8125+/*
8126+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
8127+ *
8128+ * returns 1 when task should be killed
8129+ * 2 when rt_sigreturn trampoline was detected
8130+ * 3 when unpatched PLT trampoline was detected
8131+ */
8132+static int pax_handle_fetch_fault(struct pt_regs *regs)
8133+{
8134+
8135+#ifdef CONFIG_PAX_EMUPLT
8136+ int err;
8137+
8138+ do { /* PaX: unpatched PLT emulation */
8139+ unsigned int bl, depwi;
8140+
8141+ err = get_user(bl, (unsigned int *)instruction_pointer(regs));
8142+ err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
8143+
8144+ if (err)
8145+ break;
8146+
8147+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
8148+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
8149+
8150+ err = get_user(ldw, (unsigned int *)addr);
8151+ err |= get_user(bv, (unsigned int *)(addr+4));
8152+ err |= get_user(ldw2, (unsigned int *)(addr+8));
8153+
8154+ if (err)
8155+ break;
8156+
8157+ if (ldw == 0x0E801096U &&
8158+ bv == 0xEAC0C000U &&
8159+ ldw2 == 0x0E881095U)
8160+ {
8161+ unsigned int resolver, map;
8162+
8163+ err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
8164+ err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
8165+ if (err)
8166+ break;
8167+
8168+ regs->gr[20] = instruction_pointer(regs)+8;
8169+ regs->gr[21] = map;
8170+ regs->gr[22] = resolver;
8171+ regs->iaoq[0] = resolver | 3UL;
8172+ regs->iaoq[1] = regs->iaoq[0] + 4;
8173+ return 3;
8174+ }
8175+ }
8176+ } while (0);
8177+#endif
8178+
8179+#ifdef CONFIG_PAX_EMUTRAMP
8180+
8181+#ifndef CONFIG_PAX_EMUSIGRT
8182+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
8183+ return 1;
8184+#endif
8185+
8186+ do { /* PaX: rt_sigreturn emulation */
8187+ unsigned int ldi1, ldi2, bel, nop;
8188+
8189+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
8190+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
8191+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
8192+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
8193+
8194+ if (err)
8195+ break;
8196+
8197+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
8198+ ldi2 == 0x3414015AU &&
8199+ bel == 0xE4008200U &&
8200+ nop == 0x08000240U)
8201+ {
8202+ regs->gr[25] = (ldi1 & 2) >> 1;
8203+ regs->gr[20] = __NR_rt_sigreturn;
8204+ regs->gr[31] = regs->iaoq[1] + 16;
8205+ regs->sr[0] = regs->iasq[1];
8206+ regs->iaoq[0] = 0x100UL;
8207+ regs->iaoq[1] = regs->iaoq[0] + 4;
8208+ regs->iasq[0] = regs->sr[2];
8209+ regs->iasq[1] = regs->sr[2];
8210+ return 2;
8211+ }
8212+ } while (0);
8213+#endif
8214+
8215+ return 1;
8216+}
8217+
8218+void pax_report_insns(void *pc, void *sp)
8219+{
8220+ unsigned long i;
8221+
8222+ printk(KERN_ERR "PAX: bytes at PC: ");
8223+ for (i = 0; i < 5; i++) {
8224+ unsigned int c;
8225+ if (get_user(c, (unsigned int *)pc+i))
8226+ printk("???????? ");
8227+ else
8228+ printk("%08x ", c);
8229+ }
8230+ printk("\n");
8231+}
8232+#endif
8233+
8234 void do_page_fault(struct pt_regs *regs, unsigned long code,
8235 unsigned long address)
8236 {
8237@@ -164,8 +276,33 @@ good_area:
8238
8239 acc_type = parisc_acctyp(code,regs->iir);
8240
8241- if ((vma->vm_flags & acc_type) != acc_type)
8242+ if ((vma->vm_flags & acc_type) != acc_type) {
8243+
8244+#ifdef CONFIG_PAX_PAGEEXEC
8245+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
8246+ (address & ~3UL) == instruction_pointer(regs))
8247+ {
8248+ up_read(&mm->mmap_sem);
8249+ switch (pax_handle_fetch_fault(regs)) {
8250+
8251+#ifdef CONFIG_PAX_EMUPLT
8252+ case 3:
8253+ return;
8254+#endif
8255+
8256+#ifdef CONFIG_PAX_EMUTRAMP
8257+ case 2:
8258+ return;
8259+#endif
8260+
8261+ }
8262+ pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
8263+ do_exit(SIGKILL);
8264+ }
8265+#endif
8266+
8267 goto bad_area;
8268+ }
8269
8270 /*
8271 * If for any reason at all we couldn't handle the fault, make
8272diff -urNp linux-2.6.22.1/arch/powerpc/kernel/module_32.c linux-2.6.22.1/arch/powerpc/kernel/module_32.c
8273--- linux-2.6.22.1/arch/powerpc/kernel/module_32.c 2007-07-10 14:56:30.000000000 -0400
8274+++ linux-2.6.22.1/arch/powerpc/kernel/module_32.c 2007-08-02 11:38:46.000000000 -0400
8275@@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
8276 me->arch.core_plt_section = i;
8277 }
8278 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
8279- printk("Module doesn't contain .plt or .init.plt sections.\n");
8280+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
8281 return -ENOEXEC;
8282 }
8283
8284@@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
8285
8286 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
8287 /* Init, or core PLT? */
8288- if (location >= mod->module_core
8289- && location < mod->module_core + mod->core_size)
8290+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
8291+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
8292 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
8293- else
8294+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
8295+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
8296 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
8297+ else {
8298+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
8299+ return ~0UL;
8300+ }
8301
8302 /* Find this entry, or if that fails, the next avail. entry */
8303 while (entry->jump[0]) {
8304diff -urNp linux-2.6.22.1/arch/powerpc/kernel/signal_32.c linux-2.6.22.1/arch/powerpc/kernel/signal_32.c
8305--- linux-2.6.22.1/arch/powerpc/kernel/signal_32.c 2007-07-10 14:56:30.000000000 -0400
8306+++ linux-2.6.22.1/arch/powerpc/kernel/signal_32.c 2007-08-02 11:38:46.000000000 -0400
8307@@ -758,7 +758,7 @@ static int handle_rt_signal(unsigned lon
8308
8309 /* Save user registers on the stack */
8310 frame = &rt_sf->uc.uc_mcontext;
8311- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
8312+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
8313 if (save_user_regs(regs, frame, 0))
8314 goto badframe;
8315 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
8316diff -urNp linux-2.6.22.1/arch/powerpc/kernel/signal_64.c linux-2.6.22.1/arch/powerpc/kernel/signal_64.c
8317--- linux-2.6.22.1/arch/powerpc/kernel/signal_64.c 2007-07-10 14:56:30.000000000 -0400
8318+++ linux-2.6.22.1/arch/powerpc/kernel/signal_64.c 2007-08-02 11:38:46.000000000 -0400
8319@@ -400,7 +400,7 @@ static int setup_rt_frame(int signr, str
8320 current->thread.fpscr.val = 0;
8321
8322 /* Set up to return from userspace. */
8323- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
8324+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
8325 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
8326 } else {
8327 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
8328diff -urNp linux-2.6.22.1/arch/powerpc/kernel/vdso.c linux-2.6.22.1/arch/powerpc/kernel/vdso.c
8329--- linux-2.6.22.1/arch/powerpc/kernel/vdso.c 2007-07-10 14:56:30.000000000 -0400
8330+++ linux-2.6.22.1/arch/powerpc/kernel/vdso.c 2007-08-02 11:38:46.000000000 -0400
8331@@ -199,7 +199,7 @@ int arch_setup_additional_pages(struct l
8332 vdso_base = VDSO32_MBASE;
8333 #endif
8334
8335- current->mm->context.vdso_base = 0;
8336+ current->mm->context.vdso_base = ~0UL;
8337
8338 /* vDSO has a problem and was disabled, just don't "enable" it for the
8339 * process
8340@@ -216,7 +216,7 @@ int arch_setup_additional_pages(struct l
8341 */
8342 down_write(&mm->mmap_sem);
8343 vdso_base = get_unmapped_area(NULL, vdso_base,
8344- vdso_pages << PAGE_SHIFT, 0, 0);
8345+ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
8346 if (IS_ERR_VALUE(vdso_base)) {
8347 rc = vdso_base;
8348 goto fail_mmapsem;
8349diff -urNp linux-2.6.22.1/arch/powerpc/mm/fault.c linux-2.6.22.1/arch/powerpc/mm/fault.c
8350--- linux-2.6.22.1/arch/powerpc/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
8351+++ linux-2.6.22.1/arch/powerpc/mm/fault.c 2007-08-02 11:38:46.000000000 -0400
8352@@ -29,6 +29,12 @@
8353 #include <linux/module.h>
8354 #include <linux/kprobes.h>
8355 #include <linux/kdebug.h>
8356+#include <linux/binfmts.h>
8357+#include <linux/slab.h>
8358+#include <linux/pagemap.h>
8359+#include <linux/compiler.h>
8360+#include <linux/binfmts.h>
8361+#include <linux/unistd.h>
8362
8363 #include <asm/page.h>
8364 #include <asm/pgtable.h>
8365@@ -62,6 +68,364 @@ static inline int notify_page_fault(stru
8366 }
8367 #endif
8368
8369+#ifdef CONFIG_PAX_EMUSIGRT
8370+void pax_syscall_close(struct vm_area_struct *vma)
8371+{
8372+ vma->vm_mm->call_syscall = 0UL;
8373+}
8374+
8375+static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8376+{
8377+ struct page *page;
8378+ unsigned int *kaddr;
8379+
8380+ page = alloc_page(GFP_HIGHUSER);
8381+ if (!page)
8382+ return NOPAGE_OOM;
8383+
8384+ kaddr = kmap(page);
8385+ memset(kaddr, 0, PAGE_SIZE);
8386+ kaddr[0] = 0x44000002U; /* sc */
8387+ __flush_dcache_icache(kaddr);
8388+ kunmap(page);
8389+ if (type)
8390+ *type = VM_FAULT_MAJOR;
8391+ return page;
8392+}
8393+
8394+static struct vm_operations_struct pax_vm_ops = {
8395+ .close = pax_syscall_close,
8396+ .nopage = pax_syscall_nopage,
8397+};
8398+
8399+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8400+{
8401+ int ret;
8402+
8403+ memset(vma, 0, sizeof(*vma));
8404+ vma->vm_mm = current->mm;
8405+ vma->vm_start = addr;
8406+ vma->vm_end = addr + PAGE_SIZE;
8407+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8408+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8409+ vma->vm_ops = &pax_vm_ops;
8410+
8411+ ret = insert_vm_struct(current->mm, vma);
8412+ if (ret)
8413+ return ret;
8414+
8415+ ++current->mm->total_vm;
8416+ return 0;
8417+}
8418+#endif
8419+
8420+#ifdef CONFIG_PAX_PAGEEXEC
8421+/*
8422+ * PaX: decide what to do with offenders (regs->nip = fault address)
8423+ *
8424+ * returns 1 when task should be killed
8425+ * 2 when patched GOT trampoline was detected
8426+ * 3 when patched PLT trampoline was detected
8427+ * 4 when unpatched PLT trampoline was detected
8428+ * 5 when sigreturn trampoline was detected
8429+ * 6 when rt_sigreturn trampoline was detected
8430+ */
8431+static int pax_handle_fetch_fault(struct pt_regs *regs)
8432+{
8433+
8434+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
8435+ int err;
8436+#endif
8437+
8438+#ifdef CONFIG_PAX_EMUPLT
8439+ do { /* PaX: patched GOT emulation */
8440+ unsigned int blrl;
8441+
8442+ err = get_user(blrl, (unsigned int *)regs->nip);
8443+
8444+ if (!err && blrl == 0x4E800021U) {
8445+ unsigned long temp = regs->nip;
8446+
8447+ regs->nip = regs->link & 0xFFFFFFFCUL;
8448+ regs->link = temp + 4UL;
8449+ return 2;
8450+ }
8451+ } while (0);
8452+
8453+ do { /* PaX: patched PLT emulation #1 */
8454+ unsigned int b;
8455+
8456+ err = get_user(b, (unsigned int *)regs->nip);
8457+
8458+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
8459+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
8460+ return 3;
8461+ }
8462+ } while (0);
8463+
8464+ do { /* PaX: unpatched PLT emulation #1 */
8465+ unsigned int li, b;
8466+
8467+ err = get_user(li, (unsigned int *)regs->nip);
8468+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8469+
8470+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8471+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8472+ unsigned long addr = b | 0xFC000000UL;
8473+
8474+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8475+ err = get_user(rlwinm, (unsigned int *)addr);
8476+ err |= get_user(add, (unsigned int *)(addr+4));
8477+ err |= get_user(li2, (unsigned int *)(addr+8));
8478+ err |= get_user(addis2, (unsigned int *)(addr+12));
8479+ err |= get_user(mtctr, (unsigned int *)(addr+16));
8480+ err |= get_user(li3, (unsigned int *)(addr+20));
8481+ err |= get_user(addis3, (unsigned int *)(addr+24));
8482+ err |= get_user(bctr, (unsigned int *)(addr+28));
8483+
8484+ if (err)
8485+ break;
8486+
8487+ if (rlwinm == 0x556C083CU &&
8488+ add == 0x7D6C5A14U &&
8489+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8490+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8491+ mtctr == 0x7D8903A6U &&
8492+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8493+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8494+ bctr == 0x4E800420U)
8495+ {
8496+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8497+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8498+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8499+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8500+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8501+ regs->nip = regs->ctr;
8502+ return 4;
8503+ }
8504+ }
8505+ } while (0);
8506+
8507+#if 0
8508+ do { /* PaX: unpatched PLT emulation #2 */
8509+ unsigned int lis, lwzu, b, bctr;
8510+
8511+ err = get_user(lis, (unsigned int *)regs->nip);
8512+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
8513+ err |= get_user(b, (unsigned int *)(regs->nip+8));
8514+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
8515+
8516+ if (err)
8517+ break;
8518+
8519+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
8520+ (lwzu & 0xU) == 0xU &&
8521+ (b & 0xFC000003U) == 0x48000000U &&
8522+ bctr == 0x4E800420U)
8523+ {
8524+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8525+ unsigned long addr = b | 0xFC000000UL;
8526+
8527+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8528+ err = get_user(addis, (unsigned int*)addr);
8529+ err |= get_user(addi, (unsigned int*)(addr+4));
8530+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
8531+ err |= get_user(add, (unsigned int*)(addr+12));
8532+ err |= get_user(li2, (unsigned int*)(addr+16));
8533+ err |= get_user(addis2, (unsigned int*)(addr+20));
8534+ err |= get_user(mtctr, (unsigned int*)(addr+24));
8535+ err |= get_user(li3, (unsigned int*)(addr+28));
8536+ err |= get_user(addis3, (unsigned int*)(addr+32));
8537+ err |= get_user(bctr, (unsigned int*)(addr+36));
8538+
8539+ if (err)
8540+ break;
8541+
8542+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8543+ (addi & 0xFFFF0000U) == 0x396B0000U &&
8544+ rlwinm == 0x556C083CU &&
8545+ add == 0x7D6C5A14U &&
8546+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8547+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8548+ mtctr == 0x7D8903A6U &&
8549+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8550+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8551+ bctr == 0x4E800420U)
8552+ {
8553+ regs->gpr[PT_R11] =
8554+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8555+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8556+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8557+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8558+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8559+ regs->nip = regs->ctr;
8560+ return 4;
8561+ }
8562+ }
8563+ } while (0);
8564+#endif
8565+
8566+ do { /* PaX: unpatched PLT emulation #3 */
8567+ unsigned int li, b;
8568+
8569+ err = get_user(li, (unsigned int *)regs->nip);
8570+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8571+
8572+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8573+ unsigned int addis, lwz, mtctr, bctr;
8574+ unsigned long addr = b | 0xFC000000UL;
8575+
8576+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8577+ err = get_user(addis, (unsigned int *)addr);
8578+ err |= get_user(lwz, (unsigned int *)(addr+4));
8579+ err |= get_user(mtctr, (unsigned int *)(addr+8));
8580+ err |= get_user(bctr, (unsigned int *)(addr+12));
8581+
8582+ if (err)
8583+ break;
8584+
8585+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8586+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
8587+ mtctr == 0x7D6903A6U &&
8588+ bctr == 0x4E800420U)
8589+ {
8590+ unsigned int r11;
8591+
8592+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8593+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8594+
8595+ err = get_user(r11, (unsigned int *)addr);
8596+ if (err)
8597+ break;
8598+
8599+ regs->gpr[PT_R11] = r11;
8600+ regs->ctr = r11;
8601+ regs->nip = r11;
8602+ return 4;
8603+ }
8604+ }
8605+ } while (0);
8606+#endif
8607+
8608+#ifdef CONFIG_PAX_EMUSIGRT
8609+ do { /* PaX: sigreturn emulation */
8610+ unsigned int li, sc;
8611+
8612+ err = get_user(li, (unsigned int *)regs->nip);
8613+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8614+
8615+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
8616+ struct vm_area_struct *vma;
8617+ unsigned long call_syscall;
8618+
8619+ down_read(&current->mm->mmap_sem);
8620+ call_syscall = current->mm->call_syscall;
8621+ up_read(&current->mm->mmap_sem);
8622+ if (likely(call_syscall))
8623+ goto emulate;
8624+
8625+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8626+
8627+ down_write(&current->mm->mmap_sem);
8628+ if (current->mm->call_syscall) {
8629+ call_syscall = current->mm->call_syscall;
8630+ up_write(&current->mm->mmap_sem);
8631+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8632+ goto emulate;
8633+ }
8634+
8635+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8636+ if (!vma || (call_syscall & ~PAGE_MASK)) {
8637+ up_write(&current->mm->mmap_sem);
8638+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8639+ return 1;
8640+ }
8641+
8642+ if (pax_insert_vma(vma, call_syscall)) {
8643+ up_write(&current->mm->mmap_sem);
8644+ kmem_cache_free(vm_area_cachep, vma);
8645+ return 1;
8646+ }
8647+
8648+ current->mm->call_syscall = call_syscall;
8649+ up_write(&current->mm->mmap_sem);
8650+
8651+emulate:
8652+ regs->gpr[PT_R0] = __NR_sigreturn;
8653+ regs->nip = call_syscall;
8654+ return 5;
8655+ }
8656+ } while (0);
8657+
8658+ do { /* PaX: rt_sigreturn emulation */
8659+ unsigned int li, sc;
8660+
8661+ err = get_user(li, (unsigned int *)regs->nip);
8662+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
8663+
8664+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
8665+ struct vm_area_struct *vma;
8666+ unsigned int call_syscall;
8667+
8668+ down_read(&current->mm->mmap_sem);
8669+ call_syscall = current->mm->call_syscall;
8670+ up_read(&current->mm->mmap_sem);
8671+ if (likely(call_syscall))
8672+ goto rt_emulate;
8673+
8674+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8675+
8676+ down_write(&current->mm->mmap_sem);
8677+ if (current->mm->call_syscall) {
8678+ call_syscall = current->mm->call_syscall;
8679+ up_write(&current->mm->mmap_sem);
8680+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8681+ goto rt_emulate;
8682+ }
8683+
8684+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8685+ if (!vma || (call_syscall & ~PAGE_MASK)) {
8686+ up_write(&current->mm->mmap_sem);
8687+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8688+ return 1;
8689+ }
8690+
8691+ if (pax_insert_vma(vma, call_syscall)) {
8692+ up_write(&current->mm->mmap_sem);
8693+ kmem_cache_free(vm_area_cachep, vma);
8694+ return 1;
8695+ }
8696+
8697+ current->mm->call_syscall = call_syscall;
8698+ up_write(&current->mm->mmap_sem);
8699+
8700+rt_emulate:
8701+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
8702+ regs->nip = call_syscall;
8703+ return 6;
8704+ }
8705+ } while (0);
8706+#endif
8707+
8708+ return 1;
8709+}
8710+
8711+void pax_report_insns(void *pc, void *sp)
8712+{
8713+ unsigned long i;
8714+
8715+ printk(KERN_ERR "PAX: bytes at PC: ");
8716+ for (i = 0; i < 5; i++) {
8717+ unsigned int c;
8718+ if (get_user(c, (unsigned int *)pc+i))
8719+ printk("???????? ");
8720+ else
8721+ printk("%08x ", c);
8722+ }
8723+ printk("\n");
8724+}
8725+#endif
8726+
8727 /*
8728 * Check whether the instruction at regs->nip is a store using
8729 * an update addressing form which will update r1.
8730@@ -157,7 +521,7 @@ int __kprobes do_page_fault(struct pt_re
8731 * indicate errors in DSISR but can validly be set in SRR1.
8732 */
8733 if (trap == 0x400)
8734- error_code &= 0x48200000;
8735+ error_code &= 0x58200000;
8736 else
8737 is_write = error_code & DSISR_ISSTORE;
8738 #else
8739@@ -355,6 +719,37 @@ bad_area:
8740 bad_area_nosemaphore:
8741 /* User mode accesses cause a SIGSEGV */
8742 if (user_mode(regs)) {
8743+
8744+#ifdef CONFIG_PAX_PAGEEXEC
8745+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
8746+#ifdef CONFIG_PPC64
8747+ if (is_exec && (error_code & DSISR_PROTFAULT)) {
8748+#else
8749+ if (is_exec && regs->nip == address) {
8750+#endif
8751+ switch (pax_handle_fetch_fault(regs)) {
8752+
8753+#ifdef CONFIG_PAX_EMUPLT
8754+ case 2:
8755+ case 3:
8756+ case 4:
8757+ return 0;
8758+#endif
8759+
8760+#ifdef CONFIG_PAX_EMUSIGRT
8761+ case 5:
8762+ case 6:
8763+ return 0;
8764+#endif
8765+
8766+ }
8767+
8768+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
8769+ do_exit(SIGKILL);
8770+ }
8771+ }
8772+#endif
8773+
8774 _exception(SIGSEGV, regs, code, address);
8775 return 0;
8776 }
8777diff -urNp linux-2.6.22.1/arch/powerpc/mm/mmap.c linux-2.6.22.1/arch/powerpc/mm/mmap.c
8778--- linux-2.6.22.1/arch/powerpc/mm/mmap.c 2007-07-10 14:56:30.000000000 -0400
8779+++ linux-2.6.22.1/arch/powerpc/mm/mmap.c 2007-08-02 11:38:46.000000000 -0400
8780@@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
8781 */
8782 if (mmap_is_legacy()) {
8783 mm->mmap_base = TASK_UNMAPPED_BASE;
8784+
8785+#ifdef CONFIG_PAX_RANDMMAP
8786+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8787+ mm->mmap_base += mm->delta_mmap;
8788+#endif
8789+
8790 mm->get_unmapped_area = arch_get_unmapped_area;
8791 mm->unmap_area = arch_unmap_area;
8792 } else {
8793 mm->mmap_base = mmap_base();
8794+
8795+#ifdef CONFIG_PAX_RANDMMAP
8796+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8797+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8798+#endif
8799+
8800 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8801 mm->unmap_area = arch_unmap_area_topdown;
8802 }
8803diff -urNp linux-2.6.22.1/arch/ppc/mm/fault.c linux-2.6.22.1/arch/ppc/mm/fault.c
8804--- linux-2.6.22.1/arch/ppc/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
8805+++ linux-2.6.22.1/arch/ppc/mm/fault.c 2007-08-02 11:38:46.000000000 -0400
8806@@ -25,6 +25,11 @@
8807 #include <linux/interrupt.h>
8808 #include <linux/highmem.h>
8809 #include <linux/module.h>
8810+#include <linux/slab.h>
8811+#include <linux/pagemap.h>
8812+#include <linux/compiler.h>
8813+#include <linux/binfmts.h>
8814+#include <linux/unistd.h>
8815
8816 #include <asm/page.h>
8817 #include <asm/pgtable.h>
8818@@ -48,6 +53,364 @@ unsigned long pte_misses; /* updated by
8819 unsigned long pte_errors; /* updated by do_page_fault() */
8820 unsigned int probingmem;
8821
8822+#ifdef CONFIG_PAX_EMUSIGRT
8823+void pax_syscall_close(struct vm_area_struct *vma)
8824+{
8825+ vma->vm_mm->call_syscall = 0UL;
8826+}
8827+
8828+static struct page *pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8829+{
8830+ struct page *page;
8831+ unsigned int *kaddr;
8832+
8833+ page = alloc_page(GFP_HIGHUSER);
8834+ if (!page)
8835+ return NOPAGE_OOM;
8836+
8837+ kaddr = kmap(page);
8838+ memset(kaddr, 0, PAGE_SIZE);
8839+ kaddr[0] = 0x44000002U; /* sc */
8840+ __flush_dcache_icache(kaddr);
8841+ kunmap(page);
8842+ if (type)
8843+ *type = VM_FAULT_MAJOR;
8844+ return page;
8845+}
8846+
8847+static struct vm_operations_struct pax_vm_ops = {
8848+ .close = pax_syscall_close,
8849+ .nopage = pax_syscall_nopage,
8850+};
8851+
8852+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8853+{
8854+ int ret;
8855+
8856+ memset(vma, 0, sizeof(*vma));
8857+ vma->vm_mm = current->mm;
8858+ vma->vm_start = addr;
8859+ vma->vm_end = addr + PAGE_SIZE;
8860+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8861+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
8862+ vma->vm_ops = &pax_vm_ops;
8863+
8864+ ret = insert_vm_struct(current->mm, vma);
8865+ if (ret)
8866+ return ret;
8867+
8868+ ++current->mm->total_vm;
8869+ return 0;
8870+}
8871+#endif
8872+
8873+#ifdef CONFIG_PAX_PAGEEXEC
8874+/*
8875+ * PaX: decide what to do with offenders (regs->nip = fault address)
8876+ *
8877+ * returns 1 when task should be killed
8878+ * 2 when patched GOT trampoline was detected
8879+ * 3 when patched PLT trampoline was detected
8880+ * 4 when unpatched PLT trampoline was detected
8881+ * 5 when sigreturn trampoline was detected
8882+ * 6 when rt_sigreturn trampoline was detected
8883+ */
8884+static int pax_handle_fetch_fault(struct pt_regs *regs)
8885+{
8886+
8887+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
8888+ int err;
8889+#endif
8890+
8891+#ifdef CONFIG_PAX_EMUPLT
8892+ do { /* PaX: patched GOT emulation */
8893+ unsigned int blrl;
8894+
8895+ err = get_user(blrl, (unsigned int *)regs->nip);
8896+
8897+ if (!err && blrl == 0x4E800021U) {
8898+ unsigned long temp = regs->nip;
8899+
8900+ regs->nip = regs->link & 0xFFFFFFFCUL;
8901+ regs->link = temp + 4UL;
8902+ return 2;
8903+ }
8904+ } while (0);
8905+
8906+ do { /* PaX: patched PLT emulation #1 */
8907+ unsigned int b;
8908+
8909+ err = get_user(b, (unsigned int *)regs->nip);
8910+
8911+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
8912+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
8913+ return 3;
8914+ }
8915+ } while (0);
8916+
8917+ do { /* PaX: unpatched PLT emulation #1 */
8918+ unsigned int li, b;
8919+
8920+ err = get_user(li, (unsigned int *)regs->nip);
8921+ err |= get_user(b, (unsigned int *)(regs->nip+4));
8922+
8923+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8924+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8925+ unsigned long addr = b | 0xFC000000UL;
8926+
8927+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8928+ err = get_user(rlwinm, (unsigned int *)addr);
8929+ err |= get_user(add, (unsigned int *)(addr+4));
8930+ err |= get_user(li2, (unsigned int *)(addr+8));
8931+ err |= get_user(addis2, (unsigned int *)(addr+12));
8932+ err |= get_user(mtctr, (unsigned int *)(addr+16));
8933+ err |= get_user(li3, (unsigned int *)(addr+20));
8934+ err |= get_user(addis3, (unsigned int *)(addr+24));
8935+ err |= get_user(bctr, (unsigned int *)(addr+28));
8936+
8937+ if (err)
8938+ break;
8939+
8940+ if (rlwinm == 0x556C083CU &&
8941+ add == 0x7D6C5A14U &&
8942+ (li2 & 0xFFFF0000U) == 0x39800000U &&
8943+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8944+ mtctr == 0x7D8903A6U &&
8945+ (li3 & 0xFFFF0000U) == 0x39800000U &&
8946+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8947+ bctr == 0x4E800420U)
8948+ {
8949+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8950+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8951+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8952+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8953+ regs->ctr += (addis2 & 0xFFFFU) << 16;
8954+ regs->nip = regs->ctr;
8955+ return 4;
8956+ }
8957+ }
8958+ } while (0);
8959+
8960+#if 0
8961+ do { /* PaX: unpatched PLT emulation #2 */
8962+ unsigned int lis, lwzu, b, bctr;
8963+
8964+ err = get_user(lis, (unsigned int *)regs->nip);
8965+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
8966+ err |= get_user(b, (unsigned int *)(regs->nip+8));
8967+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
8968+
8969+ if (err)
8970+ break;
8971+
8972+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
8973+ (lwzu & 0xU) == 0xU &&
8974+ (b & 0xFC000003U) == 0x48000000U &&
8975+ bctr == 0x4E800420U)
8976+ {
8977+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8978+ unsigned long addr = b | 0xFC000000UL;
8979+
8980+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8981+ err = get_user(addis, (unsigned int*)addr);
8982+ err |= get_user(addi, (unsigned int*)(addr+4));
8983+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
8984+ err |= get_user(add, (unsigned int*)(addr+12));
8985+ err |= get_user(li2, (unsigned int*)(addr+16));
8986+ err |= get_user(addis2, (unsigned int*)(addr+20));
8987+ err |= get_user(mtctr, (unsigned int*)(addr+24));
8988+ err |= get_user(li3, (unsigned int*)(addr+28));
8989+ err |= get_user(addis3, (unsigned int*)(addr+32));
8990+ err |= get_user(bctr, (unsigned int*)(addr+36));
8991+
8992+ if (err)
8993+ break;
8994+
8995+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8996+ (addi & 0xFFFF0000U) == 0x396B0000U &&
8997+ rlwinm == 0x556C083CU &&
8998+ add == 0x7D6C5A14U &&
8999+ (li2 & 0xFFFF0000U) == 0x39800000U &&
9000+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
9001+ mtctr == 0x7D8903A6U &&
9002+ (li3 & 0xFFFF0000U) == 0x39800000U &&
9003+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
9004+ bctr == 0x4E800420U)
9005+ {
9006+ regs->gpr[PT_R11] =
9007+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9008+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9009+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
9010+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9011+ regs->ctr += (addis2 & 0xFFFFU) << 16;
9012+ regs->nip = regs->ctr;
9013+ return 4;
9014+ }
9015+ }
9016+ } while (0);
9017+#endif
9018+
9019+ do { /* PaX: unpatched PLT emulation #3 */
9020+ unsigned int li, b;
9021+
9022+ err = get_user(li, (unsigned int *)regs->nip);
9023+ err |= get_user(b, (unsigned int *)(regs->nip+4));
9024+
9025+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
9026+ unsigned int addis, lwz, mtctr, bctr;
9027+ unsigned long addr = b | 0xFC000000UL;
9028+
9029+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
9030+ err = get_user(addis, (unsigned int *)addr);
9031+ err |= get_user(lwz, (unsigned int *)(addr+4));
9032+ err |= get_user(mtctr, (unsigned int *)(addr+8));
9033+ err |= get_user(bctr, (unsigned int *)(addr+12));
9034+
9035+ if (err)
9036+ break;
9037+
9038+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
9039+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
9040+ mtctr == 0x7D6903A6U &&
9041+ bctr == 0x4E800420U)
9042+ {
9043+ unsigned int r11;
9044+
9045+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9046+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
9047+
9048+ err = get_user(r11, (unsigned int *)addr);
9049+ if (err)
9050+ break;
9051+
9052+ regs->gpr[PT_R11] = r11;
9053+ regs->ctr = r11;
9054+ regs->nip = r11;
9055+ return 4;
9056+ }
9057+ }
9058+ } while (0);
9059+#endif
9060+
9061+#ifdef CONFIG_PAX_EMUSIGRT
9062+ do { /* PaX: sigreturn emulation */
9063+ unsigned int li, sc;
9064+
9065+ err = get_user(li, (unsigned int *)regs->nip);
9066+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9067+
9068+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
9069+ struct vm_area_struct *vma;
9070+ unsigned long call_syscall;
9071+
9072+ down_read(&current->mm->mmap_sem);
9073+ call_syscall = current->mm->call_syscall;
9074+ up_read(&current->mm->mmap_sem);
9075+ if (likely(call_syscall))
9076+ goto emulate;
9077+
9078+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9079+
9080+ down_write(&current->mm->mmap_sem);
9081+ if (current->mm->call_syscall) {
9082+ call_syscall = current->mm->call_syscall;
9083+ up_write(&current->mm->mmap_sem);
9084+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9085+ goto emulate;
9086+ }
9087+
9088+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9089+ if (!vma || (call_syscall & ~PAGE_MASK)) {
9090+ up_write(&current->mm->mmap_sem);
9091+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9092+ return 1;
9093+ }
9094+
9095+ if (pax_insert_vma(vma, call_syscall)) {
9096+ up_write(&current->mm->mmap_sem);
9097+ kmem_cache_free(vm_area_cachep, vma);
9098+ return 1;
9099+ }
9100+
9101+ current->mm->call_syscall = call_syscall;
9102+ up_write(&current->mm->mmap_sem);
9103+
9104+emulate:
9105+ regs->gpr[PT_R0] = __NR_sigreturn;
9106+ regs->nip = call_syscall;
9107+ return 5;
9108+ }
9109+ } while (0);
9110+
9111+ do { /* PaX: rt_sigreturn emulation */
9112+ unsigned int li, sc;
9113+
9114+ err = get_user(li, (unsigned int *)regs->nip);
9115+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
9116+
9117+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
9118+ struct vm_area_struct *vma;
9119+ unsigned int call_syscall;
9120+
9121+ down_read(&current->mm->mmap_sem);
9122+ call_syscall = current->mm->call_syscall;
9123+ up_read(&current->mm->mmap_sem);
9124+ if (likely(call_syscall))
9125+ goto rt_emulate;
9126+
9127+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9128+
9129+ down_write(&current->mm->mmap_sem);
9130+ if (current->mm->call_syscall) {
9131+ call_syscall = current->mm->call_syscall;
9132+ up_write(&current->mm->mmap_sem);
9133+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9134+ goto rt_emulate;
9135+ }
9136+
9137+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9138+ if (!vma || (call_syscall & ~PAGE_MASK)) {
9139+ up_write(&current->mm->mmap_sem);
9140+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9141+ return 1;
9142+ }
9143+
9144+ if (pax_insert_vma(vma, call_syscall)) {
9145+ up_write(&current->mm->mmap_sem);
9146+ kmem_cache_free(vm_area_cachep, vma);
9147+ return 1;
9148+ }
9149+
9150+ current->mm->call_syscall = call_syscall;
9151+ up_write(&current->mm->mmap_sem);
9152+
9153+rt_emulate:
9154+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
9155+ regs->nip = call_syscall;
9156+ return 6;
9157+ }
9158+ } while (0);
9159+#endif
9160+
9161+ return 1;
9162+}
9163+
9164+void pax_report_insns(void *pc, void *sp)
9165+{
9166+ unsigned long i;
9167+
9168+ printk(KERN_ERR "PAX: bytes at PC: ");
9169+ for (i = 0; i < 5; i++) {
9170+ unsigned int c;
9171+ if (get_user(c, (unsigned int *)pc+i))
9172+ printk("???????? ");
9173+ else
9174+ printk("%08x ", c);
9175+ }
9176+ printk("\n");
9177+}
9178+#endif
9179+
9180 /*
9181 * Check whether the instruction at regs->nip is a store using
9182 * an update addressing form which will update r1.
9183@@ -108,7 +471,7 @@ int do_page_fault(struct pt_regs *regs,
9184 * indicate errors in DSISR but can validly be set in SRR1.
9185 */
9186 if (TRAP(regs) == 0x400)
9187- error_code &= 0x48200000;
9188+ error_code &= 0x58200000;
9189 else
9190 is_write = error_code & 0x02000000;
9191 #endif /* CONFIG_4xx || CONFIG_BOOKE */
9192@@ -203,15 +566,14 @@ good_area:
9193 pte_t *ptep;
9194 pmd_t *pmdp;
9195
9196-#if 0
9197+#if 1
9198 /* It would be nice to actually enforce the VM execute
9199 permission on CPUs which can do so, but far too
9200 much stuff in userspace doesn't get the permissions
9201 right, so we let any page be executed for now. */
9202 if (! (vma->vm_flags & VM_EXEC))
9203 goto bad_area;
9204-#endif
9205-
9206+#else
9207 /* Since 4xx/Book-E supports per-page execute permission,
9208 * we lazily flush dcache to icache. */
9209 ptep = NULL;
9210@@ -234,6 +596,7 @@ good_area:
9211 pte_unmap_unlock(ptep, ptl);
9212 }
9213 #endif
9214+#endif
9215 /* a read */
9216 } else {
9217 /* protection fault */
9218@@ -279,6 +642,33 @@ bad_area:
9219
9220 /* User mode accesses cause a SIGSEGV */
9221 if (user_mode(regs)) {
9222+
9223+#ifdef CONFIG_PAX_PAGEEXEC
9224+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
9225+ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
9226+ switch (pax_handle_fetch_fault(regs)) {
9227+
9228+#ifdef CONFIG_PAX_EMUPLT
9229+ case 2:
9230+ case 3:
9231+ case 4:
9232+ return 0;
9233+#endif
9234+
9235+#ifdef CONFIG_PAX_EMUSIGRT
9236+ case 5:
9237+ case 6:
9238+ return 0;
9239+#endif
9240+
9241+ }
9242+
9243+ pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[1]);
9244+ do_exit(SIGKILL);
9245+ }
9246+ }
9247+#endif
9248+
9249 _exception(SIGSEGV, regs, code, address);
9250 return 0;
9251 }
9252diff -urNp linux-2.6.22.1/arch/s390/kernel/module.c linux-2.6.22.1/arch/s390/kernel/module.c
9253--- linux-2.6.22.1/arch/s390/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
9254+++ linux-2.6.22.1/arch/s390/kernel/module.c 2007-08-02 11:38:46.000000000 -0400
9255@@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
9256
9257 /* Increase core size by size of got & plt and set start
9258 offsets for got and plt. */
9259- me->core_size = ALIGN(me->core_size, 4);
9260- me->arch.got_offset = me->core_size;
9261- me->core_size += me->arch.got_size;
9262- me->arch.plt_offset = me->core_size;
9263- me->core_size += me->arch.plt_size;
9264+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
9265+ me->arch.got_offset = me->core_size_rw;
9266+ me->core_size_rw += me->arch.got_size;
9267+ me->arch.plt_offset = me->core_size_rx;
9268+ me->core_size_rx += me->arch.plt_size;
9269 return 0;
9270 }
9271
9272@@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9273 if (info->got_initialized == 0) {
9274 Elf_Addr *gotent;
9275
9276- gotent = me->module_core + me->arch.got_offset +
9277+ gotent = me->module_core_rw + me->arch.got_offset +
9278 info->got_offset;
9279 *gotent = val;
9280 info->got_initialized = 1;
9281@@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9282 else if (r_type == R_390_GOTENT ||
9283 r_type == R_390_GOTPLTENT)
9284 *(unsigned int *) loc =
9285- (val + (Elf_Addr) me->module_core - loc) >> 1;
9286+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
9287 else if (r_type == R_390_GOT64 ||
9288 r_type == R_390_GOTPLT64)
9289 *(unsigned long *) loc = val;
9290@@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9291 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
9292 if (info->plt_initialized == 0) {
9293 unsigned int *ip;
9294- ip = me->module_core + me->arch.plt_offset +
9295+ ip = me->module_core_rx + me->arch.plt_offset +
9296 info->plt_offset;
9297 #ifndef CONFIG_64BIT
9298 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
9299@@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9300 val = me->arch.plt_offset - me->arch.got_offset +
9301 info->plt_offset + rela->r_addend;
9302 else
9303- val = (Elf_Addr) me->module_core +
9304+ val = (Elf_Addr) me->module_core_rx +
9305 me->arch.plt_offset + info->plt_offset +
9306 rela->r_addend - loc;
9307 if (r_type == R_390_PLT16DBL)
9308@@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9309 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
9310 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
9311 val = val + rela->r_addend -
9312- ((Elf_Addr) me->module_core + me->arch.got_offset);
9313+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
9314 if (r_type == R_390_GOTOFF16)
9315 *(unsigned short *) loc = val;
9316 else if (r_type == R_390_GOTOFF32)
9317@@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
9318 break;
9319 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
9320 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
9321- val = (Elf_Addr) me->module_core + me->arch.got_offset +
9322+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
9323 rela->r_addend - loc;
9324 if (r_type == R_390_GOTPC)
9325 *(unsigned int *) loc = val;
9326diff -urNp linux-2.6.22.1/arch/sparc/kernel/ptrace.c linux-2.6.22.1/arch/sparc/kernel/ptrace.c
9327--- linux-2.6.22.1/arch/sparc/kernel/ptrace.c 2007-07-10 14:56:30.000000000 -0400
9328+++ linux-2.6.22.1/arch/sparc/kernel/ptrace.c 2007-08-02 11:09:14.000000000 -0400
9329@@ -20,6 +20,7 @@
9330 #include <linux/security.h>
9331 #include <linux/signal.h>
9332 #include <linux/vs_base.h>
9333+#include <linux/grsecurity.h>
9334
9335 #include <asm/pgtable.h>
9336 #include <asm/system.h>
9337@@ -303,6 +304,11 @@ asmlinkage void do_ptrace(struct pt_regs
9338 goto out_tsk;
9339 }
9340
9341+ if (gr_handle_ptrace(child, request)) {
9342+ pt_error_return(regs, EPERM);
9343+ goto out_tsk;
9344+ }
9345+
9346 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
9347 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
9348 if (ptrace_attach(child)) {
9349diff -urNp linux-2.6.22.1/arch/sparc/kernel/sys_sparc.c linux-2.6.22.1/arch/sparc/kernel/sys_sparc.c
9350--- linux-2.6.22.1/arch/sparc/kernel/sys_sparc.c 2007-07-10 14:56:30.000000000 -0400
9351+++ linux-2.6.22.1/arch/sparc/kernel/sys_sparc.c 2007-08-02 11:38:46.000000000 -0400
9352@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
9353 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
9354 return -ENOMEM;
9355 if (!addr)
9356- addr = TASK_UNMAPPED_BASE;
9357+ addr = current->mm->mmap_base;
9358
9359 if (flags & MAP_SHARED)
9360 addr = COLOUR_ALIGN(addr);
9361diff -urNp linux-2.6.22.1/arch/sparc/Makefile linux-2.6.22.1/arch/sparc/Makefile
9362--- linux-2.6.22.1/arch/sparc/Makefile 2007-07-10 14:56:30.000000000 -0400
9363+++ linux-2.6.22.1/arch/sparc/Makefile 2007-08-02 11:09:14.000000000 -0400
9364@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
9365 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
9366 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
9367 CORE_Y := $(core-y)
9368-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
9369+CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
9370 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
9371 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
9372 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
9373diff -urNp linux-2.6.22.1/arch/sparc/mm/fault.c linux-2.6.22.1/arch/sparc/mm/fault.c
9374--- linux-2.6.22.1/arch/sparc/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
9375+++ linux-2.6.22.1/arch/sparc/mm/fault.c 2007-08-02 11:38:46.000000000 -0400
9376@@ -21,6 +21,10 @@
9377 #include <linux/interrupt.h>
9378 #include <linux/module.h>
9379 #include <linux/kdebug.h>
9380+#include <linux/slab.h>
9381+#include <linux/pagemap.h>
9382+#include <linux/compiler.h>
9383+#include <linux/binfmts.h>
9384
9385 #include <asm/system.h>
9386 #include <asm/page.h>
9387@@ -216,6 +220,252 @@ static unsigned long compute_si_addr(str
9388 return safe_compute_effective_address(regs, insn);
9389 }
9390
9391+#ifdef CONFIG_PAX_PAGEEXEC
9392+void pax_emuplt_close(struct vm_area_struct *vma)
9393+{
9394+ vma->vm_mm->call_dl_resolve = 0UL;
9395+}
9396+
9397+static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9398+{
9399+ struct page *page;
9400+ unsigned int *kaddr;
9401+
9402+ page = alloc_page(GFP_HIGHUSER);
9403+ if (!page)
9404+ return NOPAGE_OOM;
9405+
9406+ kaddr = kmap(page);
9407+ memset(kaddr, 0, PAGE_SIZE);
9408+ kaddr[0] = 0x9DE3BFA8U; /* save */
9409+ flush_dcache_page(page);
9410+ kunmap(page);
9411+ if (type)
9412+ *type = VM_FAULT_MAJOR;
9413+
9414+ return page;
9415+}
9416+
9417+static struct vm_operations_struct pax_vm_ops = {
9418+ .close = pax_emuplt_close,
9419+ .nopage = pax_emuplt_nopage,
9420+};
9421+
9422+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9423+{
9424+ int ret;
9425+
9426+ memset(vma, 0, sizeof(*vma));
9427+ vma->vm_mm = current->mm;
9428+ vma->vm_start = addr;
9429+ vma->vm_end = addr + PAGE_SIZE;
9430+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9431+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
9432+ vma->vm_ops = &pax_vm_ops;
9433+
9434+ ret = insert_vm_struct(current->mm, vma);
9435+ if (ret)
9436+ return ret;
9437+
9438+ ++current->mm->total_vm;
9439+ return 0;
9440+}
9441+
9442+/*
9443+ * PaX: decide what to do with offenders (regs->pc = fault address)
9444+ *
9445+ * returns 1 when task should be killed
9446+ * 2 when patched PLT trampoline was detected
9447+ * 3 when unpatched PLT trampoline was detected
9448+ */
9449+static int pax_handle_fetch_fault(struct pt_regs *regs)
9450+{
9451+
9452+#ifdef CONFIG_PAX_EMUPLT
9453+ int err;
9454+
9455+ do { /* PaX: patched PLT emulation #1 */
9456+ unsigned int sethi1, sethi2, jmpl;
9457+
9458+ err = get_user(sethi1, (unsigned int *)regs->pc);
9459+ err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
9460+ err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
9461+
9462+ if (err)
9463+ break;
9464+
9465+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9466+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
9467+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
9468+ {
9469+ unsigned int addr;
9470+
9471+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
9472+ addr = regs->u_regs[UREG_G1];
9473+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
9474+ regs->pc = addr;
9475+ regs->npc = addr+4;
9476+ return 2;
9477+ }
9478+ } while (0);
9479+
9480+ { /* PaX: patched PLT emulation #2 */
9481+ unsigned int ba;
9482+
9483+ err = get_user(ba, (unsigned int *)regs->pc);
9484+
9485+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
9486+ unsigned int addr;
9487+
9488+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
9489+ regs->pc = addr;
9490+ regs->npc = addr+4;
9491+ return 2;
9492+ }
9493+ }
9494+
9495+ do { /* PaX: patched PLT emulation #3 */
9496+ unsigned int sethi, jmpl, nop;
9497+
9498+ err = get_user(sethi, (unsigned int *)regs->pc);
9499+ err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
9500+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
9501+
9502+ if (err)
9503+ break;
9504+
9505+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9506+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
9507+ nop == 0x01000000U)
9508+ {
9509+ unsigned int addr;
9510+
9511+ addr = (sethi & 0x003FFFFFU) << 10;
9512+ regs->u_regs[UREG_G1] = addr;
9513+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
9514+ regs->pc = addr;
9515+ regs->npc = addr+4;
9516+ return 2;
9517+ }
9518+ } while (0);
9519+
9520+ do { /* PaX: unpatched PLT emulation step 1 */
9521+ unsigned int sethi, ba, nop;
9522+
9523+ err = get_user(sethi, (unsigned int *)regs->pc);
9524+ err |= get_user(ba, (unsigned int *)(regs->pc+4));
9525+ err |= get_user(nop, (unsigned int *)(regs->pc+8));
9526+
9527+ if (err)
9528+ break;
9529+
9530+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9531+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
9532+ nop == 0x01000000U)
9533+ {
9534+ unsigned int addr, save, call;
9535+
9536+ if ((ba & 0xFFC00000U) == 0x30800000U)
9537+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
9538+ else
9539+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
9540+
9541+ err = get_user(save, (unsigned int *)addr);
9542+ err |= get_user(call, (unsigned int *)(addr+4));
9543+ err |= get_user(nop, (unsigned int *)(addr+8));
9544+ if (err)
9545+ break;
9546+
9547+ if (save == 0x9DE3BFA8U &&
9548+ (call & 0xC0000000U) == 0x40000000U &&
9549+ nop == 0x01000000U)
9550+ {
9551+ struct vm_area_struct *vma;
9552+ unsigned long call_dl_resolve;
9553+
9554+ down_read(&current->mm->mmap_sem);
9555+ call_dl_resolve = current->mm->call_dl_resolve;
9556+ up_read(&current->mm->mmap_sem);
9557+ if (likely(call_dl_resolve))
9558+ goto emulate;
9559+
9560+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9561+
9562+ down_write(&current->mm->mmap_sem);
9563+ if (current->mm->call_dl_resolve) {
9564+ call_dl_resolve = current->mm->call_dl_resolve;
9565+ up_write(&current->mm->mmap_sem);
9566+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9567+ goto emulate;
9568+ }
9569+
9570+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9571+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
9572+ up_write(&current->mm->mmap_sem);
9573+ if (vma) kmem_cache_free(vm_area_cachep, vma);
9574+ return 1;
9575+ }
9576+
9577+ if (pax_insert_vma(vma, call_dl_resolve)) {
9578+ up_write(&current->mm->mmap_sem);
9579+ kmem_cache_free(vm_area_cachep, vma);
9580+ return 1;
9581+ }
9582+
9583+ current->mm->call_dl_resolve = call_dl_resolve;
9584+ up_write(&current->mm->mmap_sem);
9585+
9586+emulate:
9587+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
9588+ regs->pc = call_dl_resolve;
9589+ regs->npc = addr+4;
9590+ return 3;
9591+ }
9592+ }
9593+ } while (0);
9594+
9595+ do { /* PaX: unpatched PLT emulation step 2 */
9596+ unsigned int save, call, nop;
9597+
9598+ err = get_user(save, (unsigned int *)(regs->pc-4));
9599+ err |= get_user(call, (unsigned int *)regs->pc);
9600+ err |= get_user(nop, (unsigned int *)(regs->pc+4));
9601+ if (err)
9602+ break;
9603+
9604+ if (save == 0x9DE3BFA8U &&
9605+ (call & 0xC0000000U) == 0x40000000U &&
9606+ nop == 0x01000000U)
9607+ {
9608+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
9609+
9610+ regs->u_regs[UREG_RETPC] = regs->pc;
9611+ regs->pc = dl_resolve;
9612+ regs->npc = dl_resolve+4;
9613+ return 3;
9614+ }
9615+ } while (0);
9616+#endif
9617+
9618+ return 1;
9619+}
9620+
9621+void pax_report_insns(void *pc, void *sp)
9622+{
9623+ unsigned long i;
9624+
9625+ printk(KERN_ERR "PAX: bytes at PC: ");
9626+ for (i = 0; i < 5; i++) {
9627+ unsigned int c;
9628+ if (get_user(c, (unsigned int *)pc+i))
9629+ printk("???????? ");
9630+ else
9631+ printk("%08x ", c);
9632+ }
9633+ printk("\n");
9634+}
9635+#endif
9636+
9637 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
9638 unsigned long address)
9639 {
9640@@ -279,6 +529,24 @@ good_area:
9641 if(!(vma->vm_flags & VM_WRITE))
9642 goto bad_area;
9643 } else {
9644+
9645+#ifdef CONFIG_PAX_PAGEEXEC
9646+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
9647+ up_read(&mm->mmap_sem);
9648+ switch (pax_handle_fetch_fault(regs)) {
9649+
9650+#ifdef CONFIG_PAX_EMUPLT
9651+ case 2:
9652+ case 3:
9653+ return;
9654+#endif
9655+
9656+ }
9657+ pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
9658+ do_exit(SIGKILL);
9659+ }
9660+#endif
9661+
9662 /* Allow reads even for write-only mappings */
9663 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
9664 goto bad_area;
9665diff -urNp linux-2.6.22.1/arch/sparc/mm/init.c linux-2.6.22.1/arch/sparc/mm/init.c
9666--- linux-2.6.22.1/arch/sparc/mm/init.c 2007-07-10 14:56:30.000000000 -0400
9667+++ linux-2.6.22.1/arch/sparc/mm/init.c 2007-08-02 11:38:46.000000000 -0400
9668@@ -333,17 +333,17 @@ void __init paging_init(void)
9669
9670 /* Initialize the protection map with non-constant, MMU dependent values. */
9671 protection_map[0] = PAGE_NONE;
9672- protection_map[1] = PAGE_READONLY;
9673- protection_map[2] = PAGE_COPY;
9674- protection_map[3] = PAGE_COPY;
9675+ protection_map[1] = PAGE_READONLY_NOEXEC;
9676+ protection_map[2] = PAGE_COPY_NOEXEC;
9677+ protection_map[3] = PAGE_COPY_NOEXEC;
9678 protection_map[4] = PAGE_READONLY;
9679 protection_map[5] = PAGE_READONLY;
9680 protection_map[6] = PAGE_COPY;
9681 protection_map[7] = PAGE_COPY;
9682 protection_map[8] = PAGE_NONE;
9683- protection_map[9] = PAGE_READONLY;
9684- protection_map[10] = PAGE_SHARED;
9685- protection_map[11] = PAGE_SHARED;
9686+ protection_map[9] = PAGE_READONLY_NOEXEC;
9687+ protection_map[10] = PAGE_SHARED_NOEXEC;
9688+ protection_map[11] = PAGE_SHARED_NOEXEC;
9689 protection_map[12] = PAGE_READONLY;
9690 protection_map[13] = PAGE_READONLY;
9691 protection_map[14] = PAGE_SHARED;
9692diff -urNp linux-2.6.22.1/arch/sparc/mm/srmmu.c linux-2.6.22.1/arch/sparc/mm/srmmu.c
9693--- linux-2.6.22.1/arch/sparc/mm/srmmu.c 2007-07-10 14:56:30.000000000 -0400
9694+++ linux-2.6.22.1/arch/sparc/mm/srmmu.c 2007-08-02 11:38:46.000000000 -0400
9695@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
9696 BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
9697 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
9698 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
9699+
9700+#ifdef CONFIG_PAX_PAGEEXEC
9701+ BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
9702+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
9703+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
9704+#endif
9705+
9706 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
9707 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
9708
9709diff -urNp linux-2.6.22.1/arch/sparc64/kernel/ptrace.c linux-2.6.22.1/arch/sparc64/kernel/ptrace.c
9710--- linux-2.6.22.1/arch/sparc64/kernel/ptrace.c 2007-07-10 14:56:30.000000000 -0400
9711+++ linux-2.6.22.1/arch/sparc64/kernel/ptrace.c 2007-08-02 11:09:14.000000000 -0400
9712@@ -23,6 +23,7 @@
9713 #include <linux/audit.h>
9714 #include <linux/signal.h>
9715 #include <linux/vs_base.h>
9716+#include <linux/grsecurity.h>
9717
9718 #include <asm/asi.h>
9719 #include <asm/pgtable.h>
9720@@ -216,6 +217,11 @@ asmlinkage void do_ptrace(struct pt_regs
9721 goto out_tsk;
9722 }
9723
9724+ if (gr_handle_ptrace(child, (long)request)) {
9725+ pt_error_return(regs, EPERM);
9726+ goto out_tsk;
9727+ }
9728+
9729 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
9730 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
9731 if (ptrace_attach(child)) {
9732diff -urNp linux-2.6.22.1/arch/sparc64/kernel/sys_sparc.c linux-2.6.22.1/arch/sparc64/kernel/sys_sparc.c
9733--- linux-2.6.22.1/arch/sparc64/kernel/sys_sparc.c 2007-07-10 14:56:30.000000000 -0400
9734+++ linux-2.6.22.1/arch/sparc64/kernel/sys_sparc.c 2007-08-02 11:38:46.000000000 -0400
9735@@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
9736 /* We do not accept a shared mapping if it would violate
9737 * cache aliasing constraints.
9738 */
9739- if ((flags & MAP_SHARED) &&
9740+ if ((filp || (flags & MAP_SHARED)) &&
9741 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
9742 return -EINVAL;
9743 return addr;
9744@@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
9745 if (filp || (flags & MAP_SHARED))
9746 do_color_align = 1;
9747
9748+#ifdef CONFIG_PAX_RANDMMAP
9749+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9750+#endif
9751+
9752 if (addr) {
9753 if (do_color_align)
9754 addr = COLOUR_ALIGN(addr, pgoff);
9755@@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
9756 }
9757
9758 if (len > mm->cached_hole_size) {
9759- start_addr = addr = mm->free_area_cache;
9760+ start_addr = addr = mm->free_area_cache;
9761 } else {
9762- start_addr = addr = TASK_UNMAPPED_BASE;
9763+ start_addr = addr = mm->mmap_base;
9764 mm->cached_hole_size = 0;
9765 }
9766
9767@@ -174,8 +178,8 @@ full_search:
9768 vma = find_vma(mm, VA_EXCLUDE_END);
9769 }
9770 if (unlikely(task_size < addr)) {
9771- if (start_addr != TASK_UNMAPPED_BASE) {
9772- start_addr = addr = TASK_UNMAPPED_BASE;
9773+ if (start_addr != mm->mmap_base) {
9774+ start_addr = addr = mm->mmap_base;
9775 mm->cached_hole_size = 0;
9776 goto full_search;
9777 }
9778@@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
9779 /* We do not accept a shared mapping if it would violate
9780 * cache aliasing constraints.
9781 */
9782- if ((flags & MAP_SHARED) &&
9783+ if ((filp || (flags & MAP_SHARED)) &&
9784 ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
9785 return -EINVAL;
9786 return addr;
9787@@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
9788 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
9789 sysctl_legacy_va_layout) {
9790 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
9791+
9792+#ifdef CONFIG_PAX_RANDMMAP
9793+ if (mm->pax_flags & MF_PAX_RANDMMAP)
9794+ mm->mmap_base += mm->delta_mmap;
9795+#endif
9796+
9797 mm->get_unmapped_area = arch_get_unmapped_area;
9798 mm->unmap_area = arch_unmap_area;
9799 } else {
9800@@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
9801 gap = (task_size / 6 * 5);
9802
9803 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
9804+
9805+#ifdef CONFIG_PAX_RANDMMAP
9806+ if (mm->pax_flags & MF_PAX_RANDMMAP)
9807+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9808+#endif
9809+
9810 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9811 mm->unmap_area = arch_unmap_area_topdown;
9812 }
9813diff -urNp linux-2.6.22.1/arch/sparc64/mm/fault.c linux-2.6.22.1/arch/sparc64/mm/fault.c
9814--- linux-2.6.22.1/arch/sparc64/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
9815+++ linux-2.6.22.1/arch/sparc64/mm/fault.c 2007-08-02 11:38:46.000000000 -0400
9816@@ -20,6 +20,10 @@
9817 #include <linux/kprobes.h>
9818 #include <linux/kallsyms.h>
9819 #include <linux/kdebug.h>
9820+#include <linux/slab.h>
9821+#include <linux/pagemap.h>
9822+#include <linux/compiler.h>
9823+#include <linux/binfmts.h>
9824
9825 #include <asm/page.h>
9826 #include <asm/pgtable.h>
9827@@ -273,6 +277,369 @@ cannot_handle:
9828 unhandled_fault (address, current, regs);
9829 }
9830
9831+#ifdef CONFIG_PAX_PAGEEXEC
9832+#ifdef CONFIG_PAX_EMUPLT
9833+static void pax_emuplt_close(struct vm_area_struct *vma)
9834+{
9835+ vma->vm_mm->call_dl_resolve = 0UL;
9836+}
9837+
9838+static struct page *pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9839+{
9840+ struct page *page;
9841+ unsigned int *kaddr;
9842+
9843+ page = alloc_page(GFP_HIGHUSER);
9844+ if (!page)
9845+ return NOPAGE_OOM;
9846+
9847+ kaddr = kmap(page);
9848+ memset(kaddr, 0, PAGE_SIZE);
9849+ kaddr[0] = 0x9DE3BFA8U; /* save */
9850+ flush_dcache_page(page);
9851+ kunmap(page);
9852+ if (type)
9853+ *type = VM_FAULT_MAJOR;
9854+ return page;
9855+}
9856+
9857+static struct vm_operations_struct pax_vm_ops = {
9858+ .close = pax_emuplt_close,
9859+ .nopage = pax_emuplt_nopage,
9860+};
9861+
9862+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9863+{
9864+ int ret;
9865+
9866+ memset(vma, 0, sizeof(*vma));
9867+ vma->vm_mm = current->mm;
9868+ vma->vm_start = addr;
9869+ vma->vm_end = addr + PAGE_SIZE;
9870+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9871+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
9872+ vma->vm_ops = &pax_vm_ops;
9873+
9874+ ret = insert_vm_struct(current->mm, vma);
9875+ if (ret)
9876+ return ret;
9877+
9878+ ++current->mm->total_vm;
9879+ return 0;
9880+}
9881+#endif
9882+
9883+/*
9884+ * PaX: decide what to do with offenders (regs->tpc = fault address)
9885+ *
9886+ * returns 1 when task should be killed
9887+ * 2 when patched PLT trampoline was detected
9888+ * 3 when unpatched PLT trampoline was detected
9889+ */
9890+static int pax_handle_fetch_fault(struct pt_regs *regs)
9891+{
9892+
9893+#ifdef CONFIG_PAX_EMUPLT
9894+ int err;
9895+
9896+ do { /* PaX: patched PLT emulation #1 */
9897+ unsigned int sethi1, sethi2, jmpl;
9898+
9899+ err = get_user(sethi1, (unsigned int *)regs->tpc);
9900+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
9901+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
9902+
9903+ if (err)
9904+ break;
9905+
9906+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9907+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
9908+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
9909+ {
9910+ unsigned long addr;
9911+
9912+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
9913+ addr = regs->u_regs[UREG_G1];
9914+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9915+ regs->tpc = addr;
9916+ regs->tnpc = addr+4;
9917+ return 2;
9918+ }
9919+ } while (0);
9920+
9921+ { /* PaX: patched PLT emulation #2 */
9922+ unsigned int ba;
9923+
9924+ err = get_user(ba, (unsigned int *)regs->tpc);
9925+
9926+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
9927+ unsigned long addr;
9928+
9929+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9930+ regs->tpc = addr;
9931+ regs->tnpc = addr+4;
9932+ return 2;
9933+ }
9934+ }
9935+
9936+ do { /* PaX: patched PLT emulation #3 */
9937+ unsigned int sethi, jmpl, nop;
9938+
9939+ err = get_user(sethi, (unsigned int *)regs->tpc);
9940+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
9941+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
9942+
9943+ if (err)
9944+ break;
9945+
9946+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
9947+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
9948+ nop == 0x01000000U)
9949+ {
9950+ unsigned long addr;
9951+
9952+ addr = (sethi & 0x003FFFFFU) << 10;
9953+ regs->u_regs[UREG_G1] = addr;
9954+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9955+ regs->tpc = addr;
9956+ regs->tnpc = addr+4;
9957+ return 2;
9958+ }
9959+ } while (0);
9960+
9961+ do { /* PaX: patched PLT emulation #4 */
9962+ unsigned int mov1, call, mov2;
9963+
9964+ err = get_user(mov1, (unsigned int *)regs->tpc);
9965+ err |= get_user(call, (unsigned int *)(regs->tpc+4));
9966+ err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
9967+
9968+ if (err)
9969+ break;
9970+
9971+ if (mov1 == 0x8210000FU &&
9972+ (call & 0xC0000000U) == 0x40000000U &&
9973+ mov2 == 0x9E100001U)
9974+ {
9975+ unsigned long addr;
9976+
9977+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
9978+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
9979+ regs->tpc = addr;
9980+ regs->tnpc = addr+4;
9981+ return 2;
9982+ }
9983+ } while (0);
9984+
9985+ do { /* PaX: patched PLT emulation #5 */
9986+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
9987+
9988+ err = get_user(sethi1, (unsigned int *)regs->tpc);
9989+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
9990+ err |= get_user(or1, (unsigned int *)(regs->tpc+8));
9991+ err |= get_user(or2, (unsigned int *)(regs->tpc+12));
9992+ err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
9993+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
9994+ err |= get_user(nop, (unsigned int *)(regs->tpc+24));
9995+
9996+ if (err)
9997+ break;
9998+
9999+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
10000+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
10001+ (or1 & 0xFFFFE000U) == 0x82106000U &&
10002+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
10003+ sllx == 0x83287020 &&
10004+ jmpl == 0x81C04005U &&
10005+ nop == 0x01000000U)
10006+ {
10007+ unsigned long addr;
10008+
10009+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
10010+ regs->u_regs[UREG_G1] <<= 32;
10011+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
10012+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
10013+ regs->tpc = addr;
10014+ regs->tnpc = addr+4;
10015+ return 2;
10016+ }
10017+ } while (0);
10018+
10019+ do { /* PaX: patched PLT emulation #6 */
10020+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
10021+
10022+ err = get_user(sethi1, (unsigned int *)regs->tpc);
10023+ err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
10024+ err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
10025+ err |= get_user(or, (unsigned int *)(regs->tpc+12));
10026+ err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
10027+ err |= get_user(nop, (unsigned int *)(regs->tpc+20));
10028+
10029+ if (err)
10030+ break;
10031+
10032+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
10033+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
10034+ sllx == 0x83287020 &&
10035+ (or & 0xFFFFE000U) == 0x8A116000U &&
10036+ jmpl == 0x81C04005U &&
10037+ nop == 0x01000000U)
10038+ {
10039+ unsigned long addr;
10040+
10041+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
10042+ regs->u_regs[UREG_G1] <<= 32;
10043+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
10044+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
10045+ regs->tpc = addr;
10046+ regs->tnpc = addr+4;
10047+ return 2;
10048+ }
10049+ } while (0);
10050+
10051+ do { /* PaX: patched PLT emulation #7 */
10052+ unsigned int sethi, ba, nop;
10053+
10054+ err = get_user(sethi, (unsigned int *)regs->tpc);
10055+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
10056+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
10057+
10058+ if (err)
10059+ break;
10060+
10061+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10062+ (ba & 0xFFF00000U) == 0x30600000U &&
10063+ nop == 0x01000000U)
10064+ {
10065+ unsigned long addr;
10066+
10067+ addr = (sethi & 0x003FFFFFU) << 10;
10068+ regs->u_regs[UREG_G1] = addr;
10069+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
10070+ regs->tpc = addr;
10071+ regs->tnpc = addr+4;
10072+ return 2;
10073+ }
10074+ } while (0);
10075+
10076+ do { /* PaX: unpatched PLT emulation step 1 */
10077+ unsigned int sethi, ba, nop;
10078+
10079+ err = get_user(sethi, (unsigned int *)regs->tpc);
10080+ err |= get_user(ba, (unsigned int *)(regs->tpc+4));
10081+ err |= get_user(nop, (unsigned int *)(regs->tpc+8));
10082+
10083+ if (err)
10084+ break;
10085+
10086+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
10087+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
10088+ nop == 0x01000000U)
10089+ {
10090+ unsigned long addr;
10091+ unsigned int save, call;
10092+
10093+ if ((ba & 0xFFC00000U) == 0x30800000U)
10094+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
10095+ else
10096+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
10097+
10098+ err = get_user(save, (unsigned int *)addr);
10099+ err |= get_user(call, (unsigned int *)(addr+4));
10100+ err |= get_user(nop, (unsigned int *)(addr+8));
10101+ if (err)
10102+ break;
10103+
10104+ if (save == 0x9DE3BFA8U &&
10105+ (call & 0xC0000000U) == 0x40000000U &&
10106+ nop == 0x01000000U)
10107+ {
10108+ struct vm_area_struct *vma;
10109+ unsigned long call_dl_resolve;
10110+
10111+ down_read(&current->mm->mmap_sem);
10112+ call_dl_resolve = current->mm->call_dl_resolve;
10113+ up_read(&current->mm->mmap_sem);
10114+ if (likely(call_dl_resolve))
10115+ goto emulate;
10116+
10117+ vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
10118+
10119+ down_write(&current->mm->mmap_sem);
10120+ if (current->mm->call_dl_resolve) {
10121+ call_dl_resolve = current->mm->call_dl_resolve;
10122+ up_write(&current->mm->mmap_sem);
10123+ if (vma) kmem_cache_free(vm_area_cachep, vma);
10124+ goto emulate;
10125+ }
10126+
10127+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
10128+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
10129+ up_write(&current->mm->mmap_sem);
10130+ if (vma) kmem_cache_free(vm_area_cachep, vma);
10131+ return 1;
10132+ }
10133+
10134+ if (pax_insert_vma(vma, call_dl_resolve)) {
10135+ up_write(&current->mm->mmap_sem);
10136+ kmem_cache_free(vm_area_cachep, vma);
10137+ return 1;
10138+ }
10139+
10140+ current->mm->call_dl_resolve = call_dl_resolve;
10141+ up_write(&current->mm->mmap_sem);
10142+
10143+emulate:
10144+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
10145+ regs->tpc = call_dl_resolve;
10146+ regs->tnpc = addr+4;
10147+ return 3;
10148+ }
10149+ }
10150+ } while (0);
10151+
10152+ do { /* PaX: unpatched PLT emulation step 2 */
10153+ unsigned int save, call, nop;
10154+
10155+ err = get_user(save, (unsigned int *)(regs->tpc-4));
10156+ err |= get_user(call, (unsigned int *)regs->tpc);
10157+ err |= get_user(nop, (unsigned int *)(regs->tpc+4));
10158+ if (err)
10159+ break;
10160+
10161+ if (save == 0x9DE3BFA8U &&
10162+ (call & 0xC0000000U) == 0x40000000U &&
10163+ nop == 0x01000000U)
10164+ {
10165+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
10166+
10167+ regs->u_regs[UREG_RETPC] = regs->tpc;
10168+ regs->tpc = dl_resolve;
10169+ regs->tnpc = dl_resolve+4;
10170+ return 3;
10171+ }
10172+ } while (0);
10173+#endif
10174+
10175+ return 1;
10176+}
10177+
10178+void pax_report_insns(void *pc, void *sp)
10179+{
10180+ unsigned long i;
10181+
10182+ printk(KERN_ERR "PAX: bytes at PC: ");
10183+ for (i = 0; i < 5; i++) {
10184+ unsigned int c;
10185+ if (get_user(c, (unsigned int *)pc+i))
10186+ printk("???????? ");
10187+ else
10188+ printk("%08x ", c);
10189+ }
10190+ printk("\n");
10191+}
10192+#endif
10193+
10194 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
10195 {
10196 struct mm_struct *mm = current->mm;
10197@@ -314,8 +681,10 @@ asmlinkage void __kprobes do_sparc64_fau
10198 goto intr_or_no_mm;
10199
10200 if (test_thread_flag(TIF_32BIT)) {
10201- if (!(regs->tstate & TSTATE_PRIV))
10202+ if (!(regs->tstate & TSTATE_PRIV)) {
10203 regs->tpc &= 0xffffffff;
10204+ regs->tnpc &= 0xffffffff;
10205+ }
10206 address &= 0xffffffff;
10207 }
10208
10209@@ -332,6 +701,29 @@ asmlinkage void __kprobes do_sparc64_fau
10210 if (!vma)
10211 goto bad_area;
10212
10213+#ifdef CONFIG_PAX_PAGEEXEC
10214+ /* PaX: detect ITLB misses on non-exec pages */
10215+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
10216+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
10217+ {
10218+ if (address != regs->tpc)
10219+ goto good_area;
10220+
10221+ up_read(&mm->mmap_sem);
10222+ switch (pax_handle_fetch_fault(regs)) {
10223+
10224+#ifdef CONFIG_PAX_EMUPLT
10225+ case 2:
10226+ case 3:
10227+ return;
10228+#endif
10229+
10230+ }
10231+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
10232+ do_exit(SIGKILL);
10233+ }
10234+#endif
10235+
10236 /* Pure DTLB misses do not tell us whether the fault causing
10237 * load/store/atomic was a write or not, it only says that there
10238 * was no match. So in such a case we (carefully) read the
10239diff -urNp linux-2.6.22.1/arch/sparc64/mm/Makefile linux-2.6.22.1/arch/sparc64/mm/Makefile
10240--- linux-2.6.22.1/arch/sparc64/mm/Makefile 2007-07-10 14:56:30.000000000 -0400
10241+++ linux-2.6.22.1/arch/sparc64/mm/Makefile 2007-08-02 11:38:46.000000000 -0400
10242@@ -3,7 +3,7 @@
10243 #
10244
10245 EXTRA_AFLAGS := -ansi
10246-EXTRA_CFLAGS := -Werror
10247+#EXTRA_CFLAGS := -Werror
10248
10249 obj-y := ultra.o tlb.o tsb.o fault.o init.o generic.o
10250
10251diff -urNp linux-2.6.22.1/arch/v850/kernel/module.c linux-2.6.22.1/arch/v850/kernel/module.c
10252--- linux-2.6.22.1/arch/v850/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
10253+++ linux-2.6.22.1/arch/v850/kernel/module.c 2007-08-02 11:38:46.000000000 -0400
10254@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
10255 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
10256
10257 /* Init, or core PLT? */
10258- if (location >= mod->module_core
10259- && location < mod->module_core + mod->core_size)
10260+ if (location >= mod->module_core_rx
10261+ && location < mod->module_core_rx + mod->core_size_rx)
10262 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
10263 else
10264 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
10265diff -urNp linux-2.6.22.1/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.22.1/arch/x86_64/ia32/ia32_binfmt.c
10266--- linux-2.6.22.1/arch/x86_64/ia32/ia32_binfmt.c 2007-07-10 14:56:30.000000000 -0400
10267+++ linux-2.6.22.1/arch/x86_64/ia32/ia32_binfmt.c 2007-08-02 11:38:46.000000000 -0400
10268@@ -143,6 +143,13 @@ struct elf_prpsinfo
10269 //#include <asm/ia32.h>
10270 #include <linux/elf.h>
10271
10272+#ifdef CONFIG_PAX_ASLR
10273+#define PAX_ELF_ET_DYN_BASE 0x08048000UL
10274+
10275+#define PAX_DELTA_MMAP_LEN 16
10276+#define PAX_DELTA_STACK_LEN 16
10277+#endif
10278+
10279 typedef struct user_i387_ia32_struct elf_fpregset_t;
10280 typedef struct user32_fxsr_struct elf_fpxregset_t;
10281
10282@@ -317,8 +324,20 @@ int ia32_setup_arg_pages(struct linux_bi
10283 mpnt->vm_flags = VM_STACK_FLAGS & ~VM_EXEC;
10284 else
10285 mpnt->vm_flags = VM_STACK_FLAGS;
10286- mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ?
10287- PAGE_COPY_EXEC : PAGE_COPY;
10288+
10289+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10290+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
10291+ mpnt->vm_flags &= ~VM_EXEC;
10292+
10293+#ifdef CONFIG_PAX_MPROTECT
10294+ if (mm->pax_flags & MF_PAX_MPROTECT)
10295+ mpnt->vm_flags &= ~VM_MAYEXEC;
10296+#endif
10297+
10298+ }
10299+#endif
10300+
10301+ mpnt->vm_page_prot = vm_get_page_prot(mpnt->vm_flags);
10302 if ((ret = insert_vm_struct(mm, mpnt))) {
10303 up_write(&mm->mmap_sem);
10304 kmem_cache_free(vm_area_cachep, mpnt);
10305@@ -329,15 +348,18 @@ int ia32_setup_arg_pages(struct linux_bi
10306
10307 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10308 struct page *page = bprm->page[i];
10309+ int retval;
10310 if (page) {
10311 bprm->page[i] = NULL;
10312- install_arg_page(mpnt, page, stack_base);
10313+ retval = install_arg_page(mpnt, page, stack_base);
10314+ if (!ret)
10315+ ret = retval;
10316 }
10317 stack_base += PAGE_SIZE;
10318 }
10319 up_write(&mm->mmap_sem);
10320-
10321- return 0;
10322+
10323+ return ret;
10324 }
10325 EXPORT_SYMBOL(ia32_setup_arg_pages);
10326
10327diff -urNp linux-2.6.22.1/arch/x86_64/ia32/mmap32.c linux-2.6.22.1/arch/x86_64/ia32/mmap32.c
10328--- linux-2.6.22.1/arch/x86_64/ia32/mmap32.c 2007-07-10 14:56:30.000000000 -0400
10329+++ linux-2.6.22.1/arch/x86_64/ia32/mmap32.c 2007-08-02 11:38:46.000000000 -0400
10330@@ -69,10 +69,22 @@ void ia32_pick_mmap_layout(struct mm_str
10331 (current->personality & ADDR_COMPAT_LAYOUT) ||
10332 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
10333 mm->mmap_base = TASK_UNMAPPED_BASE;
10334+
10335+#ifdef CONFIG_PAX_RANDMMAP
10336+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10337+ mm->mmap_base += mm->delta_mmap;
10338+#endif
10339+
10340 mm->get_unmapped_area = arch_get_unmapped_area;
10341 mm->unmap_area = arch_unmap_area;
10342 } else {
10343 mm->mmap_base = mmap_base(mm);
10344+
10345+#ifdef CONFIG_PAX_RANDMMAP
10346+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10347+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
10348+#endif
10349+
10350 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
10351 mm->unmap_area = arch_unmap_area_topdown;
10352 }
10353diff -urNp linux-2.6.22.1/arch/x86_64/kernel/hpet.c linux-2.6.22.1/arch/x86_64/kernel/hpet.c
10354--- linux-2.6.22.1/arch/x86_64/kernel/hpet.c 2007-07-10 14:56:30.000000000 -0400
10355+++ linux-2.6.22.1/arch/x86_64/kernel/hpet.c 2007-08-02 11:38:46.000000000 -0400
10356@@ -65,7 +65,7 @@ static __init int late_hpet_init(void)
10357 hpet = (struct hpet *) fix_to_virt(FIX_HPET_BASE);
10358 timer = &hpet->hpet_timers[2];
10359 for (i = 2; i < ntimer; timer++, i++)
10360- hd.hd_irq[i] = (timer->hpet_config &
10361+ hd.hd_irq[i] = (readl(&timer->hpet_config) &
10362 Tn_INT_ROUTE_CNF_MASK) >>
10363 Tn_INT_ROUTE_CNF_SHIFT;
10364
10365diff -urNp linux-2.6.22.1/arch/x86_64/kernel/ioport.c linux-2.6.22.1/arch/x86_64/kernel/ioport.c
10366--- linux-2.6.22.1/arch/x86_64/kernel/ioport.c 2007-07-10 14:56:30.000000000 -0400
10367+++ linux-2.6.22.1/arch/x86_64/kernel/ioport.c 2007-08-02 11:09:14.000000000 -0400
10368@@ -41,8 +41,16 @@ asmlinkage long sys_ioperm(unsigned long
10369
10370 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
10371 return -EINVAL;
10372+
10373+#ifdef CONFIG_GRKERNSEC_IO
10374+ if (turn_on) {
10375+ gr_handle_ioperm();
10376+ return -EPERM;
10377+ }
10378+#else
10379 if (turn_on && !capable(CAP_SYS_RAWIO))
10380 return -EPERM;
10381+#endif
10382
10383 /*
10384 * If it's the first ioperm() call in this thread's lifetime, set the
10385@@ -111,8 +119,13 @@ asmlinkage long sys_iopl(unsigned int le
10386 return -EINVAL;
10387 /* Trying to gain more privileges? */
10388 if (level > old) {
10389+#ifdef CONFIG_GRKERNSEC_IO
10390+ gr_handle_iopl();
10391+ return -EPERM;
10392+#else
10393 if (!capable(CAP_SYS_RAWIO))
10394 return -EPERM;
10395+#endif
10396 }
10397 regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12);
10398 return 0;
10399diff -urNp linux-2.6.22.1/arch/x86_64/kernel/process.c linux-2.6.22.1/arch/x86_64/kernel/process.c
10400--- linux-2.6.22.1/arch/x86_64/kernel/process.c 2007-07-10 14:56:30.000000000 -0400
10401+++ linux-2.6.22.1/arch/x86_64/kernel/process.c 2007-08-02 11:38:46.000000000 -0400
10402@@ -883,10 +883,3 @@ int dump_task_regs(struct task_struct *t
10403
10404 return 1;
10405 }
10406-
10407-unsigned long arch_align_stack(unsigned long sp)
10408-{
10409- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
10410- sp -= get_random_int() % 8192;
10411- return sp & ~0xf;
10412-}
3ba9fddb 10413diff -urNp linux-2.6.22.1/arch/x86_64/kernel/setup64.c linux-2.6.22.1/arch/x86_64/kernel/setup64.c
10414--- linux-2.6.22.1/arch/x86_64/kernel/setup64.c 2007-07-10 14:56:30.000000000 -0400
10415+++ linux-2.6.22.1/arch/x86_64/kernel/setup64.c 2007-08-02 11:38:46.000000000 -0400
10416@@ -37,7 +37,7 @@ struct desc_ptr idt_descr = { 256 * 16 -
10417 char boot_cpu_stack[IRQSTACKSIZE] __attribute__((section(".bss.page_aligned")));
10418
10419 unsigned long __supported_pte_mask __read_mostly = ~0UL;
10420-static int do_not_nx __cpuinitdata = 0;
10421+EXPORT_SYMBOL(__supported_pte_mask);
10422
10423 /* noexec=on|off
10424 Control non executable mappings for 64bit processes.
10425@@ -51,16 +51,14 @@ static int __init nonx_setup(char *str)
10426 return -EINVAL;
10427 if (!strncmp(str, "on", 2)) {
10428 __supported_pte_mask |= _PAGE_NX;
10429- do_not_nx = 0;
10430 } else if (!strncmp(str, "off", 3)) {
10431- do_not_nx = 1;
10432 __supported_pte_mask &= ~_PAGE_NX;
10433 }
10434 return 0;
10435 }
10436 early_param("noexec", nonx_setup);
10437
10438-int force_personality32 = 0;
10439+int force_personality32;
10440
10441 /* noexec32=on|off
10442 Control non executable heap for 32bit processes.
10443@@ -177,7 +175,7 @@ void __cpuinit check_efer(void)
10444 unsigned long efer;
10445
10446 rdmsrl(MSR_EFER, efer);
10447- if (!(efer & EFER_NX) || do_not_nx) {
10448+ if (!(efer & EFER_NX)) {
10449 __supported_pte_mask &= ~_PAGE_NX;
10450 }
10451 }
10452diff -urNp linux-2.6.22.1/arch/x86_64/kernel/signal.c linux-2.6.22.1/arch/x86_64/kernel/signal.c
10453--- linux-2.6.22.1/arch/x86_64/kernel/signal.c 2007-07-10 14:56:30.000000000 -0400
10454+++ linux-2.6.22.1/arch/x86_64/kernel/signal.c 2007-08-02 11:38:46.000000000 -0400
10455@@ -253,8 +253,8 @@ static int setup_rt_frame(int sig, struc
10456 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
10457 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
10458 if (sizeof(*set) == 16) {
10459- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
10460- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
10461+ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
10462+ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
10463 } else
10464 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
10465
10466diff -urNp linux-2.6.22.1/arch/x86_64/kernel/sys_x86_64.c linux-2.6.22.1/arch/x86_64/kernel/sys_x86_64.c
10467--- linux-2.6.22.1/arch/x86_64/kernel/sys_x86_64.c 2007-07-10 14:56:30.000000000 -0400
10468+++ linux-2.6.22.1/arch/x86_64/kernel/sys_x86_64.c 2007-08-02 11:38:46.000000000 -0400
10469@@ -64,8 +64,8 @@ out:
10470 return error;
10471 }
10472
10473-static void find_start_end(unsigned long flags, unsigned long *begin,
10474- unsigned long *end)
10475+static void find_start_end(struct mm_struct *mm, unsigned long flags,
10476+ unsigned long *begin, unsigned long *end)
10477 {
10478 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
10479 /* This is usually used needed to map code in small
10480@@ -78,7 +78,7 @@ static void find_start_end(unsigned long
10481 *begin = 0x40000000;
10482 *end = 0x80000000;
10483 } else {
10484- *begin = TASK_UNMAPPED_BASE;
10485+ *begin = mm->mmap_base;
10486 *end = TASK_SIZE;
10487 }
10488 }
10489@@ -95,11 +95,15 @@ arch_get_unmapped_area(struct file *filp
10490 if (flags & MAP_FIXED)
10491 return addr;
10492
10493- find_start_end(flags, &begin, &end);
10494+ find_start_end(mm, flags, &begin, &end);
10495
10496 if (len > end)
10497 return -ENOMEM;
10498
10499+#ifdef CONFIG_PAX_RANDMMAP
10500+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
10501+#endif
10502+
10503 if (addr) {
10504 addr = PAGE_ALIGN(addr);
10505 vma = find_vma(mm, addr);
10506diff -urNp linux-2.6.22.1/arch/x86_64/mm/fault.c linux-2.6.22.1/arch/x86_64/mm/fault.c
10507--- linux-2.6.22.1/arch/x86_64/mm/fault.c 2007-07-10 14:56:30.000000000 -0400
10508+++ linux-2.6.22.1/arch/x86_64/mm/fault.c 2007-08-02 11:38:46.000000000 -0400
10509@@ -25,6 +25,7 @@
10510 #include <linux/kprobes.h>
10511 #include <linux/uaccess.h>
10512 #include <linux/kdebug.h>
10513+#include <linux/binfmts.h>
10514
10515 #include <asm/system.h>
10516 #include <asm/pgalloc.h>
10517@@ -301,6 +302,33 @@ static int vmalloc_fault(unsigned long a
10518 return 0;
10519 }
10520
10521+#ifdef CONFIG_PAX_PAGEEXEC
10522+void pax_report_insns(void *pc, void *sp)
10523+{
10524+ long i;
10525+
10526+ printk(KERN_ERR "PAX: bytes at PC: ");
10527+ for (i = 0; i < 20; i++) {
10528+ unsigned char c;
10529+ if (get_user(c, (unsigned char __user *)pc+i))
10530+ printk("?? ");
10531+ else
10532+ printk("%02x ", c);
10533+ }
10534+ printk("\n");
10535+
10536+ printk(KERN_ERR "PAX: bytes at SP-8: ");
10537+ for (i = -1; i < 10; i++) {
10538+ unsigned long c;
10539+ if (get_user(c, (unsigned long __user *)sp+i))
10540+ printk("???????????????? ");
10541+ else
10542+ printk("%016lx ", c);
10543+ }
10544+ printk("\n");
10545+}
10546+#endif
10547+
10548 int page_fault_trace = 0;
10549 int exception_trace = 1;
10550
10551@@ -430,6 +458,8 @@ asmlinkage void __kprobes do_page_fault(
10552 good_area:
10553 info.si_code = SEGV_ACCERR;
10554 write = 0;
10555+ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10556+ goto bad_area;
10557 switch (error_code & (PF_PROT|PF_WRITE)) {
10558 default: /* 3: write, present */
10559 /* fall through */
10560@@ -502,7 +532,14 @@ bad_area_nosemaphore:
10561 tsk->comm, tsk->pid, tsk->xid, address,
10562 regs->rip, regs->rsp, error_code);
10563 }
10564-
10565+
10566+#ifdef CONFIG_PAX_PAGEEXEC
10567+ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
10568+ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
10569+ do_exit(SIGKILL);
10570+ }
10571+#endif
10572+
10573 tsk->thread.cr2 = address;
10574 /* Kernel addresses are always protection faults */
10575 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
10576diff -urNp linux-2.6.22.1/arch/x86_64/mm/mmap.c linux-2.6.22.1/arch/x86_64/mm/mmap.c
10577--- linux-2.6.22.1/arch/x86_64/mm/mmap.c 2007-07-10 14:56:30.000000000 -0400
10578+++ linux-2.6.22.1/arch/x86_64/mm/mmap.c 2007-08-02 11:38:46.000000000 -0400
10579@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
10580 unsigned rnd = get_random_int() & 0xfffffff;
10581 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
10582 }
10583+
10584+#ifdef CONFIG_PAX_RANDMMAP
10585+ if (mm->pax_flags & MF_PAX_RANDMMAP)
10586+ mm->mmap_base += mm->delta_mmap;
10587+#endif
10588+
10589 mm->get_unmapped_area = arch_get_unmapped_area;
10590 mm->unmap_area = arch_unmap_area;
10591 }
10592diff -urNp linux-2.6.22.1/crypto/lrw.c linux-2.6.22.1/crypto/lrw.c
10593--- linux-2.6.22.1/crypto/lrw.c 2007-07-10 14:56:30.000000000 -0400
10594+++ linux-2.6.22.1/crypto/lrw.c 2007-08-02 11:38:46.000000000 -0400
10595@@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
10596 struct priv *ctx = crypto_tfm_ctx(parent);
10597 struct crypto_cipher *child = ctx->child;
10598 int err, i;
10599- be128 tmp = { 0 };
10600+ be128 tmp = { 0, 0 };
10601 int bsize = crypto_cipher_blocksize(child);
10602
10603 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
10604diff -urNp linux-2.6.22.1/Documentation/dontdiff linux-2.6.22.1/Documentation/dontdiff
10605--- linux-2.6.22.1/Documentation/dontdiff 2007-07-10 14:56:30.000000000 -0400
10606+++ linux-2.6.22.1/Documentation/dontdiff 2007-08-02 11:38:45.000000000 -0400
10607@@ -177,10 +177,13 @@ version.h*
10608 vmlinux
10609 vmlinux-*
10610 vmlinux.aout
10611+vmlinux.bin.all
10612 vmlinux.lds
10613+vmlinux.relocs
10614 vsyscall.lds
10615 wanxlfw.inc
10616 uImage
10617 unifdef
10618+utsrelease.h
10619 zImage*
10620 zconf.hash.c
10621diff -urNp linux-2.6.22.1/drivers/acpi/blacklist.c linux-2.6.22.1/drivers/acpi/blacklist.c
10622--- linux-2.6.22.1/drivers/acpi/blacklist.c 2007-07-10 14:56:30.000000000 -0400
10623+++ linux-2.6.22.1/drivers/acpi/blacklist.c 2007-08-02 11:38:46.000000000 -0400
10624@@ -70,7 +70,7 @@ static struct acpi_blacklist_item acpi_b
10625 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
10626 "Bogus PCI routing", 1},
10627
10628- {""}
10629+ {"", "", 0, 0, 0, all_versions, 0}
10630 };
10631
10632 #if CONFIG_ACPI_BLACKLIST_YEAR
10633diff -urNp linux-2.6.22.1/drivers/acpi/glue.c linux-2.6.22.1/drivers/acpi/glue.c
10634--- linux-2.6.22.1/drivers/acpi/glue.c 2007-07-10 14:56:30.000000000 -0400
10635+++ linux-2.6.22.1/drivers/acpi/glue.c 2007-08-02 11:38:46.000000000 -0400
10636@@ -16,7 +16,7 @@
10637 #if ACPI_GLUE_DEBUG
10638 #define DBG(x...) printk(PREFIX x)
10639 #else
10640-#define DBG(x...)
10641+#define DBG(x...) do {} while (0)
10642 #endif
10643 static LIST_HEAD(bus_type_list);
10644 static DECLARE_RWSEM(bus_type_sem);
10645diff -urNp linux-2.6.22.1/drivers/acpi/processor_core.c linux-2.6.22.1/drivers/acpi/processor_core.c
10646--- linux-2.6.22.1/drivers/acpi/processor_core.c 2007-07-10 14:56:30.000000000 -0400
10647+++ linux-2.6.22.1/drivers/acpi/processor_core.c 2007-08-02 11:38:46.000000000 -0400
10648@@ -635,7 +635,7 @@ static int __cpuinit acpi_processor_star
10649 return 0;
10650 }
10651
10652- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
10653+ BUG_ON(pr->id >= NR_CPUS);
10654
10655 /*
10656 * Buggy BIOS check
10657diff -urNp linux-2.6.22.1/drivers/acpi/processor_idle.c linux-2.6.22.1/drivers/acpi/processor_idle.c
10658--- linux-2.6.22.1/drivers/acpi/processor_idle.c 2007-07-10 14:56:30.000000000 -0400
10659+++ linux-2.6.22.1/drivers/acpi/processor_idle.c 2007-08-02 11:38:46.000000000 -0400
10660@@ -163,7 +163,7 @@ static struct dmi_system_id __cpuinitdat
10661 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
10662 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
10663 (void *)2},
10664- {},
10665+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
10666 };
10667
10668 static inline u32 ticks_elapsed(u32 t1, u32 t2)
10669diff -urNp linux-2.6.22.1/drivers/acpi/sleep/main.c linux-2.6.22.1/drivers/acpi/sleep/main.c
10670--- linux-2.6.22.1/drivers/acpi/sleep/main.c 2007-07-10 14:56:30.000000000 -0400
10671+++ linux-2.6.22.1/drivers/acpi/sleep/main.c 2007-08-02 11:38:46.000000000 -0400
10672@@ -241,7 +241,7 @@ static struct dmi_system_id __initdata a
10673 .ident = "Toshiba Satellite 4030cdt",
10674 .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
10675 },
10676- {},
10677+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
10678 };
10679
10680 int __init acpi_sleep_init(void)
10681diff -urNp linux-2.6.22.1/drivers/acpi/tables/tbfadt.c linux-2.6.22.1/drivers/acpi/tables/tbfadt.c
10682--- linux-2.6.22.1/drivers/acpi/tables/tbfadt.c 2007-07-10 14:56:30.000000000 -0400
10683+++ linux-2.6.22.1/drivers/acpi/tables/tbfadt.c 2007-08-02 11:38:46.000000000 -0400
10684@@ -48,7 +48,7 @@
10685 ACPI_MODULE_NAME("tbfadt")
10686
10687 /* Local prototypes */
10688-static void inline
10689+static inline void
10690 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
10691 u8 bit_width, u64 address);
10692
10693@@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
10694 *
10695 ******************************************************************************/
10696
10697-static void inline
10698+static inline void
10699 acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
10700 u8 bit_width, u64 address)
10701 {
10702diff -urNp linux-2.6.22.1/drivers/ata/ata_piix.c linux-2.6.22.1/drivers/ata/ata_piix.c
10703--- linux-2.6.22.1/drivers/ata/ata_piix.c 2007-07-10 14:56:30.000000000 -0400
10704+++ linux-2.6.22.1/drivers/ata/ata_piix.c 2007-08-02 11:38:46.000000000 -0400
10705@@ -244,7 +244,7 @@ static const struct pci_device_id piix_p
10706 /* SATA Controller IDE (ICH9M) */
10707 { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
10708
10709- { } /* terminate list */
10710+ { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
10711 };
10712
10713 static struct pci_driver piix_pci_driver = {
10714@@ -580,7 +580,7 @@ static const struct ich_laptop ich_lapto
10715 { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */
10716 { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */
10717 /* end marker */
10718- { 0, }
10719+ { 0, 0, 0 }
10720 };
10721
10722 /**
10723diff -urNp linux-2.6.22.1/drivers/ata/libata-core.c linux-2.6.22.1/drivers/ata/libata-core.c
10724--- linux-2.6.22.1/drivers/ata/libata-core.c 2007-07-10 14:56:30.000000000 -0400
10725+++ linux-2.6.22.1/drivers/ata/libata-core.c 2007-08-02 11:38:46.000000000 -0400
10726@@ -469,7 +469,7 @@ static const struct ata_xfer_ent {
10727 { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
10728 { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
10729 { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
10730- { -1, },
10731+ { -1, 0, 0 },
10732 };
10733
10734 /**
10735@@ -2559,7 +2559,7 @@ static const struct ata_timing ata_timin
10736
10737 /* { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960, 0 }, */
10738
10739- { 0xFF }
10740+ { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
10741 };
10742
10743 #define ENOUGH(v,unit) (((v)-1)/(unit)+1)
10744@@ -3804,7 +3804,7 @@ static const struct ata_blacklist_entry
10745 /* Devices with NCQ limits */
10746
10747 /* End Marker */
10748- { }
10749+ { NULL, NULL, 0 }
10750 };
10751
10752 unsigned long ata_device_blacklisted(const struct ata_device *dev)
10753diff -urNp linux-2.6.22.1/drivers/char/agp/frontend.c linux-2.6.22.1/drivers/char/agp/frontend.c
10754--- linux-2.6.22.1/drivers/char/agp/frontend.c 2007-07-10 14:56:30.000000000 -0400
10755+++ linux-2.6.22.1/drivers/char/agp/frontend.c 2007-08-02 11:38:46.000000000 -0400
10756@@ -819,7 +819,7 @@ static int agpioc_reserve_wrap(struct ag
10757 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
10758 return -EFAULT;
10759
10760- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
10761+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
10762 return -EFAULT;
10763
10764 client = agp_find_client_by_pid(reserve.pid);
10765diff -urNp linux-2.6.22.1/drivers/char/agp/intel-agp.c linux-2.6.22.1/drivers/char/agp/intel-agp.c
10766--- linux-2.6.22.1/drivers/char/agp/intel-agp.c 2007-07-10 14:56:30.000000000 -0400
10767+++ linux-2.6.22.1/drivers/char/agp/intel-agp.c 2007-08-02 11:38:46.000000000 -0400
10768@@ -2059,7 +2059,7 @@ static struct pci_device_id agp_intel_pc
10769 ID(PCI_DEVICE_ID_INTEL_G33_HB),
10770 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
10771 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
10772- { }
10773+ { 0, 0, 0, 0, 0, 0, 0 }
10774 };
10775
10776 MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
10777diff -urNp linux-2.6.22.1/drivers/char/drm/drm_drawable.c linux-2.6.22.1/drivers/char/drm/drm_drawable.c
10778--- linux-2.6.22.1/drivers/char/drm/drm_drawable.c 2007-07-10 14:56:30.000000000 -0400
10779+++ linux-2.6.22.1/drivers/char/drm/drm_drawable.c 2007-08-02 11:38:46.000000000 -0400
10780@@ -245,7 +245,7 @@ int drm_update_drawable_info(DRM_IOCTL_A
10781 idx = id / (8 * sizeof(*bitfield));
10782 shift = id % (8 * sizeof(*bitfield));
10783
10784- if (idx < 0 || idx >= bitfield_length ||
10785+ if (idx >= bitfield_length ||
10786 !(bitfield[idx] & (1 << shift))) {
10787 DRM_ERROR("No such drawable %d\n", update.handle);
10788 return DRM_ERR(EINVAL);
10789@@ -330,7 +330,7 @@ drm_drawable_info_t *drm_get_drawable_in
10790 idx = id / (8 * sizeof(*bitfield));
10791 shift = id % (8 * sizeof(*bitfield));
10792
10793- if (idx < 0 || idx >= dev->drw_bitfield_length ||
10794+ if (idx >= dev->drw_bitfield_length ||
10795 !(bitfield[idx] & (1 << shift))) {
10796 DRM_DEBUG("No such drawable %d\n", id);
10797 return NULL;
10798diff -urNp linux-2.6.22.1/drivers/char/drm/drm_pciids.h linux-2.6.22.1/drivers/char/drm/drm_pciids.h
10799--- linux-2.6.22.1/drivers/char/drm/drm_pciids.h 2007-07-10 14:56:30.000000000 -0400
10800+++ linux-2.6.22.1/drivers/char/drm/drm_pciids.h 2007-08-02 11:38:46.000000000 -0400
10801@@ -251,7 +251,7 @@
10802 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10803 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10804 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10805- {0, 0, 0}
10806+ {0, 0, 0, 0, 0, 0, 0 }
10807
10808 #define i830_PCI_IDS \
10809 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10810diff -urNp linux-2.6.22.1/drivers/char/hpet.c linux-2.6.22.1/drivers/char/hpet.c
10811--- linux-2.6.22.1/drivers/char/hpet.c 2007-07-10 14:56:30.000000000 -0400
10812+++ linux-2.6.22.1/drivers/char/hpet.c 2007-08-02 11:38:46.000000000 -0400
10813@@ -1008,7 +1008,7 @@ static struct acpi_driver hpet_acpi_driv
10814 },
10815 };
10816
10817-static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
10818+static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
10819
10820 static int __init hpet_init(void)
10821 {
10822diff -urNp linux-2.6.22.1/drivers/char/keyboard.c linux-2.6.22.1/drivers/char/keyboard.c
10823--- linux-2.6.22.1/drivers/char/keyboard.c 2007-07-10 14:56:30.000000000 -0400
10824+++ linux-2.6.22.1/drivers/char/keyboard.c 2007-08-02 11:38:46.000000000 -0400
10825@@ -595,6 +595,16 @@ static void k_spec(struct vc_data *vc, u
10826 kbd->kbdmode == VC_MEDIUMRAW) &&
10827 value != KVAL(K_SAK))
10828 return; /* SAK is allowed even in raw mode */
10829+
10830+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
10831+ {
10832+ void *func = fn_handler[value];
10833+ if (func == fn_show_state || func == fn_show_ptregs ||
10834+ func == fn_show_mem)
10835+ return;
10836+ }
10837+#endif
10838+
10839 fn_handler[value](vc);
10840 }
10841
10842@@ -1334,7 +1344,7 @@ static const struct input_device_id kbd_
10843 .evbit = { BIT(EV_SND) },
10844 },
10845
10846- { }, /* Terminating entry */
10847+ { 0 }, /* Terminating entry */
10848 };
10849
10850 MODULE_DEVICE_TABLE(input, kbd_ids);
10851diff -urNp linux-2.6.22.1/drivers/char/mem.c linux-2.6.22.1/drivers/char/mem.c
10852--- linux-2.6.22.1/drivers/char/mem.c 2007-07-10 14:56:30.000000000 -0400
10853+++ linux-2.6.22.1/drivers/char/mem.c 2007-08-02 11:38:46.000000000 -0400
10854@@ -26,6 +26,7 @@
10855 #include <linux/bootmem.h>
10856 #include <linux/pipe_fs_i.h>
10857 #include <linux/pfn.h>
10858+#include <linux/grsecurity.h>
10859
10860 #include <asm/uaccess.h>
10861 #include <asm/io.h>
10862@@ -34,6 +35,10 @@
10863 # include <linux/efi.h>
10864 #endif
10865
10866+#ifdef CONFIG_GRKERNSEC
10867+extern struct file_operations grsec_fops;
10868+#endif
10869+
10870 /*
10871 * Architectures vary in how they handle caching for addresses
10872 * outside of main memory.
10873@@ -173,6 +178,11 @@ static ssize_t write_mem(struct file * f
10874 if (!valid_phys_addr_range(p, count))
10875 return -EFAULT;
10876
10877+#ifdef CONFIG_GRKERNSEC_KMEM
10878+ gr_handle_mem_write();
10879+ return -EPERM;
10880+#endif
10881+
10882 written = 0;
10883
10884 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
10885@@ -274,6 +284,11 @@ static int mmap_mem(struct file * file,
10886 if (!private_mapping_ok(vma))
10887 return -ENOSYS;
10888
10889+#ifdef CONFIG_GRKERNSEC_KMEM
10890+ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
10891+ return -EPERM;
10892+#endif
10893+
10894 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
10895 size,
10896 vma->vm_page_prot);
10897@@ -505,6 +520,11 @@ static ssize_t write_kmem(struct file *
10898 ssize_t written;
10899 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
10900
10901+#ifdef CONFIG_GRKERNSEC_KMEM
10902+ gr_handle_kmem_write();
10903+ return -EPERM;
10904+#endif
10905+
10906 if (p < (unsigned long) high_memory) {
10907
10908 wrote = count;
10909@@ -628,6 +648,10 @@ static inline size_t read_zero_pagealign
10910 struct vm_area_struct * vma;
10911 unsigned long addr=(unsigned long)buf;
10912
10913+#ifdef CONFIG_PAX_SEGMEXEC
10914+ struct vm_area_struct *vma_m;
10915+#endif
10916+
10917 mm = current->mm;
10918 /* Oops, this was forgotten before. -ben */
10919 down_read(&mm->mmap_sem);
10920@@ -644,8 +668,14 @@ static inline size_t read_zero_pagealign
10921 if (count > size)
10922 count = size;
10923
10924+#ifdef CONFIG_PAX_SEGMEXEC
10925+ vma_m = pax_find_mirror_vma(vma);
10926+ if (vma_m)
10927+ zap_page_range(vma_m, addr + SEGMEXEC_TASK_SIZE, count, NULL);
10928+#endif
10929+
10930 zap_page_range(vma, addr, count, NULL);
10931- if (zeromap_page_range(vma, addr, count, PAGE_COPY))
10932+ if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
10933 break;
10934
10935 size -= count;
10936@@ -798,6 +828,16 @@ static loff_t memory_lseek(struct file *
10937
10938 static int open_port(struct inode * inode, struct file * filp)
10939 {
10940+#ifdef CONFIG_GRKERNSEC_KMEM
10941+ gr_handle_open_port();
10942+ return -EPERM;
10943+#endif
10944+
10945+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
10946+}
10947+
10948+static int open_mem(struct inode * inode, struct file * filp)
10949+{
10950 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
10951 }
10952
10953@@ -805,7 +845,6 @@ static int open_port(struct inode * inod
10954 #define full_lseek null_lseek
10955 #define write_zero write_null
10956 #define read_full read_zero
10957-#define open_mem open_port
10958 #define open_kmem open_mem
10959 #define open_oldmem open_mem
10960
10961@@ -938,6 +977,11 @@ static int memory_open(struct inode * in
10962 filp->f_op = &oldmem_fops;
10963 break;
10964 #endif
10965+#ifdef CONFIG_GRKERNSEC
10966+ case 13:
10967+ filp->f_op = &grsec_fops;
10968+ break;
10969+#endif
10970 default:
10971 return -ENXIO;
10972 }
10973@@ -970,6 +1014,9 @@ static const struct {
10974 #ifdef CONFIG_CRASH_DUMP
10975 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
10976 #endif
10977+#ifdef CONFIG_GRKERNSEC
10978+ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
10979+#endif
10980 };
10981
10982 static struct class *mem_class;
10983diff -urNp linux-2.6.22.1/drivers/char/nvram.c linux-2.6.22.1/drivers/char/nvram.c
10984--- linux-2.6.22.1/drivers/char/nvram.c 2007-07-10 14:56:30.000000000 -0400
10985+++ linux-2.6.22.1/drivers/char/nvram.c 2007-08-02 11:38:46.000000000 -0400
10986@@ -449,7 +449,10 @@ static const struct file_operations nvra
10987 static struct miscdevice nvram_dev = {
10988 NVRAM_MINOR,
10989 "nvram",
10990- &nvram_fops
10991+ &nvram_fops,
10992+ {NULL, NULL},
10993+ NULL,
10994+ NULL
10995 };
10996
10997 static int __init
10998diff -urNp linux-2.6.22.1/drivers/char/random.c linux-2.6.22.1/drivers/char/random.c
10999--- linux-2.6.22.1/drivers/char/random.c 2007-07-10 14:56:30.000000000 -0400
11000+++ linux-2.6.22.1/drivers/char/random.c 2007-08-02 11:40:03.000000000 -0400
11001@@ -248,8 +248,13 @@
11002 /*
11003 * Configuration information
11004 */
11005+#ifdef CONFIG_GRKERNSEC_RANDNET
11006+#define INPUT_POOL_WORDS 512
11007+#define OUTPUT_POOL_WORDS 128
11008+#else
11009 #define INPUT_POOL_WORDS 128
11010 #define OUTPUT_POOL_WORDS 32
11011+#endif
11012 #define SEC_XFER_SIZE 512
11013
11014 /*
11015@@ -286,10 +291,17 @@ static struct poolinfo {
11016 int poolwords;
11017 int tap1, tap2, tap3, tap4, tap5;
11018 } poolinfo_table[] = {
11019+#ifdef CONFIG_GRKERNSEC_RANDNET
11020+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
11021+ { 512, 411, 308, 208, 104, 1 },
11022+ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
11023+ { 128, 103, 76, 51, 25, 1 },
11024+#else
11025 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
11026 { 128, 103, 76, 51, 25, 1 },
11027 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
11028 { 32, 26, 20, 14, 7, 1 },
11029+#endif
11030 #if 0
11031 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
11032 { 2048, 1638, 1231, 819, 411, 1 },
11033diff -urNp linux-2.6.22.1/drivers/char/vt_ioctl.c linux-2.6.22.1/drivers/char/vt_ioctl.c
11034--- linux-2.6.22.1/drivers/char/vt_ioctl.c 2007-07-10 14:56:30.000000000 -0400
11035+++ linux-2.6.22.1/drivers/char/vt_ioctl.c 2007-08-02 11:09:15.000000000 -0400
11036@@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
11037 case KDSKBENT:
11038 if (!perm)
11039 return -EPERM;
11040+
11041+#ifdef CONFIG_GRKERNSEC
11042+ if (!capable(CAP_SYS_TTY_CONFIG))
11043+ return -EPERM;
11044+#endif
11045+
11046 if (!i && v == K_NOSUCHMAP) {
11047 /* deallocate map */
11048 key_map = key_maps[s];
11049@@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
11050 goto reterr;
11051 }
11052
11053+#ifdef CONFIG_GRKERNSEC
11054+ if (!capable(CAP_SYS_TTY_CONFIG)) {
11055+ ret = -EPERM;
11056+ goto reterr;
11057+ }
11058+#endif
11059+
11060 q = func_table[i];
11061 first_free = funcbufptr + (funcbufsize - funcbufleft);
11062 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
11063diff -urNp linux-2.6.22.1/drivers/edac/edac_mc.h linux-2.6.22.1/drivers/edac/edac_mc.h
11064--- linux-2.6.22.1/drivers/edac/edac_mc.h 2007-07-10 14:56:30.000000000 -0400
11065+++ linux-2.6.22.1/drivers/edac/edac_mc.h 2007-08-02 11:38:46.000000000 -0400
11066@@ -71,11 +71,11 @@ extern int edac_debug_level;
11067
11068 #else /* !CONFIG_EDAC_DEBUG */
11069
11070-#define debugf0( ... )
11071-#define debugf1( ... )
11072-#define debugf2( ... )
11073-#define debugf3( ... )
11074-#define debugf4( ... )
11075+#define debugf0( ... ) do {} while (0)
11076+#define debugf1( ... ) do {} while (0)
11077+#define debugf2( ... ) do {} while (0)
11078+#define debugf3( ... ) do {} while (0)
11079+#define debugf4( ... ) do {} while (0)
11080
11081 #endif /* !CONFIG_EDAC_DEBUG */
11082
11083diff -urNp linux-2.6.22.1/drivers/hwmon/fscpos.c linux-2.6.22.1/drivers/hwmon/fscpos.c
11084--- linux-2.6.22.1/drivers/hwmon/fscpos.c 2007-07-10 14:56:30.000000000 -0400
11085+++ linux-2.6.22.1/drivers/hwmon/fscpos.c 2007-08-02 11:38:46.000000000 -0400
11086@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
11087 unsigned long v = simple_strtoul(buf, NULL, 10);
11088
11089 /* Range: 0..255 */
11090- if (v < 0) v = 0;
11091 if (v > 255) v = 255;
11092
11093 mutex_lock(&data->update_lock);
11094diff -urNp linux-2.6.22.1/drivers/hwmon/k8temp.c linux-2.6.22.1/drivers/hwmon/k8temp.c
11095--- linux-2.6.22.1/drivers/hwmon/k8temp.c 2007-07-10 14:56:30.000000000 -0400
11096+++ linux-2.6.22.1/drivers/hwmon/k8temp.c 2007-08-02 11:38:46.000000000 -0400
11097@@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
11098
11099 static struct pci_device_id k8temp_ids[] = {
11100 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
11101- { 0 },
11102+ { 0, 0, 0, 0, 0, 0, 0 },
11103 };
11104
11105 MODULE_DEVICE_TABLE(pci, k8temp_ids);
11106diff -urNp linux-2.6.22.1/drivers/hwmon/sis5595.c linux-2.6.22.1/drivers/hwmon/sis5595.c
11107--- linux-2.6.22.1/drivers/hwmon/sis5595.c 2007-07-10 14:56:30.000000000 -0400
11108+++ linux-2.6.22.1/drivers/hwmon/sis5595.c 2007-08-02 11:38:46.000000000 -0400
11109@@ -755,7 +755,7 @@ static struct sis5595_data *sis5595_upda
11110
11111 static struct pci_device_id sis5595_pci_ids[] = {
11112 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
11113- { 0, }
11114+ { 0, 0, 0, 0, 0, 0, 0 }
11115 };
11116
11117 MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
11118diff -urNp linux-2.6.22.1/drivers/hwmon/via686a.c linux-2.6.22.1/drivers/hwmon/via686a.c
11119--- linux-2.6.22.1/drivers/hwmon/via686a.c 2007-07-10 14:56:30.000000000 -0400
11120+++ linux-2.6.22.1/drivers/hwmon/via686a.c 2007-08-02 11:38:46.000000000 -0400
11121@@ -813,7 +813,7 @@ static struct via686a_data *via686a_upda
11122
11123 static struct pci_device_id via686a_pci_ids[] = {
11124 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
11125- { 0, }
11126+ { 0, 0, 0, 0, 0, 0, 0 }
11127 };
11128
11129 MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
11130diff -urNp linux-2.6.22.1/drivers/hwmon/vt8231.c linux-2.6.22.1/drivers/hwmon/vt8231.c
11131--- linux-2.6.22.1/drivers/hwmon/vt8231.c 2007-07-10 14:56:30.000000000 -0400
11132+++ linux-2.6.22.1/drivers/hwmon/vt8231.c 2007-08-02 11:38:46.000000000 -0400
11133@@ -666,7 +666,7 @@ static struct i2c_driver vt8231_driver =
11134
11135 static struct pci_device_id vt8231_pci_ids[] = {
11136 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
11137- { 0, }
11138+ { 0, 0, 0, 0, 0, 0, 0 }
11139 };
11140
11141 MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
11142diff -urNp linux-2.6.22.1/drivers/hwmon/w83791d.c linux-2.6.22.1/drivers/hwmon/w83791d.c
11143--- linux-2.6.22.1/drivers/hwmon/w83791d.c 2007-07-10 14:56:30.000000000 -0400
11144+++ linux-2.6.22.1/drivers/hwmon/w83791d.c 2007-08-02 11:38:46.000000000 -0400
11145@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
11146 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
11147 static int w83791d_detach_client(struct i2c_client *client);
11148
11149-static int w83791d_read(struct i2c_client *client, u8 register);
11150-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
11151+static int w83791d_read(struct i2c_client *client, u8 reg);
11152+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
11153 static struct w83791d_data *w83791d_update_device(struct device *dev);
11154
11155 #ifdef DEBUG
11156diff -urNp linux-2.6.22.1/drivers/i2c/busses/i2c-i801.c linux-2.6.22.1/drivers/i2c/busses/i2c-i801.c
11157--- linux-2.6.22.1/drivers/i2c/busses/i2c-i801.c 2007-07-10 14:56:30.000000000 -0400
11158+++ linux-2.6.22.1/drivers/i2c/busses/i2c-i801.c 2007-08-02 11:38:46.000000000 -0400
11159@@ -460,7 +460,7 @@ static struct pci_device_id i801_ids[] =
11160 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
11161 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
11162 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
11163- { 0, }
11164+ { 0, 0, 0, 0, 0, 0, 0 }
11165 };
11166
11167 MODULE_DEVICE_TABLE (pci, i801_ids);
11168diff -urNp linux-2.6.22.1/drivers/i2c/busses/i2c-i810.c linux-2.6.22.1/drivers/i2c/busses/i2c-i810.c
11169--- linux-2.6.22.1/drivers/i2c/busses/i2c-i810.c 2007-07-10 14:56:30.000000000 -0400
11170+++ linux-2.6.22.1/drivers/i2c/busses/i2c-i810.c 2007-08-02 11:38:46.000000000 -0400
11171@@ -198,7 +198,7 @@ static struct pci_device_id i810_ids[] _
11172 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
11173 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
11174 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
11175- { 0, },
11176+ { 0, 0, 0, 0, 0, 0, 0 },
11177 };
11178
11179 MODULE_DEVICE_TABLE (pci, i810_ids);
11180diff -urNp linux-2.6.22.1/drivers/i2c/busses/i2c-piix4.c linux-2.6.22.1/drivers/i2c/busses/i2c-piix4.c
11181--- linux-2.6.22.1/drivers/i2c/busses/i2c-piix4.c 2007-07-10 14:56:30.000000000 -0400
11182+++ linux-2.6.22.1/drivers/i2c/busses/i2c-piix4.c 2007-08-02 11:38:46.000000000 -0400
11183@@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
11184 .ident = "IBM",
11185 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
11186 },
11187- { },
11188+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
11189 };
11190
11191 static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
11192@@ -411,7 +411,7 @@ static struct pci_device_id piix4_ids[]
11193 .driver_data = 3 },
11194 { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
11195 .driver_data = 0 },
11196- { 0, }
11197+ { 0, 0, 0, 0, 0, 0, 0 }
11198 };
11199
11200 MODULE_DEVICE_TABLE (pci, piix4_ids);
11201diff -urNp linux-2.6.22.1/drivers/i2c/busses/i2c-sis630.c linux-2.6.22.1/drivers/i2c/busses/i2c-sis630.c
11202--- linux-2.6.22.1/drivers/i2c/busses/i2c-sis630.c 2007-07-10 14:56:30.000000000 -0400
11203+++ linux-2.6.22.1/drivers/i2c/busses/i2c-sis630.c 2007-08-02 11:38:46.000000000 -0400
11204@@ -465,7 +465,7 @@ static struct i2c_adapter sis630_adapter
11205 static struct pci_device_id sis630_ids[] __devinitdata = {
11206 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
11207 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
11208- { 0, }
11209+ { PCI_DEVICE(0, 0) }
11210 };
11211
11212 MODULE_DEVICE_TABLE (pci, sis630_ids);
11213diff -urNp linux-2.6.22.1/drivers/i2c/busses/i2c-sis96x.c linux-2.6.22.1/drivers/i2c/busses/i2c-sis96x.c
11214--- linux-2.6.22.1/drivers/i2c/busses/i2c-sis96x.c 2007-07-10 14:56:30.000000000 -0400
11215+++ linux-2.6.22.1/drivers/i2c/busses/i2c-sis96x.c 2007-08-02 11:38:46.000000000 -0400
11216@@ -255,7 +255,7 @@ static struct i2c_adapter sis96x_adapter
11217
11218 static struct pci_device_id sis96x_ids[] = {
11219 { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
11220- { 0, }
11221+ { PCI_DEVICE(0, 0) }
11222 };
11223
11224 MODULE_DEVICE_TABLE (pci, sis96x_ids);
11225diff -urNp linux-2.6.22.1/drivers/ide/ide-cd.c linux-2.6.22.1/drivers/ide/ide-cd.c
11226--- linux-2.6.22.1/drivers/ide/ide-cd.c 2007-07-10 14:56:30.000000000 -0400
11227+++ linux-2.6.22.1/drivers/ide/ide-cd.c 2007-08-02 11:38:46.000000000 -0400
11228@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
11229 sector &= ~(bio_sectors -1);
11230 valid = (sector - failed_command->sector) << 9;
11231
11232- if (valid < 0)
11233- valid = 0;
11234 if (sector < get_capacity(info->disk) &&
11235 drive->probed_capacity - sector < 4 * 75) {
11236 set_capacity(info->disk, sector);
11237diff -urNp linux-2.6.22.1/drivers/ieee1394/dv1394.c linux-2.6.22.1/drivers/ieee1394/dv1394.c
11238--- linux-2.6.22.1/drivers/ieee1394/dv1394.c 2007-07-10 14:56:30.000000000 -0400
11239+++ linux-2.6.22.1/drivers/ieee1394/dv1394.c 2007-08-02 11:38:46.000000000 -0400
11240@@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
11241 based upon DIF section and sequence
11242 */
11243
11244-static void inline
11245+static inline void
11246 frame_put_packet (struct frame *f, struct packet *p)
11247 {
11248 int section_type = p->data[0] >> 5; /* section type is in bits 5 - 7 */
11249@@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
11250 /* default SYT offset is 3 cycles */
11251 init->syt_offset = 3;
11252
11253- if ( (init->channel > 63) || (init->channel < 0) )
11254+ if (init->channel > 63)
11255 init->channel = 63;
11256
11257 chan_mask = (u64)1 << init->channel;
11258@@ -2173,7 +2173,7 @@ static struct ieee1394_device_id dv1394_
11259 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
11260 .version = AVC_SW_VERSION_ENTRY & 0xffffff
11261 },
11262- { }
11263+ { 0, 0, 0, 0, 0, 0 }
11264 };
11265
11266 MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
11267diff -urNp linux-2.6.22.1/drivers/ieee1394/eth1394.c linux-2.6.22.1/drivers/ieee1394/eth1394.c
11268--- linux-2.6.22.1/drivers/ieee1394/eth1394.c 2007-07-10 14:56:30.000000000 -0400
11269+++ linux-2.6.22.1/drivers/ieee1394/eth1394.c 2007-08-02 11:38:46.000000000 -0400
11270@@ -449,7 +449,7 @@ static struct ieee1394_device_id eth1394
11271 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
11272 .version = ETHER1394_GASP_VERSION,
11273 },
11274- {}
11275+ { 0, 0, 0, 0, 0, 0 }
11276 };
11277
11278 MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
11279diff -urNp linux-2.6.22.1/drivers/ieee1394/hosts.c linux-2.6.22.1/drivers/ieee1394/hosts.c
11280--- linux-2.6.22.1/drivers/ieee1394/hosts.c 2007-07-10 14:56:30.000000000 -0400
11281+++ linux-2.6.22.1/drivers/ieee1394/hosts.c 2007-08-02 11:38:46.000000000 -0400
11282@@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso
11283 }
11284
11285 static struct hpsb_host_driver dummy_driver = {
11286+ .name = "dummy",
11287 .transmit_packet = dummy_transmit_packet,
11288 .devctl = dummy_devctl,
11289 .isoctl = dummy_isoctl
11290diff -urNp linux-2.6.22.1/drivers/ieee1394/ohci1394.c linux-2.6.22.1/drivers/ieee1394/ohci1394.c
11291--- linux-2.6.22.1/drivers/ieee1394/ohci1394.c 2007-07-10 14:56:30.000000000 -0400
11292+++ linux-2.6.22.1/drivers/ieee1394/ohci1394.c 2007-08-02 11:38:46.000000000 -0400
11293@@ -160,9 +160,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
11294 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
11295
11296 /* Module Parameters */
11297-static int phys_dma = 1;
11298+static int phys_dma;
11299 module_param(phys_dma, int, 0444);
11300-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
11301+MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
11302
11303 static void dma_trm_tasklet(unsigned long data);
11304 static void dma_trm_reset(struct dma_trm_ctx *d);
11305@@ -3632,7 +3632,7 @@ static struct pci_device_id ohci1394_pci
11306 .subvendor = PCI_ANY_ID,
11307 .subdevice = PCI_ANY_ID,
11308 },
11309- { 0, },
11310+ { 0, 0, 0, 0, 0, 0, 0 },
11311 };
11312
11313 MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
11314diff -urNp linux-2.6.22.1/drivers/ieee1394/raw1394.c linux-2.6.22.1/drivers/ieee1394/raw1394.c
11315--- linux-2.6.22.1/drivers/ieee1394/raw1394.c 2007-07-10 14:56:30.000000000 -0400
11316+++ linux-2.6.22.1/drivers/ieee1394/raw1394.c 2007-08-02 11:38:46.000000000 -0400
11317@@ -3013,7 +3013,7 @@ static struct ieee1394_device_id raw1394
11318 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
11319 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
11320 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
11321- {}
11322+ { 0, 0, 0, 0, 0, 0 }
11323 };
11324
11325 MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
11326diff -urNp linux-2.6.22.1/drivers/ieee1394/sbp2.c linux-2.6.22.1/drivers/ieee1394/sbp2.c
11327--- linux-2.6.22.1/drivers/ieee1394/sbp2.c 2007-07-10 14:56:30.000000000 -0400
11328+++ linux-2.6.22.1/drivers/ieee1394/sbp2.c 2007-08-02 11:38:46.000000000 -0400
11329@@ -273,7 +273,7 @@ static struct ieee1394_device_id sbp2_id
11330 .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
11331 .specifier_id = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
11332 .version = SBP2_SW_VERSION_ENTRY & 0xffffff},
11333- {}
11334+ { 0, 0, 0, 0, 0, 0 }
11335 };
11336 MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
11337
11338@@ -2136,7 +2136,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
11339 MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
11340 MODULE_LICENSE("GPL");
11341
11342-static int sbp2_module_init(void)
11343+static int __init sbp2_module_init(void)
11344 {
11345 int ret;
11346
11347diff -urNp linux-2.6.22.1/drivers/ieee1394/video1394.c linux-2.6.22.1/drivers/ieee1394/video1394.c
11348--- linux-2.6.22.1/drivers/ieee1394/video1394.c 2007-07-10 14:56:30.000000000 -0400
11349+++ linux-2.6.22.1/drivers/ieee1394/video1394.c 2007-08-02 11:38:46.000000000 -0400
11350@@ -893,7 +893,7 @@ static long video1394_ioctl(struct file
11351 if (unlikely(d == NULL))
11352 return -EFAULT;
11353
11354- if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
11355+ if (unlikely(v.buffer>=d->num_desc - 1)) {
11356 PRINT(KERN_ERR, ohci->host->id,
11357 "Buffer %d out of range",v.buffer);
11358 return -EINVAL;
11359@@ -959,7 +959,7 @@ static long video1394_ioctl(struct file
11360 if (unlikely(d == NULL))
11361 return -EFAULT;
11362
11363- if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
11364+ if (unlikely(v.buffer>d->num_desc - 1)) {
11365 PRINT(KERN_ERR, ohci->host->id,
11366 "Buffer %d out of range",v.buffer);
11367 return -EINVAL;
11368@@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file
11369 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
11370 if (d == NULL) return -EFAULT;
11371
11372- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
11373+ if (v.buffer>=d->num_desc - 1) {
11374 PRINT(KERN_ERR, ohci->host->id,
11375 "Buffer %d out of range",v.buffer);
11376 return -EINVAL;
11377@@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file
11378 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
11379 if (d == NULL) return -EFAULT;
11380
11381- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
11382+ if (v.buffer>=d->num_desc-1) {
11383 PRINT(KERN_ERR, ohci->host->id,
11384 "Buffer %d out of range",v.buffer);
11385 return -EINVAL;
11386@@ -1309,7 +1309,7 @@ static struct ieee1394_device_id video13
11387 .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
11388 .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
11389 },
11390- { }
11391+ { 0, 0, 0, 0, 0, 0 }
11392 };
11393
11394 MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
11395diff -urNp linux-2.6.22.1/drivers/input/keyboard/atkbd.c linux-2.6.22.1/drivers/input/keyboard/atkbd.c
11396--- linux-2.6.22.1/drivers/input/keyboard/atkbd.c 2007-07-10 14:56:30.000000000 -0400
11397+++ linux-2.6.22.1/drivers/input/keyboard/atkbd.c 2007-08-02 11:38:46.000000000 -0400
11398@@ -1075,7 +1075,7 @@ static struct serio_device_id atkbd_seri
11399 .id = SERIO_ANY,
11400 .extra = SERIO_ANY,
11401 },
11402- { 0 }
11403+ { 0, 0, 0, 0 }
11404 };
11405
11406 MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
11407diff -urNp linux-2.6.22.1/drivers/input/mouse/lifebook.c linux-2.6.22.1/drivers/input/mouse/lifebook.c
11408--- linux-2.6.22.1/drivers/input/mouse/lifebook.c 2007-07-10 14:56:30.000000000 -0400
11409+++ linux-2.6.22.1/drivers/input/mouse/lifebook.c 2007-08-02 11:38:46.000000000 -0400
11410@@ -102,7 +102,7 @@ static struct dmi_system_id lifebook_dmi
11411 DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
11412 },
11413 },
11414- { }
11415+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11416 };
11417
11418 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
11419diff -urNp linux-2.6.22.1/drivers/input/mouse/psmouse-base.c linux-2.6.22.1/drivers/input/mouse/psmouse-base.c
11420--- linux-2.6.22.1/drivers/input/mouse/psmouse-base.c 2007-07-10 14:56:30.000000000 -0400
11421+++ linux-2.6.22.1/drivers/input/mouse/psmouse-base.c 2007-08-02 11:38:46.000000000 -0400
11422@@ -1296,7 +1296,7 @@ static struct serio_device_id psmouse_se
11423 .id = SERIO_ANY,
11424 .extra = SERIO_ANY,
11425 },
11426- { 0 }
11427+ { 0, 0, 0, 0 }
11428 };
11429
11430 MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
11431diff -urNp linux-2.6.22.1/drivers/input/mouse/synaptics.c linux-2.6.22.1/drivers/input/mouse/synaptics.c
11432--- linux-2.6.22.1/drivers/input/mouse/synaptics.c 2007-07-10 14:56:30.000000000 -0400
11433+++ linux-2.6.22.1/drivers/input/mouse/synaptics.c 2007-08-02 11:38:46.000000000 -0400
11434@@ -417,7 +417,7 @@ static void synaptics_process_packet(str
11435 break;
11436 case 2:
11437 if (SYN_MODEL_PEN(priv->model_id))
11438- ; /* Nothing, treat a pen as a single finger */
11439+ break; /* Nothing, treat a pen as a single finger */
11440 break;
11441 case 4 ... 15:
11442 if (SYN_CAP_PALMDETECT(priv->capabilities))
11443@@ -624,7 +624,7 @@ static struct dmi_system_id toshiba_dmi_
11444 DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
11445 },
11446 },
11447- { }
11448+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11449 };
11450 #endif
11451
11452diff -urNp linux-2.6.22.1/drivers/input/mousedev.c linux-2.6.22.1/drivers/input/mousedev.c
11453--- linux-2.6.22.1/drivers/input/mousedev.c 2007-07-10 14:56:30.000000000 -0400
11454+++ linux-2.6.22.1/drivers/input/mousedev.c 2007-08-02 11:38:46.000000000 -0400
11455@@ -815,7 +815,7 @@ static struct input_handler mousedev_han
11456
11457 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
11458 static struct miscdevice psaux_mouse = {
11459- PSMOUSE_MINOR, "psaux", &mousedev_fops
11460+ PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
11461 };
11462 static int psaux_registered;
11463 #endif
11464diff -urNp linux-2.6.22.1/drivers/input/serio/i8042-x86ia64io.h linux-2.6.22.1/drivers/input/serio/i8042-x86ia64io.h
11465--- linux-2.6.22.1/drivers/input/serio/i8042-x86ia64io.h 2007-07-10 14:56:30.000000000 -0400
11466+++ linux-2.6.22.1/drivers/input/serio/i8042-x86ia64io.h 2007-08-02 11:38:46.000000000 -0400
11467@@ -110,7 +110,7 @@ static struct dmi_system_id __initdata i
11468 DMI_MATCH(DMI_PRODUCT_VERSION, "5a"),
11469 },
11470 },
11471- { }
11472+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11473 };
11474
11475 /*
11476@@ -252,7 +252,7 @@ static struct dmi_system_id __initdata i
11477 DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
11478 },
11479 },
11480- { }
11481+ { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11482 };
11483
11484
11485diff -urNp linux-2.6.22.1/drivers/input/serio/serio_raw.c linux-2.6.22.1/drivers/input/serio/serio_raw.c
11486--- linux-2.6.22.1/drivers/input/serio/serio_raw.c 2007-07-10 14:56:30.000000000 -0400
11487+++ linux-2.6.22.1/drivers/input/serio/serio_raw.c 2007-08-02 11:38:47.000000000 -0400
11488@@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
11489 .id = SERIO_ANY,
11490 .extra = SERIO_ANY,
11491 },
11492- { 0 }
11493+ { 0, 0, 0, 0 }
11494 };
11495
11496 MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
11497diff -urNp linux-2.6.22.1/drivers/kvm/kvm_main.c linux-2.6.22.1/drivers/kvm/kvm_main.c
11498--- linux-2.6.22.1/drivers/kvm/kvm_main.c 2007-07-10 14:56:30.000000000 -0400
11499+++ linux-2.6.22.1/drivers/kvm/kvm_main.c 2007-08-02 11:38:47.000000000 -0400
11500@@ -60,19 +60,19 @@ static struct kvm_stats_debugfs_item {
11501 int offset;
11502 struct dentry *dentry;
11503 } debugfs_entries[] = {
11504- { "pf_fixed", STAT_OFFSET(pf_fixed) },
11505- { "pf_guest", STAT_OFFSET(pf_guest) },
11506- { "tlb_flush", STAT_OFFSET(tlb_flush) },
11507- { "invlpg", STAT_OFFSET(invlpg) },
11508- { "exits", STAT_OFFSET(exits) },
11509- { "io_exits", STAT_OFFSET(io_exits) },
11510- { "mmio_exits", STAT_OFFSET(mmio_exits) },
11511- { "signal_exits", STAT_OFFSET(signal_exits) },
11512- { "irq_window", STAT_OFFSET(irq_window_exits) },
11513- { "halt_exits", STAT_OFFSET(halt_exits) },
11514- { "request_irq", STAT_OFFSET(request_irq_exits) },
11515- { "irq_exits", STAT_OFFSET(irq_exits) },
11516- { NULL }
11517+ { "pf_fixed", STAT_OFFSET(pf_fixed), NULL },
11518+ { "pf_guest", STAT_OFFSET(pf_guest), NULL },
11519+ { "tlb_flush", STAT_OFFSET(tlb_flush), NULL },
11520+ { "invlpg", STAT_OFFSET(invlpg), NULL },
11521+ { "exits", STAT_OFFSET(exits), NULL },
11522+ { "io_exits", STAT_OFFSET(io_exits), NULL },
11523+ { "mmio_exits", STAT_OFFSET(mmio_exits), NULL },
11524+ { "signal_exits", STAT_OFFSET(signal_exits), NULL },
11525+ { "irq_window", STAT_OFFSET(irq_window_exits), NULL },
11526+ { "halt_exits", STAT_OFFSET(halt_exits), NULL },
11527+ { "request_irq", STAT_OFFSET(request_irq_exits), NULL },
11528+ { "irq_exits", STAT_OFFSET(irq_exits), NULL },
11529+ { NULL, NULL, NULL }
11530 };
11531
11532 static struct dentry *debugfs_dir;
11533@@ -2193,7 +2193,7 @@ static int kvm_vcpu_ioctl_translate(stru
11534 static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
11535 struct kvm_interrupt *irq)
11536 {
11537- if (irq->irq < 0 || irq->irq >= 256)
11538+ if (irq->irq >= 256)
11539 return -EINVAL;
11540 vcpu_load(vcpu);
11541
11542@@ -2851,6 +2851,9 @@ static struct miscdevice kvm_dev = {
11543 KVM_MINOR,
11544 "kvm",
11545 &kvm_chardev_ops,
11546+ {NULL, NULL},
11547+ NULL,
11548+ NULL
11549 };
11550
11551 static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
11552diff -urNp linux-2.6.22.1/drivers/kvm/vmx.c linux-2.6.22.1/drivers/kvm/vmx.c
11553--- linux-2.6.22.1/drivers/kvm/vmx.c 2007-07-10 14:56:30.000000000 -0400
11554+++ linux-2.6.22.1/drivers/kvm/vmx.c 2007-08-02 11:38:47.000000000 -0400
11555@@ -2013,7 +2013,7 @@ again:
11556
11557 vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
11558
11559- asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
11560+ asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
11561
11562 if (fail) {
11563 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
11564diff -urNp linux-2.6.22.1/drivers/md/bitmap.c linux-2.6.22.1/drivers/md/bitmap.c
11565--- linux-2.6.22.1/drivers/md/bitmap.c 2007-07-10 14:56:30.000000000 -0400
11566+++ linux-2.6.22.1/drivers/md/bitmap.c 2007-08-02 11:38:47.000000000 -0400
11567@@ -57,7 +57,7 @@
11568 # if DEBUG > 0
11569 # define PRINTK(x...) printk(KERN_DEBUG x)
11570 # else
11571-# define PRINTK(x...)
11572+# define PRINTK(x...) do {} while (0)
11573 # endif
11574 #endif
11575
11576diff -urNp linux-2.6.22.1/drivers/mtd/devices/doc2001.c linux-2.6.22.1/drivers/mtd/devices/doc2001.c
11577--- linux-2.6.22.1/drivers/mtd/devices/doc2001.c 2007-07-10 14:56:30.000000000 -0400
11578+++ linux-2.6.22.1/drivers/mtd/devices/doc2001.c 2007-08-02 11:09:15.000000000 -0400
11579@@ -398,6 +398,8 @@ static int doc_read (struct mtd_info *mt
11580 /* Don't allow read past end of device */
11581 if (from >= this->totlen)
11582 return -EINVAL;
11583+ if (!len)
11584+ return -EINVAL;
11585
11586 /* Don't allow a single read to cross a 512-byte block boundary */
11587 if (from + len > ((from | 0x1ff) + 1))
11588diff -urNp linux-2.6.22.1/drivers/net/eepro100.c linux-2.6.22.1/drivers/net/eepro100.c
11589--- linux-2.6.22.1/drivers/net/eepro100.c 2007-07-10 14:56:30.000000000 -0400
11590+++ linux-2.6.22.1/drivers/net/eepro100.c 2007-08-02 11:38:47.000000000 -0400
11591@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
11592 # define rx_align(skb) skb_reserve((skb), 2)
11593 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
11594 #else
11595-# define rx_align(skb)
11596+# define rx_align(skb) do {} while (0)
11597 # define RxFD_ALIGNMENT
11598 #endif
11599
11600@@ -2339,33 +2339,33 @@ static void __devexit eepro100_remove_on
11601 }
11602
11603 static struct pci_device_id eepro100_pci_tbl[] = {
11604- { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
11605- { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
11606- { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
11607- { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
11608- { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
11609- { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
11610- { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
11611- { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
11612- { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
11613- { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
11614- { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
11615- { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
11616- { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
11617- { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
11618- { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
11619- { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
11620- { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
11621- { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
11622- { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
11623- { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
11624- { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
11625- { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
11626- { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
11627- { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
11628- { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
11629- { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
11630- { 0,}
11631+ { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11632+ { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11633+ { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11634+ { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11635+ { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11636+ { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11637+ { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11638+ { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11639+ { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11640+ { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11641+ { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11642+ { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11643+ { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11644+ { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11645+ { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11646+ { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11647+ { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11648+ { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11649+ { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11650+ { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11651+ { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11652+ { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11653+ { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11654+ { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11655+ { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11656+ { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
11657+ { 0, 0, 0, 0, 0, 0, 0 }
11658 };
11659 MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
11660
11661diff -urNp linux-2.6.22.1/drivers/net/pcnet32.c linux-2.6.22.1/drivers/net/pcnet32.c
11662--- linux-2.6.22.1/drivers/net/pcnet32.c 2007-07-10 14:56:30.000000000 -0400
11663+++ linux-2.6.22.1/drivers/net/pcnet32.c 2007-08-02 11:38:47.000000000 -0400
11664@@ -82,7 +82,7 @@ static int cards_found;
11665 /*
11666 * VLB I/O addresses
11667 */
11668-static unsigned int pcnet32_portlist[] __initdata =
11669+static unsigned int pcnet32_portlist[] __devinitdata =
11670 { 0x300, 0x320, 0x340, 0x360, 0 };
11671
11672 static int pcnet32_debug = 0;
11673diff -urNp linux-2.6.22.1/drivers/net/tg3.h linux-2.6.22.1/drivers/net/tg3.h
11674--- linux-2.6.22.1/drivers/net/tg3.h 2007-07-10 14:56:30.000000000 -0400
11675+++ linux-2.6.22.1/drivers/net/tg3.h 2007-08-02 11:38:47.000000000 -0400
11676@@ -127,6 +127,7 @@
11677 #define CHIPREV_ID_5750_A0 0x4000
11678 #define CHIPREV_ID_5750_A1 0x4001
11679 #define CHIPREV_ID_5750_A3 0x4003
11680+#define CHIPREV_ID_5750_C1 0x4201
11681 #define CHIPREV_ID_5750_C2 0x4202
11682 #define CHIPREV_ID_5752_A0_HW 0x5000
11683 #define CHIPREV_ID_5752_A0 0x6000
11684diff -urNp linux-2.6.22/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.22/drivers/pci/hotplug/cpqphp_nvram.c
11685--- linux-2.6.22/drivers/pci/hotplug/cpqphp_nvram.c 2007-07-10 14:56:30.000000000 -0400
11686+++ linux-2.6.22/drivers/pci/hotplug/cpqphp_nvram.c 2007-07-10 14:56:30.000000000 -0400
11687@@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
11688
11689 void compaq_nvram_init (void __iomem *rom_start)
11690 {
11691+
11692+#ifndef CONFIG_PAX_KERNEXEC
11693 if (rom_start) {
11694 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
11695 }
11696+#endif
11697+
11698 dbg("int15 entry = %p\n", compaq_int15_entry_point);
11699
11700 /* initialize our int15 lock */
11701diff -urNp linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv.c linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv.c
11702--- linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv.c 2007-07-10 14:56:30.000000000 -0400
11703+++ linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv.c 2007-08-02 11:38:47.000000000 -0400
11704@@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
11705 .port_type = PCIE_RC_PORT,
11706 .service_type = PCIE_PORT_SERVICE_AER,
11707 },
11708- { /* end: all zeroes */ }
11709+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11710 };
11711
11712 static struct pci_error_handlers aer_error_handlers = {
11713diff -urNp linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv_core.c
11714--- linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv_core.c 2007-07-10 14:56:30.000000000 -0400
11715+++ linux-2.6.22.1/drivers/pci/pcie/aer/aerdrv_core.c 2007-08-02 11:38:47.000000000 -0400
11716@@ -647,7 +647,7 @@ static void aer_isr_one_error(struct pci
11717 struct aer_err_source *e_src)
11718 {
11719 struct device *s_device;
11720- struct aer_err_info e_info = {0, 0, 0,};
11721+ struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
11722 int i;
11723 u16 id;
11724
11725diff -urNp linux-2.6.22.1/drivers/pci/pcie/portdrv_pci.c linux-2.6.22.1/drivers/pci/pcie/portdrv_pci.c
11726--- linux-2.6.22.1/drivers/pci/pcie/portdrv_pci.c 2007-07-10 14:56:30.000000000 -0400
11727+++ linux-2.6.22.1/drivers/pci/pcie/portdrv_pci.c 2007-08-02 11:38:47.000000000 -0400
11728@@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
11729 static const struct pci_device_id port_pci_ids[] = { {
11730 /* handle any PCI-Express port */
11731 PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
11732- }, { /* end: all zeroes */ }
11733+ }, { 0, 0, 0, 0, 0, 0, 0 }
11734 };
11735 MODULE_DEVICE_TABLE(pci, port_pci_ids);
11736
11737diff -urNp linux-2.6.22.1/drivers/pci/proc.c linux-2.6.22.1/drivers/pci/proc.c
11738--- linux-2.6.22.1/drivers/pci/proc.c 2007-07-10 14:56:30.000000000 -0400
11739+++ linux-2.6.22.1/drivers/pci/proc.c 2007-08-02 11:09:15.000000000 -0400
11740@@ -466,7 +466,15 @@ static int __init pci_proc_init(void)
11741 {
11742 struct proc_dir_entry *entry;
11743 struct pci_dev *dev = NULL;
11744+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11745+#ifdef CONFIG_GRKERNSEC_PROC_USER
11746+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
11747+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11748+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
11749+#endif
11750+#else
11751 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
11752+#endif
11753 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
11754 if (entry)
11755 entry->proc_fops = &proc_bus_pci_dev_operations;
11756diff -urNp linux-2.6.22.1/drivers/pcmcia/ti113x.h linux-2.6.22.1/drivers/pcmcia/ti113x.h
11757--- linux-2.6.22.1/drivers/pcmcia/ti113x.h 2007-07-10 14:56:30.000000000 -0400
11758+++ linux-2.6.22.1/drivers/pcmcia/ti113x.h 2007-08-02 11:38:47.000000000 -0400
11759@@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
11760 DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
11761 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
11762
11763- {}
11764+ { 0, 0, 0, 0, 0, 0, 0 }
11765 };
11766
11767 static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
11768diff -urNp linux-2.6.22.1/drivers/pcmcia/yenta_socket.c linux-2.6.22.1/drivers/pcmcia/yenta_socket.c
11769--- linux-2.6.22.1/drivers/pcmcia/yenta_socket.c 2007-07-10 14:56:30.000000000 -0400
11770+++ linux-2.6.22.1/drivers/pcmcia/yenta_socket.c 2007-08-02 11:38:47.000000000 -0400
11771@@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table
11772
11773 /* match any cardbus bridge */
11774 CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
11775- { /* all zeroes */ }
11776+ { 0, 0, 0, 0, 0, 0, 0 }
11777 };
11778 MODULE_DEVICE_TABLE(pci, yenta_table);
11779
11780diff -urNp linux-2.6.22.1/drivers/pnp/pnpbios/bioscalls.c linux-2.6.22.1/drivers/pnp/pnpbios/bioscalls.c
11781--- linux-2.6.22.1/drivers/pnp/pnpbios/bioscalls.c 2007-07-10 14:56:30.000000000 -0400
11782+++ linux-2.6.22.1/drivers/pnp/pnpbios/bioscalls.c 2007-08-02 11:38:47.000000000 -0400
11783@@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
11784 set_limit(gdt[(selname) >> 3], size); \
11785 } while(0)
11786
11787-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
11788+static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
11789
11790 /*
11791 * At some point we want to use this stack frame pointer to unwind
11792@@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
11793 struct desc_struct save_desc_40;
11794 int cpu;
11795
11796+#ifdef CONFIG_PAX_KERNEXEC
11797+ unsigned long cr0;
11798+#endif
11799+
11800 /*
11801 * PnP BIOSes are generally not terribly re-entrant.
11802 * Also, don't rely on them to save everything correctly.
11803@@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
11804 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
11805 spin_lock_irqsave(&pnp_bios_lock, flags);
11806
11807+#ifdef CONFIG_PAX_KERNEXEC
11808+ pax_open_kernel(cr0);
11809+#endif
11810+
11811 /* The lock prevents us bouncing CPU here */
11812 if (ts1_size)
11813 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
11814@@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
11815 "i" (0)
11816 : "memory"
11817 );
11818- spin_unlock_irqrestore(&pnp_bios_lock, flags);
11819
11820 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
11821+
11822+#ifdef CONFIG_PAX_KERNEXEC
11823+ pax_close_kernel(cr0);
11824+#endif
11825+
11826+ spin_unlock_irqrestore(&pnp_bios_lock, flags);
11827 put_cpu();
11828
11829 /* If we get here and this is set then the PnP BIOS faulted on us. */
11830@@ -515,15 +528,25 @@ static int pnp_bios_write_escd(char *dat
11831 * Initialization
11832 */
11833
11834-void pnpbios_calls_init(union pnp_bios_install_struct *header)
11835+void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
11836 {
11837 int i;
11838+
11839+#ifdef CONFIG_PAX_KERNEXEC
11840+ unsigned long cr0;
11841+#endif
11842+
11843 spin_lock_init(&pnp_bios_lock);
11844 pnp_bios_callpoint.offset = header->fields.pm16offset;
11845 pnp_bios_callpoint.segment = PNP_CS16;
11846
11847 set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
11848 _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
11849+
11850+#ifdef CONFIG_PAX_KERNEXEC
11851+ pax_open_kernel(cr0);
11852+#endif
11853+
11854 for (i = 0; i < NR_CPUS; i++) {
11855 struct desc_struct *gdt = get_cpu_gdt_table(i);
11856 if (!gdt)
11857@@ -532,4 +555,9 @@ void pnpbios_calls_init(union pnp_bios_i
11858 set_base(gdt[GDT_ENTRY_PNPBIOS_CS16], __va(header->fields.pm16cseg));
11859 set_base(gdt[GDT_ENTRY_PNPBIOS_DS], __va(header->fields.pm16dseg));
11860 }
11861+
11862+#ifdef CONFIG_PAX_KERNEXEC
11863+ pax_close_kernel(cr0);
11864+#endif
11865+
11866 }
11867diff -urNp linux-2.6.22.1/drivers/pnp/quirks.c linux-2.6.22.1/drivers/pnp/quirks.c
11868--- linux-2.6.22.1/drivers/pnp/quirks.c 2007-07-10 14:56:30.000000000 -0400
11869+++ linux-2.6.22.1/drivers/pnp/quirks.c 2007-08-02 11:38:47.000000000 -0400
11870@@ -231,7 +231,7 @@ static struct pnp_fixup pnp_fixups[] = {
11871 { "CTL0044", quirk_sb16audio_resources },
11872 { "CTL0045", quirk_sb16audio_resources },
11873 { "SMCf010", quirk_smc_enable },
11874- { "" }
11875+ { "", NULL }
11876 };
11877
11878 void pnp_fixup_device(struct pnp_dev *dev)
11879diff -urNp linux-2.6.22.1/drivers/pnp/resource.c linux-2.6.22.1/drivers/pnp/resource.c
11880--- linux-2.6.22.1/drivers/pnp/resource.c 2007-07-10 14:56:30.000000000 -0400
11881+++ linux-2.6.22.1/drivers/pnp/resource.c 2007-08-02 11:38:47.000000000 -0400
11882@@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev,
11883 return 1;
11884
11885 /* check if the resource is valid */
11886- if (*irq < 0 || *irq > 15)
11887+ if (*irq > 15)
11888 return 0;
11889
11890 /* check if the resource is reserved */
11891@@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev,
11892 return 1;
11893
11894 /* check if the resource is valid */
11895- if (*dma < 0 || *dma == 4 || *dma > 7)
11896+ if (*dma == 4 || *dma > 7)
11897 return 0;
11898
11899 /* check if the resource is reserved */
11900diff -urNp linux-2.6.22.1/drivers/scsi/scsi_lib.c linux-2.6.22.1/drivers/scsi/scsi_lib.c
11901--- linux-2.6.22.1/drivers/scsi/scsi_lib.c 2007-07-10 14:56:30.000000000 -0400
11902+++ linux-2.6.22.1/drivers/scsi/scsi_lib.c 2007-08-02 11:38:47.000000000 -0400
11903@@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
11904 #error SCSI_MAX_PHYS_SEGMENTS is too small
11905 #endif
11906
11907-#define SP(x) { x, "sgpool-" #x }
11908+#define SP(x) { x, "sgpool-" #x, NULL, NULL }
11909 static struct scsi_host_sg_pool scsi_sg_pools[] = {
11910 SP(8),
11911 SP(16),
11912diff -urNp linux-2.6.22.1/drivers/scsi/scsi_logging.h linux-2.6.22.1/drivers/scsi/scsi_logging.h
11913--- linux-2.6.22.1/drivers/scsi/scsi_logging.h 2007-07-10 14:56:30.000000000 -0400
11914+++ linux-2.6.22.1/drivers/scsi/scsi_logging.h 2007-08-02 11:38:47.000000000 -0400
11915@@ -51,7 +51,7 @@ do { \
11916 } while (0); \
11917 } while (0)
11918 #else
11919-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
11920+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
11921 #endif /* CONFIG_SCSI_LOGGING */
11922
11923 /*
11924diff -urNp linux-2.6.22.1/drivers/serial/8250_pci.c linux-2.6.22.1/drivers/serial/8250_pci.c
11925--- linux-2.6.22.1/drivers/serial/8250_pci.c 2007-07-10 14:56:30.000000000 -0400
11926+++ linux-2.6.22.1/drivers/serial/8250_pci.c 2007-08-02 11:38:47.000000000 -0400
11927@@ -2417,7 +2417,7 @@ static struct pci_device_id serial_pci_t
11928 PCI_ANY_ID, PCI_ANY_ID,
11929 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
11930 0xffff00, pbn_default },
11931- { 0, }
11932+ { 0, 0, 0, 0, 0, 0, 0 }
11933 };
11934
11935 static struct pci_driver serial_pci_driver = {
11936diff -urNp linux-2.6.22.1/drivers/usb/class/cdc-acm.c linux-2.6.22.1/drivers/usb/class/cdc-acm.c
11937--- linux-2.6.22.1/drivers/usb/class/cdc-acm.c 2007-07-10 14:56:30.000000000 -0400
11938+++ linux-2.6.22.1/drivers/usb/class/cdc-acm.c 2007-08-02 11:38:47.000000000 -0400
11939@@ -1188,7 +1188,7 @@ static struct usb_device_id acm_ids[] =
11940 USB_CDC_ACM_PROTO_AT_CDMA) },
11941
11942 /* NOTE: COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
11943- { }
11944+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11945 };
11946
11947 MODULE_DEVICE_TABLE (usb, acm_ids);
11948diff -urNp linux-2.6.22.1/drivers/usb/class/usblp.c linux-2.6.22.1/drivers/usb/class/usblp.c
11949--- linux-2.6.22.1/drivers/usb/class/usblp.c 2007-07-10 14:56:30.000000000 -0400
11950+++ linux-2.6.22.1/drivers/usb/class/usblp.c 2007-08-02 11:38:47.000000000 -0400
11951@@ -219,7 +219,7 @@ static const struct quirk_printer_struct
11952 { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
11953 { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
11954 { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
11955- { 0, 0 }
11956+ { 0, 0, 0 }
11957 };
11958
11959 static int usblp_select_alts(struct usblp *usblp);
11960@@ -1234,7 +1234,7 @@ static struct usb_device_id usblp_ids []
11961 { USB_INTERFACE_INFO(7, 1, 2) },
11962 { USB_INTERFACE_INFO(7, 1, 3) },
11963 { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
11964- { } /* Terminating entry */
11965+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
11966 };
11967
11968 MODULE_DEVICE_TABLE (usb, usblp_ids);
11969diff -urNp linux-2.6.22.1/drivers/usb/core/hub.c linux-2.6.22.1/drivers/usb/core/hub.c
11970--- linux-2.6.22.1/drivers/usb/core/hub.c 2007-07-10 14:56:30.000000000 -0400
11971+++ linux-2.6.22.1/drivers/usb/core/hub.c 2007-08-02 11:38:47.000000000 -0400
11972@@ -2833,7 +2833,7 @@ static struct usb_device_id hub_id_table
11973 .bDeviceClass = USB_CLASS_HUB},
11974 { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
11975 .bInterfaceClass = USB_CLASS_HUB},
11976- { } /* Terminating entry */
11977+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminating entry */
11978 };
11979
11980 MODULE_DEVICE_TABLE (usb, hub_id_table);
11981diff -urNp linux-2.6.22.1/drivers/usb/host/ehci-pci.c linux-2.6.22.1/drivers/usb/host/ehci-pci.c
11982--- linux-2.6.22.1/drivers/usb/host/ehci-pci.c 2007-07-10 14:56:30.000000000 -0400
11983+++ linux-2.6.22.1/drivers/usb/host/ehci-pci.c 2007-08-02 11:38:47.000000000 -0400
11984@@ -377,7 +377,7 @@ static const struct pci_device_id pci_id
11985 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
11986 .driver_data = (unsigned long) &ehci_pci_hc_driver,
11987 },
11988- { /* end: all zeroes */ }
11989+ { 0, 0, 0, 0, 0, 0, 0 }
11990 };
11991 MODULE_DEVICE_TABLE(pci, pci_ids);
11992
11993diff -urNp linux-2.6.22.1/drivers/usb/host/uhci-hcd.c linux-2.6.22.1/drivers/usb/host/uhci-hcd.c
11994--- linux-2.6.22.1/drivers/usb/host/uhci-hcd.c 2007-07-10 14:56:30.000000000 -0400
11995+++ linux-2.6.22.1/drivers/usb/host/uhci-hcd.c 2007-08-02 11:38:47.000000000 -0400
11996@@ -895,7 +895,7 @@ static const struct pci_device_id uhci_p
11997 /* handle any USB UHCI controller */
11998 PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
11999 .driver_data = (unsigned long) &uhci_driver,
12000- }, { /* end: all zeroes */ }
12001+ }, { 0, 0, 0, 0, 0, 0, 0 }
12002 };
12003
12004 MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
12005diff -urNp linux-2.6.22.1/drivers/usb/storage/debug.h linux-2.6.22.1/drivers/usb/storage/debug.h
12006--- linux-2.6.22.1/drivers/usb/storage/debug.h 2007-07-10 14:56:30.000000000 -0400
12007+++ linux-2.6.22.1/drivers/usb/storage/debug.h 2007-08-02 11:38:47.000000000 -0400
12008@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
12009 #define US_DEBUGPX(x...) printk( x )
12010 #define US_DEBUG(x) x
12011 #else
12012-#define US_DEBUGP(x...)
12013-#define US_DEBUGPX(x...)
12014-#define US_DEBUG(x)
12015+#define US_DEBUGP(x...) do {} while (0)
12016+#define US_DEBUGPX(x...) do {} while (0)
12017+#define US_DEBUG(x) do {} while (0)
12018 #endif
12019
12020 #endif
12021diff -urNp linux-2.6.22.1/drivers/usb/storage/usb.c linux-2.6.22.1/drivers/usb/storage/usb.c
12022--- linux-2.6.22.1/drivers/usb/storage/usb.c 2007-07-10 14:56:30.000000000 -0400
12023+++ linux-2.6.22.1/drivers/usb/storage/usb.c 2007-08-02 11:38:47.000000000 -0400
12024@@ -141,7 +141,7 @@ static struct usb_device_id storage_usb_
12025 #undef UNUSUAL_DEV
12026 #undef USUAL_DEV
12027 /* Terminating entry */
12028- { }
12029+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
12030 };
12031
12032 MODULE_DEVICE_TABLE (usb, storage_usb_ids);
12033@@ -181,7 +181,7 @@ static struct us_unusual_dev us_unusual_
12034 # undef USUAL_DEV
12035
12036 /* Terminating entry */
12037- { NULL }
12038+ { NULL, NULL, 0, 0, NULL }
12039 };
12040
12041
12042diff -urNp linux-2.6.22.1/drivers/video/fbcmap.c linux-2.6.22.1/drivers/video/fbcmap.c
12043--- linux-2.6.22.1/drivers/video/fbcmap.c 2007-07-10 14:56:30.000000000 -0400
12044+++ linux-2.6.22.1/drivers/video/fbcmap.c 2007-08-02 11:38:47.000000000 -0400
12045@@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user
12046 int rc, size = cmap->len * sizeof(u16);
12047 struct fb_cmap umap;
12048
12049- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
12050- !info->fbops->fb_setcmap))
12051+ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
12052 return -EINVAL;
12053
12054 memset(&umap, 0, sizeof(struct fb_cmap));
12055diff -urNp linux-2.6.22.1/drivers/video/fbmem.c linux-2.6.22.1/drivers/video/fbmem.c
12056--- linux-2.6.22.1/drivers/video/fbmem.c 2007-07-10 14:56:30.000000000 -0400
12057+++ linux-2.6.22.1/drivers/video/fbmem.c 2007-08-02 11:38:47.000000000 -0400
12058@@ -392,7 +392,7 @@ static void fb_do_show_logo(struct fb_in
12059 image->dx += image->width + 8;
12060 }
12061 } else if (rotate == FB_ROTATE_UD) {
12062- for (x = 0; x < num && image->dx >= 0; x++) {
12063+ for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
12064 info->fbops->fb_imageblit(info, image);
12065 image->dx -= image->width + 8;
12066 }
12067@@ -404,7 +404,7 @@ static void fb_do_show_logo(struct fb_in
12068 image->dy += image->height + 8;
12069 }
12070 } else if (rotate == FB_ROTATE_CCW) {
12071- for (x = 0; x < num && image->dy >= 0; x++) {
12072+ for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
12073 info->fbops->fb_imageblit(info, image);
12074 image->dy -= image->height + 8;
12075 }
12076@@ -973,9 +973,9 @@ fb_ioctl(struct inode *inode, struct fil
12077 case FBIOPUT_CON2FBMAP:
12078 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
12079 return - EFAULT;
12080- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
12081+ if (con2fb.console > MAX_NR_CONSOLES)
12082 return -EINVAL;
12083- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
12084+ if (con2fb.framebuffer >= FB_MAX)
12085 return -EINVAL;
12086 #ifdef CONFIG_KMOD
12087 if (!registered_fb[con2fb.framebuffer])
12088diff -urNp linux-2.6.22.1/drivers/video/fbmon.c linux-2.6.22.1/drivers/video/fbmon.c
12089--- linux-2.6.22.1/drivers/video/fbmon.c 2007-07-10 14:56:30.000000000 -0400
12090+++ linux-2.6.22.1/drivers/video/fbmon.c 2007-08-02 11:38:47.000000000 -0400
12091@@ -45,7 +45,7 @@
12092 #ifdef DEBUG
12093 #define DPRINTK(fmt, args...) printk(fmt,## args)
12094 #else
12095-#define DPRINTK(fmt, args...)
12096+#define DPRINTK(fmt, args...) do {} while (0)
12097 #endif
12098
12099 #define FBMON_FIX_HEADER 1
12100diff -urNp linux-2.6.22.1/drivers/video/i810/i810_accel.c linux-2.6.22.1/drivers/video/i810/i810_accel.c
12101--- linux-2.6.22.1/drivers/video/i810/i810_accel.c 2007-07-10 14:56:30.000000000 -0400
12102+++ linux-2.6.22.1/drivers/video/i810/i810_accel.c 2007-08-02 11:38:47.000000000 -0400
12103@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
12104 }
12105 }
12106 printk("ringbuffer lockup!!!\n");
12107+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
12108 i810_report_error(mmio);
12109 par->dev_flags |= LOCKUP;
12110 info->pixmap.scan_align = 1;
12111diff -urNp linux-2.6.22.1/drivers/video/i810/i810_main.c linux-2.6.22.1/drivers/video/i810/i810_main.c
12112--- linux-2.6.22.1/drivers/video/i810/i810_main.c 2007-07-10 14:56:30.000000000 -0400
12113+++ linux-2.6.22.1/drivers/video/i810/i810_main.c 2007-08-02 11:38:47.000000000 -0400
12114@@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
12115 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
12116 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
12117 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
12118- { 0 },
12119+ { 0, 0, 0, 0, 0, 0, 0 },
12120 };
12121
12122 static struct pci_driver i810fb_driver = {
12123@@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info
12124 int size = ((cursor->image.width + 7) >> 3) *
12125 cursor->image.height;
12126 int i;
12127- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
12128+ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
12129
12130 if (data == NULL)
12131 return -ENOMEM;
12132diff -urNp linux-2.6.22.1/drivers/video/modedb.c linux-2.6.22.1/drivers/video/modedb.c
12133--- linux-2.6.22.1/drivers/video/modedb.c 2007-07-10 14:56:30.000000000 -0400
12134+++ linux-2.6.22.1/drivers/video/modedb.c 2007-08-02 11:38:47.000000000 -0400
12135@@ -37,228 +37,228 @@ static const struct fb_videomode modedb[
12136 {
12137 /* 640x400 @ 70 Hz, 31.5 kHz hsync */
12138 NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
12139- 0, FB_VMODE_NONINTERLACED
12140+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12141 }, {
12142 /* 640x480 @ 60 Hz, 31.5 kHz hsync */
12143 NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
12144- 0, FB_VMODE_NONINTERLACED
12145+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12146 }, {
12147 /* 800x600 @ 56 Hz, 35.15 kHz hsync */
12148 NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
12149- 0, FB_VMODE_NONINTERLACED
12150+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12151 }, {
12152 /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
12153 NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
12154- 0, FB_VMODE_INTERLACED
12155+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
12156 }, {
12157 /* 640x400 @ 85 Hz, 37.86 kHz hsync */
12158 NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
12159- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12160+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12161 }, {
12162 /* 640x480 @ 72 Hz, 36.5 kHz hsync */
12163 NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
12164- 0, FB_VMODE_NONINTERLACED
12165+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12166 }, {
12167 /* 640x480 @ 75 Hz, 37.50 kHz hsync */
12168 NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
12169- 0, FB_VMODE_NONINTERLACED
12170+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12171 }, {
12172 /* 800x600 @ 60 Hz, 37.8 kHz hsync */
12173 NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
12174- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12175+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12176 }, {
12177 /* 640x480 @ 85 Hz, 43.27 kHz hsync */
12178 NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
12179- 0, FB_VMODE_NONINTERLACED
12180+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12181 }, {
12182 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
12183 NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
12184- 0, FB_VMODE_INTERLACED
12185+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
12186 }, {
12187 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
12188 NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
12189- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12190+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12191 }, {
12192 /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
12193 NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
12194- 0, FB_VMODE_NONINTERLACED
12195+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12196 }, {
12197 /* 640x480 @ 100 Hz, 53.01 kHz hsync */
12198 NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
12199- 0, FB_VMODE_NONINTERLACED
12200+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12201 }, {
12202 /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
12203 NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
12204- 0, FB_VMODE_NONINTERLACED
12205+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12206 }, {
12207 /* 800x600 @ 85 Hz, 55.84 kHz hsync */
12208 NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
12209- 0, FB_VMODE_NONINTERLACED
12210+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12211 }, {
12212 /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
12213 NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
12214- 0, FB_VMODE_NONINTERLACED
12215+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12216 }, {
12217 /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
12218 NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
12219- 0, FB_VMODE_INTERLACED
12220+ 0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
12221 }, {
12222 /* 800x600 @ 100 Hz, 64.02 kHz hsync */
12223 NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
12224- 0, FB_VMODE_NONINTERLACED
12225+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12226 }, {
12227 /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
12228 NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
12229- 0, FB_VMODE_NONINTERLACED
12230+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12231 }, {
12232 /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
12233 NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
12234- 0, FB_VMODE_NONINTERLACED
12235+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12236 }, {
12237 /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
12238 NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
12239- 0, FB_VMODE_NONINTERLACED
12240+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12241 }, {
12242 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
12243 NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
12244- 0, FB_VMODE_NONINTERLACED
12245+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12246 }, {
12247 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
12248 NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
12249- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12250+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12251 }, {
12252 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
12253 NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
12254- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12255+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12256 }, {
12257 /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
12258 NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
12259- 0, FB_VMODE_NONINTERLACED
12260+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12261 }, {
12262 /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
12263 NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
12264- 0, FB_VMODE_NONINTERLACED
12265+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12266 }, {
12267 /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
12268 NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
12269- 0, FB_VMODE_NONINTERLACED
12270+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12271 }, {
12272 /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
12273 NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
12274- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12275+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12276 }, {
12277 /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
12278 NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
12279- 0, FB_VMODE_NONINTERLACED
12280+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12281 }, {
12282 /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
12283 NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
12284- 0, FB_VMODE_NONINTERLACED
12285+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12286 }, {
12287 /* 1024x768 @ 100Hz, 80.21 kHz hsync */
12288 NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
12289- 0, FB_VMODE_NONINTERLACED
12290+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12291 }, {
12292 /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
12293 NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
12294- 0, FB_VMODE_NONINTERLACED
12295+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12296 }, {
12297 /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
12298 NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
12299- 0, FB_VMODE_NONINTERLACED
12300+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12301 }, {
12302 /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
12303 NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
12304- 0, FB_VMODE_NONINTERLACED
12305+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12306 }, {
12307 /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
12308 NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
12309- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12310+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12311 }, {
12312 /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
12313 NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
12314- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12315+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12316 }, {
12317 /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
12318 NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
12319- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12320+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12321 }, {
12322 /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
12323 NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
12324- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12325+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12326 }, {
12327 /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
12328 NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
12329- 0, FB_VMODE_NONINTERLACED
12330+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12331 }, {
12332 /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
12333 NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
12334- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12335+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12336 }, {
12337 /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
12338 NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
12339- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12340+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12341 }, {
12342 /* 512x384 @ 78 Hz, 31.50 kHz hsync */
12343 NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
12344- 0, FB_VMODE_NONINTERLACED
12345+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12346 }, {
12347 /* 512x384 @ 85 Hz, 34.38 kHz hsync */
12348 NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
12349- 0, FB_VMODE_NONINTERLACED
12350+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12351 }, {
12352 /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
12353 NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
12354- 0, FB_VMODE_DOUBLE
12355+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12356 }, {
12357 /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
12358 NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
12359- 0, FB_VMODE_DOUBLE
12360+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12361 }, {
12362 /* 320x240 @ 72 Hz, 36.5 kHz hsync */
12363 NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
12364- 0, FB_VMODE_DOUBLE
12365+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12366 }, {
12367 /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
12368 NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
12369- 0, FB_VMODE_DOUBLE
12370+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12371 }, {
12372 /* 400x300 @ 60 Hz, 37.8 kHz hsync */
12373 NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
12374- 0, FB_VMODE_DOUBLE
12375+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12376 }, {
12377 /* 400x300 @ 72 Hz, 48.0 kHz hsync */
12378 NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
12379- 0, FB_VMODE_DOUBLE
12380+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12381 }, {
12382 /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
12383 NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
12384- 0, FB_VMODE_DOUBLE
12385+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12386 }, {
12387 /* 480x300 @ 60 Hz, 37.8 kHz hsync */
12388 NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
12389- 0, FB_VMODE_DOUBLE
12390+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12391 }, {
12392 /* 480x300 @ 63 Hz, 39.6 kHz hsync */
12393 NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
12394- 0, FB_VMODE_DOUBLE
12395+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12396 }, {
12397 /* 480x300 @ 72 Hz, 48.0 kHz hsync */
12398 NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
12399- 0, FB_VMODE_DOUBLE
12400+ 0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
12401 }, {
12402 /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
12403 NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
12404 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
12405- FB_VMODE_NONINTERLACED
12406+ FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12407 }, {
12408 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
12409 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
12410- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
12411+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12412 }, {
12413 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
12414 NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
12415- 0, FB_VMODE_NONINTERLACED
12416+ 0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
12417 },
12418 };
12419
12420diff -urNp linux-2.6.22/drivers/video/vesafb.c linux-2.6.22/drivers/video/vesafb.c
12421--- linux-2.6.22/drivers/video/vesafb.c 2007-07-10 14:56:30.000000000 -0400
12422+++ linux-2.6.22/drivers/video/vesafb.c 2007-07-10 14:56:30.000000000 -0400
12423@@ -9,6 +9,7 @@
12424 */
12425
12426 #include <linux/module.h>
12427+#include <linux/moduleloader.h>
12428 #include <linux/kernel.h>
12429 #include <linux/errno.h>
12430 #include <linux/string.h>
12431@@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
12432 unsigned int size_vmode;
12433 unsigned int size_remap;
12434 unsigned int size_total;
12435+ void *pmi_code = NULL;
12436
12437 if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
12438 return -ENODEV;
12439@@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
12440 size_remap = size_total;
12441 vesafb_fix.smem_len = size_remap;
12442
12443-#ifndef __i386__
12444- screen_info.vesapm_seg = 0;
12445-#endif
12446-
12447 if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
12448 printk(KERN_WARNING
12449 "vesafb: cannot reserve video memory at 0x%lx\n",
12450@@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
12451 printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
12452 vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
12453
12454+#ifdef __i386__
12455+
12456+#ifdef CONFIG_PAX_KERNEXEC
12457+ pmi_code = module_alloc_exec(screen_info.vesapm_size);
12458+ if (!pmi_code)
12459+#else
12460+ if (0)
12461+#endif
12462+
12463+#endif
12464+ screen_info.vesapm_seg = 0;
12465+
12466 if (screen_info.vesapm_seg) {
12467- printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
12468- screen_info.vesapm_seg,screen_info.vesapm_off);
12469+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
12470+ screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
12471 }
12472
12473 if (screen_info.vesapm_seg < 0xc000)
12474@@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
12475
12476 if (ypan || pmi_setpal) {
12477 unsigned short *pmi_base;
12478- pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
12479- pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
12480- pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
12481+
12482+#ifdef CONFIG_PAX_KERNEXEC
12483+ unsigned long cr0;
12484+#endif
12485+
12486+ pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
12487+
12488+#ifdef CONFIG_PAX_KERNEXEC
12489+ pax_open_kernel(cr0);
12490+ memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
12491+ pax_close_kernel(cr0);
12492+#else
12493+ pmi_code = pmi_base;
12494+#endif
12495+
12496+ pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
12497+ pmi_pal = (void*)((char*)pmi_code + pmi_base[2]);
12498+
12499+#ifdef CONFIG_PAX_KERNEXEC
12500+ pmi_start -= __KERNEL_TEXT_OFFSET;
12501+ pmi_pal -= __KERNEL_TEXT_OFFSET;
12502+#endif
12503+
12504 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
12505 if (pmi_base[3]) {
12506 printk(KERN_INFO "vesafb: pmi: ports = ");
12507@@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
12508 info->node, info->fix.id);
12509 return 0;
12510 err:
12511+
12512+#ifdef CONFIG_PAX_KERNEXEC
12513+ module_free_exec(NULL, pmi_code);
12514+#endif
12515+
12516 if (info->screen_base)
12517 iounmap(info->screen_base);
12518 framebuffer_release(info);
12519diff -urNp linux-2.6.22.1/fs/binfmt_aout.c linux-2.6.22.1/fs/binfmt_aout.c
12520--- linux-2.6.22.1/fs/binfmt_aout.c 2007-07-10 14:56:30.000000000 -0400
12521+++ linux-2.6.22.1/fs/binfmt_aout.c 2007-08-02 11:38:47.000000000 -0400
12522@@ -25,6 +25,7 @@
12523 #include <linux/personality.h>
12524 #include <linux/init.h>
12525 #include <linux/vs_memory.h>
12526+#include <linux/grsecurity.h>
12527
12528 #include <asm/system.h>
12529 #include <asm/uaccess.h>
12530@@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
12531 /* If the size of the dump file exceeds the rlimit, then see what would happen
12532 if we wrote the stack, but not the data area. */
12533 #ifdef __sparc__
12534+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
12535 if ((dump.u_dsize+dump.u_ssize) >
12536 current->signal->rlim[RLIMIT_CORE].rlim_cur)
12537 dump.u_dsize = 0;
12538 #else
12539+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
12540 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
12541 current->signal->rlim[RLIMIT_CORE].rlim_cur)
12542 dump.u_dsize = 0;
12543@@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
12544
12545 /* Make sure we have enough room to write the stack and data areas. */
12546 #ifdef __sparc__
12547+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
12548 if ((dump.u_ssize) >
12549 current->signal->rlim[RLIMIT_CORE].rlim_cur)
12550 dump.u_ssize = 0;
12551 #else
12552+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
12553 if ((dump.u_ssize+1) * PAGE_SIZE >
12554 current->signal->rlim[RLIMIT_CORE].rlim_cur)
12555 dump.u_ssize = 0;
12556@@ -294,6 +299,8 @@ static int load_aout_binary(struct linux
12557 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
12558 if (rlim >= RLIM_INFINITY)
12559 rlim = ~0;
12560+
12561+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
12562 if (ex.a_data + ex.a_bss > rlim)
12563 return -ENOMEM;
12564
12565@@ -326,6 +333,28 @@ static int load_aout_binary(struct linux
12566 current->mm->mmap = NULL;
12567 compute_creds(bprm);
12568 current->flags &= ~PF_FORKNOEXEC;
12569+
12570+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
12571+ current->mm->pax_flags = 0UL;
12572+#endif
12573+
12574+#ifdef CONFIG_PAX_PAGEEXEC
12575+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
12576+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
12577+
12578+#ifdef CONFIG_PAX_EMUTRAMP
12579+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
12580+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
12581+#endif
12582+
12583+#ifdef CONFIG_PAX_MPROTECT
12584+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
12585+ current->mm->pax_flags |= MF_PAX_MPROTECT;
12586+#endif
12587+
12588+ }
12589+#endif
12590+
12591 #ifdef __sparc__
12592 if (N_MAGIC(ex) == NMAGIC) {
12593 loff_t pos = fd_offset;
12594@@ -421,7 +450,7 @@ static int load_aout_binary(struct linux
12595
12596 down_write(&current->mm->mmap_sem);
12597 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
12598- PROT_READ | PROT_WRITE | PROT_EXEC,
12599+ PROT_READ | PROT_WRITE,
12600 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
12601 fd_offset + ex.a_text);
12602 up_write(&current->mm->mmap_sem);
12603diff -urNp linux-2.6.22.1/fs/binfmt_elf.c linux-2.6.22.1/fs/binfmt_elf.c
12604--- linux-2.6.22.1/fs/binfmt_elf.c 2007-07-10 14:56:30.000000000 -0400
12605+++ linux-2.6.22.1/fs/binfmt_elf.c 2007-08-02 11:38:47.000000000 -0400
12606@@ -39,10 +39,21 @@
12607 #include <linux/elf.h>
12608 #include <linux/utsname.h>
12609 #include <linux/vs_memory.h>
12610+#include <linux/grsecurity.h>
12611+
12612 #include <asm/uaccess.h>
12613 #include <asm/param.h>
12614 #include <asm/page.h>
12615
12616+#ifdef CONFIG_PAX_SEGMEXEC
12617+#include <asm/desc.h>
12618+#endif
12619+
12620+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
12621+void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
12622+EXPORT_SYMBOL(pax_set_initial_flags_func);
12623+#endif
12624+
12625 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
12626 static int load_elf_library(struct file *);
12627 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
12628@@ -84,6 +90,8 @@ static struct linux_binfmt elf_format =
12629
12630 static int set_brk(unsigned long start, unsigned long end)
12631 {
12632+ unsigned long e = end;
12633+
12634 start = ELF_PAGEALIGN(start);
12635 end = ELF_PAGEALIGN(end);
12636 if (end > start) {
12637@@ -94,7 +102,7 @@ static int set_brk(unsigned long start,
12638 if (BAD_ADDR(addr))
12639 return addr;
12640 }
12641- current->mm->start_brk = current->mm->brk = end;
12642+ current->mm->start_brk = current->mm->brk = e;
12643 return 0;
12644 }
12645
12646@@ -315,10 +323,9 @@ static unsigned long load_elf_interp(str
12647 {
12648 struct elf_phdr *elf_phdata;
12649 struct elf_phdr *eppnt;
12650- unsigned long load_addr = 0;
12651- int load_addr_set = 0;
12652+ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
12653 unsigned long last_bss = 0, elf_bss = 0;
12654- unsigned long error = ~0UL;
12655+ unsigned long error = -EINVAL;
12656 int retval, i, size;
12657
12658 /* First of all, some simple consistency checks */
12659@@ -357,66 +364,86 @@ static unsigned long load_elf_interp(str
12660 goto out_close;
12661 }
12662
12663+#ifdef CONFIG_PAX_SEGMEXEC
12664+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
12665+ task_size = SEGMEXEC_TASK_SIZE;
12666+#endif
12667+
12668 eppnt = elf_phdata;
12669+ min_addr = task_size;
12670+ max_addr = 0;
12671+ error = -ENOMEM;
12672+
12673 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
12674- if (eppnt->p_type == PT_LOAD) {
12675- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
12676- int elf_prot = 0;
12677- unsigned long vaddr = 0;
12678- unsigned long k, map_addr;
12679-
12680- if (eppnt->p_flags & PF_R)
12681- elf_prot = PROT_READ;
12682- if (eppnt->p_flags & PF_W)
12683- elf_prot |= PROT_WRITE;
12684- if (eppnt->p_flags & PF_X)
12685- elf_prot |= PROT_EXEC;
12686- vaddr = eppnt->p_vaddr;
12687- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
12688- elf_type |= MAP_FIXED;
12689-
12690- map_addr = elf_map(interpreter, load_addr + vaddr,
12691- eppnt, elf_prot, elf_type);
12692- error = map_addr;
12693- if (BAD_ADDR(map_addr))
12694- goto out_close;
12695-
12696- if (!load_addr_set &&
12697- interp_elf_ex->e_type == ET_DYN) {
12698- load_addr = map_addr - ELF_PAGESTART(vaddr);
12699- load_addr_set = 1;
12700- }
12701+ if (eppnt->p_type != PT_LOAD)
12702+ continue;
12703
12704- /*
12705- * Check to see if the section's size will overflow the
12706- * allowed task size. Note that p_filesz must always be
12707- * <= p_memsize so it's only necessary to check p_memsz.
12708- */
12709- k = load_addr + eppnt->p_vaddr;
12710- if (BAD_ADDR(k) ||
12711- eppnt->p_filesz > eppnt->p_memsz ||
12712- eppnt->p_memsz > TASK_SIZE ||
12713- TASK_SIZE - eppnt->p_memsz < k) {
12714- error = -ENOMEM;
12715- goto out_close;
12716- }
12717+ /*
12718+ * Check to see if the section's size will overflow the
12719+ * allowed task size. Note that p_filesz must always be
12720+ * <= p_memsize so it is only necessary to check p_memsz.
12721+ */
12722+ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
12723+ goto out_close;
12724
12725- /*
12726- * Find the end of the file mapping for this phdr, and
12727- * keep track of the largest address we see for this.
12728- */
12729- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
12730- if (k > elf_bss)
12731- elf_bss = k;
12732+ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
12733+ min_addr = ELF_PAGESTART(eppnt->p_vaddr);
12734+ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
12735+ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
12736+ }
12737+ if (min_addr >= max_addr || max_addr > task_size)
12738+ goto out_close;
12739
12740- /*
12741- * Do the same thing for the memory mapping - between
12742- * elf_bss and last_bss is the bss section.
12743- */
12744- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
12745- if (k > last_bss)
12746- last_bss = k;
12747- }
12748+ if (interp_elf_ex->e_type == ET_DYN) {
12749+ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
12750+
12751+ if (load_addr >= task_size)
12752+ goto out_close;
12753+
12754+ load_addr -= min_addr;
12755+ }
12756+
12757+ eppnt = elf_phdata;
12758+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
12759+ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
12760+ int elf_prot = 0;
12761+ unsigned long vaddr = 0;
12762+ unsigned long k, map_addr;
12763+
12764+ if (eppnt->p_type != PT_LOAD)
12765+ continue;
12766+
12767+ if (eppnt->p_flags & PF_R)
12768+ elf_prot = PROT_READ;
12769+ if (eppnt->p_flags & PF_W)
12770+ elf_prot |= PROT_WRITE;
12771+ if (eppnt->p_flags & PF_X)
12772+ elf_prot |= PROT_EXEC;
12773+ vaddr = eppnt->p_vaddr;
12774+
12775+ map_addr = elf_map(interpreter, load_addr + vaddr,
12776+ eppnt, elf_prot, elf_type);
12777+ error = map_addr;
12778+ if (BAD_ADDR(map_addr))
12779+ goto out_close;
12780+
12781+ k = load_addr + eppnt->p_vaddr;
12782+
12783+ /*
12784+ * Find the end of the file mapping for this phdr, and
12785+ * keep track of the largest address we see for this.
12786+ */
12787+ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
12788+ if (k > elf_bss)
12789+ elf_bss = k;
12790+
12791+ /*
12792+ * Do the same thing for the memory mapping - between
12793+ * elf_bss and last_bss is the bss section.
12794+ */
12795+ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
12796+ if (k > last_bss)
12797+ last_bss = k;
12798 }
12799
12800 /*
12801@@ -444,6 +471,8 @@ static unsigned long load_elf_interp(str
12802
12803 *interp_load_addr = load_addr;
12804 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
12805+ if (BAD_ADDR(error))
12806+ error = -EFAULT;
12807
12808 out_close:
12809 kfree(elf_phdata);
12810@@ -454,7 +483,7 @@ out:
12811 static unsigned long load_aout_interp(struct exec *interp_ex,
12812 struct file *interpreter)
12813 {
12814- unsigned long text_data, elf_entry = ~0UL;
12815+ unsigned long text_data, elf_entry = -EINVAL;
12816 char __user * addr;
12817 loff_t offset;
12818
12819@@ -497,6 +526,177 @@ out:
12820 return elf_entry;
12821 }
12822
12823+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
12824+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
12825+{
12826+ unsigned long pax_flags = 0UL;
12827+
12828+#ifdef CONFIG_PAX_PAGEEXEC
12829+ if (elf_phdata->p_flags & PF_PAGEEXEC)
12830+ pax_flags |= MF_PAX_PAGEEXEC;
12831+#endif
12832+
12833+#ifdef CONFIG_PAX_SEGMEXEC
12834+ if (elf_phdata->p_flags & PF_SEGMEXEC)
12835+ pax_flags |= MF_PAX_SEGMEXEC;
12836+#endif
12837+
12838+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
12839+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12840+ if (nx_enabled)
12841+ pax_flags &= ~MF_PAX_SEGMEXEC;
12842+ else
12843+ pax_flags &= ~MF_PAX_PAGEEXEC;
12844+ }
12845+#endif
12846+
12847+#ifdef CONFIG_PAX_EMUTRAMP
12848+ if (elf_phdata->p_flags & PF_EMUTRAMP)
12849+ pax_flags |= MF_PAX_EMUTRAMP;
12850+#endif
12851+
12852+#ifdef CONFIG_PAX_MPROTECT
12853+ if (elf_phdata->p_flags & PF_MPROTECT)
12854+ pax_flags |= MF_PAX_MPROTECT;
12855+#endif
12856+
12857+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
12858+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
12859+ pax_flags |= MF_PAX_RANDMMAP;
12860+#endif
12861+
12862+ return pax_flags;
12863+}
12864+#endif
12865+
12866+#ifdef CONFIG_PAX_PT_PAX_FLAGS
12867+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
12868+{
12869+ unsigned long pax_flags = 0UL;
12870+
12871+#ifdef CONFIG_PAX_PAGEEXEC
12872+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
12873+ pax_flags |= MF_PAX_PAGEEXEC;
12874+#endif
12875+
12876+#ifdef CONFIG_PAX_SEGMEXEC
12877+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
12878+ pax_flags |= MF_PAX_SEGMEXEC;
12879+#endif
12880+
12881+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
12882+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12883+ if (nx_enabled)
12884+ pax_flags &= ~MF_PAX_SEGMEXEC;
12885+ else
12886+ pax_flags &= ~MF_PAX_PAGEEXEC;
12887+ }
12888+#endif
12889+
12890+#ifdef CONFIG_PAX_EMUTRAMP
12891+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
12892+ pax_flags |= MF_PAX_EMUTRAMP;
12893+#endif
12894+
12895+#ifdef CONFIG_PAX_MPROTECT
12896+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
12897+ pax_flags |= MF_PAX_MPROTECT;
12898+#endif
12899+
12900+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
12901+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
12902+ pax_flags |= MF_PAX_RANDMMAP;
12903+#endif
12904+
12905+ return pax_flags;
12906+}
12907+#endif
12908+
12909+#ifdef CONFIG_PAX_EI_PAX
12910+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
12911+{
12912+ unsigned long pax_flags = 0UL;
12913+
12914+#ifdef CONFIG_PAX_PAGEEXEC
12915+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
12916+ pax_flags |= MF_PAX_PAGEEXEC;
12917+#endif
12918+
12919+#ifdef CONFIG_PAX_SEGMEXEC
12920+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
12921+ pax_flags |= MF_PAX_SEGMEXEC;
12922+#endif
12923+
12924+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
12925+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12926+ if (nx_enabled)
12927+ pax_flags &= ~MF_PAX_SEGMEXEC;
12928+ else
12929+ pax_flags &= ~MF_PAX_PAGEEXEC;
12930+ }
12931+#endif
12932+
12933+#ifdef CONFIG_PAX_EMUTRAMP
12934+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
12935+ pax_flags |= MF_PAX_EMUTRAMP;
12936+#endif
12937+
12938+#ifdef CONFIG_PAX_MPROTECT
12939+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
12940+ pax_flags |= MF_PAX_MPROTECT;
12941+#endif
12942+
12943+#ifdef CONFIG_PAX_ASLR
12944+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
12945+ pax_flags |= MF_PAX_RANDMMAP;
12946+#endif
12947+
12948+ return pax_flags;
12949+}
12950+#endif
12951+
12952+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12953+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
12954+{
12955+ unsigned long pax_flags = 0UL;
12956+
12957+#ifdef CONFIG_PAX_PT_PAX_FLAGS
12958+ unsigned long i;
12959+#endif
12960+
12961+#ifdef CONFIG_PAX_EI_PAX
12962+ pax_flags = pax_parse_ei_pax(elf_ex);
12963+#endif
12964+
12965+#ifdef CONFIG_PAX_PT_PAX_FLAGS
12966+ for (i = 0UL; i < elf_ex->e_phnum; i++)
12967+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
12968+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
12969+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
12970+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
12971+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
12972+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
12973+ return -EINVAL;
12974+
12975+#ifdef CONFIG_PAX_SOFTMODE
12976+ if (pax_softmode)
12977+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
12978+ else
12979+#endif
12980+
12981+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
12982+ break;
12983+ }
12984+#endif
12985+
12986+ if (0 > pax_check_flags(&pax_flags))
12987+ return -EINVAL;
12988+
12989+ current->mm->pax_flags = pax_flags;
12990+ return 0;
12991+}
12992+#endif
12993+
12994 /*
12995 * These are the functions used to load ELF style executables and shared
12996 * libraries. There is no binary dependent code anywhere else.
12997@@ -534,7 +734,7 @@ static int load_elf_binary(struct linux_
12998 char * elf_interpreter = NULL;
12999 unsigned int interpreter_type = INTERPRETER_NONE;
13000 unsigned char ibcs2_interpreter = 0;
13001- unsigned long error;
13002+ unsigned long error = 0;
13003 struct elf_phdr *elf_ppnt, *elf_phdata;
13004 unsigned long elf_bss, elf_brk;
13005 int elf_exec_fileno;
13006@@ -546,12 +746,12 @@ static int load_elf_binary(struct linux_
13007 char passed_fileno[6];
13008 struct files_struct *files;
13009 int executable_stack = EXSTACK_DEFAULT;
13010- unsigned long def_flags = 0;
13011 struct {
13012 struct elfhdr elf_ex;
13013 struct elfhdr interp_elf_ex;
13014 struct exec interp_ex;
13015 } *loc;
13016+ unsigned long task_size = TASK_SIZE;
13017
13018 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
13019 if (!loc) {
13020@@ -782,14 +982,89 @@ static int load_elf_binary(struct linux_
13021 current->mm->end_code = 0;
13022 current->mm->mmap = NULL;
13023 current->flags &= ~PF_FORKNOEXEC;
13024- current->mm->def_flags = def_flags;
13025+
13026+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13027+ current->mm->pax_flags = 0UL;
13028+#endif
13029+
13030+#ifdef CONFIG_PAX_DLRESOLVE
13031+ current->mm->call_dl_resolve = 0UL;
13032+#endif
13033+
13034+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
13035+ current->mm->call_syscall = 0UL;
13036+#endif
13037+
13038+#ifdef CONFIG_PAX_ASLR
13039+ current->mm->delta_mmap = 0UL;
13040+ current->mm->delta_stack = 0UL;
13041+#endif
13042+
13043+ current->mm->def_flags = 0;
13044+
13045+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
13046+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
13047+ send_sig(SIGKILL, current, 0);
13048+ goto out_free_dentry;
13049+ }
13050+#endif
13051+
13052+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
13053+ pax_set_initial_flags(bprm);
13054+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
13055+ if (pax_set_initial_flags_func)
13056+ (pax_set_initial_flags_func)(bprm);
13057+#endif
13058+
13059+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
13060+ if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
13061+ current->mm->context.user_cs_limit = PAGE_SIZE;
13062+ current->mm->def_flags |= VM_PAGEEXEC;
13063+ }
13064+#endif
13065+
13066+#ifdef CONFIG_PAX_SEGMEXEC
13067+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
13068+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
13069+ current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
13070+ task_size = SEGMEXEC_TASK_SIZE;
13071+ }
13072+#endif
13073+
13074+#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
13075+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13076+ set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
13077+ put_cpu_no_resched();
13078+ }
13079+#endif
13080+
13081+#ifdef CONFIG_PAX_ASLR
13082+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
13083+ current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
13084+ current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
13085+ }
13086+#endif
13087+
13088+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13089+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
13090+ executable_stack = EXSTACK_DEFAULT;
13091+#endif
13092
13093 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
13094 may depend on the personality. */
13095 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
13096+
13097+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13098+ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
13099+#endif
13100+
13101 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
13102 current->personality |= READ_IMPLIES_EXEC;
13103
13104+#ifdef CONFIG_PAX_ASLR
13105+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
13106+#endif
13107+
13108 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
13109 current->flags |= PF_RANDOMIZE;
13110 arch_pick_mmap_layout(current->mm);
13111@@ -865,6 +1140,20 @@ static int load_elf_binary(struct linux_
13112 * might try to exec. This is because the brk will
13113 * follow the loader, and is not movable. */
13114 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
13115+
13116+#ifdef CONFIG_PAX_RANDMMAP
13117+ /* PaX: randomize base address at the default exe base if requested */
13118+ if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
13119+#ifdef CONFIG_SPARC64
13120+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
13121+#else
13122+ load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
13123+#endif
13124+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
13125+ elf_flags |= MAP_FIXED;
13126+ }
13127+#endif
13128+
13129 }
13130
13131 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
13132@@ -897,9 +1186,9 @@ static int load_elf_binary(struct linux_
13133 * allowed task size. Note that p_filesz must always be
13134 * <= p_memsz so it is only necessary to check p_memsz.
13135 */
13136- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
13137- elf_ppnt->p_memsz > TASK_SIZE ||
13138- TASK_SIZE - elf_ppnt->p_memsz < k) {
13139+ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
13140+ elf_ppnt->p_memsz > task_size ||
13141+ task_size - elf_ppnt->p_memsz < k) {
13142 /* set_brk can never work. Avoid overflows. */
13143 send_sig(SIGKILL, current, 0);
13144 retval = -EINVAL;
13145@@ -927,6 +1216,11 @@ static int load_elf_binary(struct linux_
13146 start_data += load_bias;
13147 end_data += load_bias;
13148
13149+#ifdef CONFIG_PAX_RANDMMAP
13150+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
13151+ elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
13152+#endif
13153+
13154 /* Calling set_brk effectively mmaps the pages that we need
13155 * for the bss and break sections. We must do this before
13156 * mapping in the interpreter, to make sure it doesn't wind
13157@@ -938,9 +1232,11 @@ static int load_elf_binary(struct linux_
13158 goto out_free_dentry;
13159 }
13160 if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
13161- send_sig(SIGSEGV, current, 0);
13162- retval = -EFAULT; /* Nobody gets to see this, but.. */
13163- goto out_free_dentry;
13164+ /*
13165+ * This bss-zeroing can fail if the ELF
13166+ * file specifies odd protections. So
13167+ * we don't check the return value
13168+ */
13169 }
13170
13171 if (elf_interpreter) {
13172@@ -1173,8 +1469,10 @@ static int dump_seek(struct file *file,
13173 unsigned long n = off;
13174 if (n > PAGE_SIZE)
13175 n = PAGE_SIZE;
13176- if (!dump_write(file, buf, n))
13177+ if (!dump_write(file, buf, n)) {
13178+ free_page((unsigned long)buf);
13179 return 0;
13180+ }
13181 off -= n;
13182 }
13183 free_page((unsigned long)buf);
13184@@ -1189,7 +1487,7 @@ static int dump_seek(struct file *file,
13185 *
13186 * I think we should skip something. But I am not sure how. H.J.
13187 */
13188-static int maydump(struct vm_area_struct *vma)
13189+static int maydump(struct vm_area_struct *vma, long signr)
13190 {
13191 /* The vma can be set up to tell us the answer directly. */
13192 if (vma->vm_flags & VM_ALWAYSDUMP)
13193@@ -1204,7 +1502,7 @@ static int maydump(struct vm_area_struct
13194 return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0;
13195
13196 /* If it hasn't been written to, don't write it out */
13197- if (!vma->anon_vma)
13198+ if (signr != SIGKILL && !vma->anon_vma)
13199 return 0;
13200
13201 return 1;
13202@@ -1261,8 +1559,11 @@ static int writenote(struct memelfnote *
13203 #undef DUMP_WRITE
13204
13205 #define DUMP_WRITE(addr, nr) \
13206+ do { \
13207+ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
13208 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
13209- goto end_coredump;
13210+ goto end_coredump; \
13211+ } while (0);
13212 #define DUMP_SEEK(off) \
13213 if (!dump_seek(file, (off))) \
13214 goto end_coredump;
13215@@ -1654,7 +1955,7 @@ static int elf_core_dump(long signr, str
13216 phdr.p_offset = offset;
13217 phdr.p_vaddr = vma->vm_start;
13218 phdr.p_paddr = 0;
13219- phdr.p_filesz = maydump(vma) ? sz : 0;
13220+ phdr.p_filesz = maydump(vma, signr) ? sz : 0;
13221 phdr.p_memsz = sz;
13222 offset += phdr.p_filesz;
13223 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
13224@@ -1698,7 +1999,7 @@ static int elf_core_dump(long signr, str
13225 vma = next_vma(vma, gate_vma)) {
13226 unsigned long addr;
13227
13228- if (!maydump(vma))
13229+ if (!maydump(vma, signr))
13230 continue;
13231
13232 for (addr = vma->vm_start;
13233@@ -1721,6 +2022,7 @@ static int elf_core_dump(long signr, str
13234 flush_cache_page(vma, addr,
13235 page_to_pfn(page));
13236 kaddr = kmap(page);
13237+ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
13238 if ((size += PAGE_SIZE) > limit ||
13239 !dump_write(file, kaddr,
13240 PAGE_SIZE)) {
13241diff -urNp linux-2.6.22.1/fs/binfmt_flat.c linux-2.6.22.1/fs/binfmt_flat.c
13242--- linux-2.6.22.1/fs/binfmt_flat.c 2007-07-10 14:56:30.000000000 -0400
13243+++ linux-2.6.22.1/fs/binfmt_flat.c 2007-08-02 11:38:47.000000000 -0400
13244@@ -559,7 +559,9 @@ static int load_flat_file(struct linux_b
13245 realdatastart = (unsigned long) -ENOMEM;
13246 printk("Unable to allocate RAM for process data, errno %d\n",
13247 (int)-realdatastart);
13248+ down_write(&current->mm->mmap_sem);
13249 do_munmap(current->mm, textpos, text_len);
13250+ up_write(&current->mm->mmap_sem);
13251 ret = realdatastart;
13252 goto err;
13253 }
13254@@ -581,8 +583,10 @@ static int load_flat_file(struct linux_b
13255 }
13256 if (result >= (unsigned long)-4096) {
13257 printk("Unable to read data+bss, errno %d\n", (int)-result);
13258+ down_write(&current->mm->mmap_sem);
13259 do_munmap(current->mm, textpos, text_len);
13260 do_munmap(current->mm, realdatastart, data_len + extra);
13261+ up_write(&current->mm->mmap_sem);
13262 ret = result;
13263 goto err;
13264 }
13265@@ -655,8 +659,10 @@ static int load_flat_file(struct linux_b
13266 }
13267 if (result >= (unsigned long)-4096) {
13268 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
13269+ down_write(&current->mm->mmap_sem);
13270 do_munmap(current->mm, textpos, text_len + data_len + extra +
13271 MAX_SHARED_LIBS * sizeof(unsigned long));
13272+ up_write(&current->mm->mmap_sem);
13273 ret = result;
13274 goto err;
13275 }
13276diff -urNp linux-2.6.22.1/fs/binfmt_misc.c linux-2.6.22.1/fs/binfmt_misc.c
13277--- linux-2.6.22.1/fs/binfmt_misc.c 2007-07-10 14:56:30.000000000 -0400
13278+++ linux-2.6.22.1/fs/binfmt_misc.c 2007-08-02 11:38:47.000000000 -0400
13279@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
13280 struct files_struct *files = NULL;
13281
13282 retval = -ENOEXEC;
13283- if (!enabled)
13284+ if (!enabled || bprm->misc)
13285 goto _ret;
13286
13287+ bprm->misc++;
13288+
13289 /* to keep locking time low, we copy the interpreter string */
13290 read_lock(&entries_lock);
13291 fmt = check_file(bprm);
13292@@ -718,7 +720,7 @@ static int bm_fill_super(struct super_bl
13293 static struct tree_descr bm_files[] = {
13294 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
13295 [3] = {"register", &bm_register_operations, S_IWUSR},
13296- /* last one */ {""}
13297+ /* last one */ {"", NULL, 0}
13298 };
13299 int err = simple_fill_super(sb, 0x42494e4d, bm_files);
13300 if (!err)
13301diff -urNp linux-2.6.22.1/fs/block_dev.c linux-2.6.22.1/fs/block_dev.c
13302--- linux-2.6.22.1/fs/block_dev.c 2007-07-10 14:56:30.000000000 -0400
13303+++ linux-2.6.22.1/fs/block_dev.c 2007-08-02 11:38:47.000000000 -0400
13304@@ -949,7 +949,7 @@ static int bd_claim_by_kobject(struct bl
13305 struct kobject *kobj)
13306 {
13307 int res;
13308- struct bd_holder *bo, *found;
13309+ struct bd_holder *bo, *found = NULL;
13310
13311 if (!kobj)
13312 return -EINVAL;
13313diff -urNp linux-2.6.22.1/fs/buffer.c linux-2.6.22.1/fs/buffer.c
13314--- linux-2.6.22.1/fs/buffer.c 2007-07-10 14:56:30.000000000 -0400
13315+++ linux-2.6.22.1/fs/buffer.c 2007-08-02 11:09:15.000000000 -0400
13316@@ -41,6 +41,7 @@
13317 #include <linux/bitops.h>
13318 #include <linux/mpage.h>
13319 #include <linux/bit_spinlock.h>
13320+#include <linux/grsecurity.h>
13321
13322 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
13323
13324@@ -2002,6 +2003,7 @@ static int __generic_cont_expand(struct
13325
13326 err = -EFBIG;
13327 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
13328+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
13329 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
13330 send_sig(SIGXFSZ, current, 0);
13331 goto out;
13332diff -urNp linux-2.6.22.1/fs/cifs/cifs_uniupr.h linux-2.6.22.1/fs/cifs/cifs_uniupr.h
13333--- linux-2.6.22.1/fs/cifs/cifs_uniupr.h 2007-07-10 14:56:30.000000000 -0400
13334+++ linux-2.6.22.1/fs/cifs/cifs_uniupr.h 2007-08-02 11:38:47.000000000 -0400
13335@@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
13336 {0x0490, 0x04cc, UniCaseRangeU0490},
13337 {0x1e00, 0x1ffc, UniCaseRangeU1e00},
13338 {0xff40, 0xff5a, UniCaseRangeUff40},
13339- {0}
13340+ {0, 0, NULL}
13341 };
13342 #endif
13343
13344diff -urNp linux-2.6.22.1/fs/cifs/dir.c linux-2.6.22.1/fs/cifs/dir.c
13345--- linux-2.6.22.1/fs/cifs/dir.c 2007-07-10 14:56:30.000000000 -0400
13346+++ linux-2.6.22.1/fs/cifs/dir.c 2007-08-02 11:38:47.000000000 -0400
13347@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, stru
13348 /* BB Do not bother to decode buf since no
13349 local inode yet to put timestamps in,
13350 but we can reuse it safely */
13351- int bytes_written;
13352+ unsigned int bytes_written;
13353 struct win_dev *pdev;
13354 pdev = (struct win_dev *)buf;
13355 if (S_ISCHR(mode)) {
13356diff -urNp linux-2.6.22.1/fs/cifs/inode.c linux-2.6.22.1/fs/cifs/inode.c
13357--- linux-2.6.22.1/fs/cifs/inode.c 2007-07-10 14:56:30.000000000 -0400
13358+++ linux-2.6.22.1/fs/cifs/inode.c 2007-08-02 11:38:47.000000000 -0400
13359@@ -1461,7 +1461,7 @@ int cifs_setattr(struct dentry *direntry
13360 atomic_dec(&open_file->wrtPending);
13361 cFYI(1,("SetFSize for attrs rc = %d", rc));
13362 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
13363- int bytes_written;
13364+ unsigned int bytes_written;
13365 rc = CIFSSMBWrite(xid, pTcon,
13366 nfid, 0, attrs->ia_size,
13367 &bytes_written, NULL, NULL,
13368@@ -1494,7 +1494,7 @@ int cifs_setattr(struct dentry *direntry
13369 cifs_sb->mnt_cifs_flags &
13370 CIFS_MOUNT_MAP_SPECIAL_CHR);
13371 if (rc==0) {
13372- int bytes_written;
13373+ unsigned int bytes_written;
13374 rc = CIFSSMBWrite(xid, pTcon,
13375 netfid, 0,
13376 attrs->ia_size,
13377diff -urNp linux-2.6.22.1/fs/compat.c linux-2.6.22.1/fs/compat.c
13378--- linux-2.6.22.1/fs/compat.c 2007-07-10 14:56:30.000000000 -0400
13379+++ linux-2.6.22.1/fs/compat.c 2007-08-02 11:09:15.000000000 -0400
13380@@ -50,6 +50,7 @@
13381 #include <linux/poll.h>
13382 #include <linux/mm.h>
13383 #include <linux/eventpoll.h>
13384+#include <linux/grsecurity.h>
13385
13386 #include <asm/uaccess.h>
13387 #include <asm/mmu_context.h>
13388@@ -1364,6 +1365,11 @@ int compat_do_execve(char * filename,
13389 struct file *file;
13390 int retval;
13391 int i;
13392+#ifdef CONFIG_GRKERNSEC
13393+ struct file *old_exec_file;
13394+ struct acl_subject_label *old_acl;
13395+ struct rlimit old_rlim[RLIM_NLIMITS];
13396+#endif
13397
13398 retval = -ENOMEM;
13399 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
13400@@ -1381,6 +1387,15 @@ int compat_do_execve(char * filename,
13401 bprm->file = file;
13402 bprm->filename = filename;
13403 bprm->interp = filename;
13404+
13405+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
13406+ retval = -EAGAIN;
13407+ if (gr_handle_nproc())
13408+ goto out_file;
13409+ retval = -EACCES;
13410+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
13411+ goto out_file;
13412+
13413 bprm->mm = mm_alloc();
13414 retval = -ENOMEM;
13415 if (!bprm->mm)
13416@@ -1419,10 +1434,39 @@ int compat_do_execve(char * filename,
13417 if (retval < 0)
13418 goto out;
13419
13420+ if (!gr_tpe_allow(file)) {
13421+ retval = -EACCES;
13422+ goto out;
13423+ }
13424+
13425+ if (gr_check_crash_exec(file)) {
13426+ retval = -EACCES;
13427+ goto out;
13428+ }
13429+
13430+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
13431+
13432+ gr_handle_exec_args(bprm, (char __user * __user *)argv);
13433+
13434+#ifdef CONFIG_GRKERNSEC
13435+ old_acl = current->acl;
13436+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
13437+ old_exec_file = current->exec_file;
13438+ get_file(file);
13439+ current->exec_file = file;
13440+#endif
13441+
13442+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
13443+
13444 retval = search_binary_handler(bprm, regs);
13445 if (retval >= 0) {
13446 free_arg_pages(bprm);
13447
13448+#ifdef CONFIG_GRKERNSEC
13449+ if (old_exec_file)
13450+ fput(old_exec_file);
13451+#endif
13452+
13453 /* execve success */
13454 security_bprm_free(bprm);
13455 acct_update_integrals(current);
13456@@ -1430,6 +1474,13 @@ int compat_do_execve(char * filename,
13457 return retval;
13458 }
13459
13460+#ifdef CONFIG_GRKERNSEC
13461+ current->acl = old_acl;
13462+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
13463+ fput(current->exec_file);
13464+ current->exec_file = old_exec_file;
13465+#endif
13466+
13467 out:
13468 /* Something went wrong, return the inode and free the argument pages*/
13469 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
13470diff -urNp linux-2.6.22.1/fs/debugfs/inode.c linux-2.6.22.1/fs/debugfs/inode.c
13471--- linux-2.6.22.1/fs/debugfs/inode.c 2007-07-10 14:56:30.000000000 -0400
13472+++ linux-2.6.22.1/fs/debugfs/inode.c 2007-08-02 11:38:47.000000000 -0400
13473@@ -125,7 +125,7 @@ static inline int debugfs_positive(struc
13474
13475 static int debug_fill_super(struct super_block *sb, void *data, int silent)
13476 {
13477- static struct tree_descr debug_files[] = {{""}};
13478+ static struct tree_descr debug_files[] = {{"", NULL, 0}};
13479
13480 return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
13481 }
13482diff -urNp linux-2.6.22.1/fs/exec.c linux-2.6.22.1/fs/exec.c
13483--- linux-2.6.22.1/fs/exec.c 2007-07-10 14:56:30.000000000 -0400
13484+++ linux-2.6.22.1/fs/exec.c 2007-08-02 11:44:13.000000000 -0400
13485@@ -52,6 +52,8 @@
13486 #include <linux/audit.h>
13487 #include <linux/signalfd.h>
13488 #include <linux/vs_memory.h>
13489+#include <linux/random.h>
13490+#include <linux/grsecurity.h>
13491
13492 #include <asm/uaccess.h>
13493 #include <asm/mmu_context.h>
13494@@ -309,7 +320,7 @@ EXPORT_SYMBOL(copy_strings_kernel);
13495 *
13496 * vma->vm_mm->mmap_sem is held for writing.
13497 */
13498-void install_arg_page(struct vm_area_struct *vma,
13499+int install_arg_page(struct vm_area_struct *vma,
13500 struct page *page, unsigned long address)
13501 {
13502 struct mm_struct *mm = vma->vm_mm;
13503@@ -327,6 +338,12 @@ void install_arg_page(struct vm_area_str
13504 pte_unmap_unlock(pte, ptl);
13505 goto out;
13506 }
13507+
13508+#ifdef CONFIG_PAX_SEGMEXEC
13509+ if (pax_find_mirror_vma(vma))
13510+ BUG_ON(TestSetPageLocked(page));
13511+#endif
13512+
13513 inc_mm_counter(mm, anon_rss);
13514 lru_cache_add_active(page);
13515 set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
13516@@ -335,10 +352,42 @@ void install_arg_page(struct vm_area_str
13517 pte_unmap_unlock(pte, ptl);
13518
13519 /* no need for flush_tlb */
13520- return;
13521+ return 0;
13522 out:
13523 __free_page(page);
13524 force_sig(SIGKILL, current);
13525+ return -ENOMEM;
13526+}
13527+
13528+static int install_arg_page_mirror(struct vm_area_struct *vma,
13529+ struct page *page, unsigned long address)
13530+{
13531+ struct mm_struct *mm = vma->vm_mm;
13532+ pte_t *pte;
13533+ spinlock_t *ptl;
13534+
13535+ page_cache_get(page);
13536+ pte = get_locked_pte(mm, address, &ptl);
13537+ if (!pte)
13538+ goto out;
13539+ if (!pte_none(*pte)) {
13540+ pte_unmap_unlock(pte, ptl);
13541+ goto out;
13542+ }
13543+ inc_mm_counter(mm, anon_rss);
13544+ set_pte_at(mm, address, pte, mk_pte(page, vma->vm_page_prot));
13545+ page_add_anon_rmap(page, vma, address);
13546+ pte_unmap_unlock(pte, ptl);
13547+
13548+ /* no need for flush_tlb */
13549+ unlock_page(page);
13550+ return 0;
13551+out:
13552+ unlock_page(page);
13553+ page_cache_release(page);
13554+ __free_page(page);
13555+ force_sig(SIGKILL, current);
13556+ return -ENOMEM;
13557 }
13558
13559 #define EXTRA_STACK_VM_PAGES 20 /* random */
13560@@ -353,6 +402,10 @@ int setup_arg_pages(struct linux_binprm
13561 int i, ret;
13562 long arg_size;
13563
13564+#ifdef CONFIG_PAX_SEGMEXEC
13565+ struct vm_area_struct *mpnt_m = NULL;
13566+#endif
13567+
13568 #ifdef CONFIG_STACK_GROWSUP
13569 /* Move the argument and environment strings to the bottom of the
13570 * stack space.
13571@@ -434,7 +478,20 @@ int setup_arg_pages(struct linux_binprm
13572 else
13573 mpnt->vm_flags = VM_STACK_FLAGS;
13574 mpnt->vm_flags |= mm->def_flags;
13575- mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
13576+
13577+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13578+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
13579+ mpnt->vm_flags &= ~VM_EXEC;
13580+
13581+#ifdef CONFIG_PAX_MPROTECT
13582+ if (mm->pax_flags & MF_PAX_MPROTECT)
13583+ mpnt->vm_flags &= ~VM_MAYEXEC;
13584+#endif
13585+
13586+ }
13587+#endif
13588+
13589+ mpnt->vm_page_prot = vm_get_page_prot(mpnt->vm_flags);
13590 if ((ret = insert_vm_struct(mm, mpnt))) {
13591 up_write(&mm->mmap_sem);
13592 kmem_cache_free(vm_area_cachep, mpnt);
13593@@ -444,17 +498,30 @@ int setup_arg_pages(struct linux_binprm
13594 mm->stack_vm = mm->total_vm;
13595 }
13596
13597- for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
13598+ for (i = 0 ; i < MAX_ARG_PAGES ; i++, stack_base += PAGE_SIZE) {
13599 struct page *page = bprm->page[i];
13600- if (page) {
13601- bprm->page[i] = NULL;
13602- install_arg_page(mpnt, page, stack_base);
13603- }
13604- stack_base += PAGE_SIZE;
13605+ int retval;
13606+ if (!page)
13607+ continue;
13608+
13609+ bprm->page[i] = NULL;
13610+ retval = install_arg_page(mpnt, page, stack_base);
13611+ if (!ret)
13612+ ret = retval;
13613+
13614+#ifdef CONFIG_PAX_SEGMEXEC
13615+ if (!mpnt_m || retval)
13616+ continue;
13617+
13618+ retval = install_arg_page_mirror(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
13619+ if (!ret)
13620+ ret = retval;
13621+#endif
13622+
13623 }
13624 up_write(&mm->mmap_sem);
13625-
13626- return 0;
13627+
13628+ return ret;
13629 }
13630
13631 EXPORT_SYMBOL(setup_arg_pages);
13632@@ -491,7 +565,7 @@ struct file *open_exec(const char *name)
13633 file = ERR_PTR(-EACCES);
13634 if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
13635 S_ISREG(inode->i_mode)) {
13636- int err = vfs_permission(&nd, MAY_EXEC);
13637+ err = vfs_permission(&nd, MAY_EXEC);
13638 file = ERR_PTR(err);
13639 if (!err) {
13640 file = nameidata_to_filp(&nd, O_RDONLY);
13641@@ -1158,6 +1232,11 @@ int do_execve(char * filename,
13642 struct file *file;
13643 int retval;
13644 int i;
13645+#ifdef CONFIG_GRKERNSEC
13646+ struct file *old_exec_file;
13647+ struct acl_subject_label *old_acl;
13648+ struct rlimit old_rlim[RLIM_NLIMITS];
13649+#endif
13650
13651 retval = -ENOMEM;
13652 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
13653@@ -1169,10 +1248,29 @@ int do_execve(char * filename,
13654 if (IS_ERR(file))
13655 goto out_kfree;
13656
13657+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
13658+
13659+ if (gr_handle_nproc()) {
13660+ allow_write_access(file);
13661+ fput(file);
13662+ return -EAGAIN;
13663+ }
13664+
13665+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
13666+ allow_write_access(file);
13667+ fput(file);
13668+ return -EACCES;
13669+ }
13670+
13671 sched_exec();
13672
13673 bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
13674
13675+#ifdef CONFIG_PAX_RANDUSTACK
13676+ if (randomize_va_space)
13677+ bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
13678+#endif
13679+
13680 bprm->file = file;
13681 bprm->filename = filename;
13682 bprm->interp = filename;
13683@@ -1214,8 +1312,38 @@ int do_execve(char * filename,
13684 if (retval < 0)
13685 goto out;
13686
13687+ if (!gr_tpe_allow(file)) {
13688+ retval = -EACCES;
13689+ goto out;
13690+ }
13691+
13692+ if (gr_check_crash_exec(file)) {
13693+ retval = -EACCES;
13694+ goto out;
13695+ }
13696+
13697+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
13698+
13699+ gr_handle_exec_args(bprm, argv);
13700+
13701+#ifdef CONFIG_GRKERNSEC
13702+ old_acl = current->acl;
13703+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
13704+ old_exec_file = current->exec_file;
13705+ get_file(file);
13706+ current->exec_file = file;
13707+#endif
13708+
13709+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
13710+ if (retval < 0)
13711+ goto out_fail;
13712+
13713 retval = search_binary_handler(bprm,regs);
13714 if (retval >= 0) {
13715+#ifdef CONFIG_GRKERNSEC
13716+ if (old_exec_file)
13717+ fput(old_exec_file);
13718+#endif
13719 free_arg_pages(bprm);
13720
13721 /* execve success */
13722@@ -1225,6 +1353,14 @@ int do_execve(char * filename,
13723 return retval;
13724 }
13725
13726+out_fail:
13727+#ifdef CONFIG_GRKERNSEC
13728+ current->acl = old_acl;
13729+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
13730+ fput(current->exec_file);
13731+ current->exec_file = old_exec_file;
13732+#endif
13733+
13734 out:
13735 /* Something went wrong, return the inode and free the argument pages*/
13736 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
13737@@ -1388,6 +1524,114 @@ out:
13738 return ispipe;
13739 }
13740
13741+int pax_check_flags(unsigned long *flags)
13742+{
13743+ int retval = 0;
13744+
13745+#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
13746+ if (*flags & MF_PAX_SEGMEXEC)
13747+ {
13748+ *flags &= ~MF_PAX_SEGMEXEC;
13749+ retval = -EINVAL;
13750+ }
13751+#endif
13752+
13753+ if ((*flags & MF_PAX_PAGEEXEC)
13754+
13755+#ifdef CONFIG_PAX_PAGEEXEC
13756+ && (*flags & MF_PAX_SEGMEXEC)
13757+#endif
13758+
13759+ )
13760+ {
13761+ *flags &= ~MF_PAX_PAGEEXEC;
13762+ retval = -EINVAL;
13763+ }
13764+
13765+ if ((*flags & MF_PAX_MPROTECT)
13766+
13767+#ifdef CONFIG_PAX_MPROTECT
13768+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
13769+#endif
13770+
13771+ )
13772+ {
13773+ *flags &= ~MF_PAX_MPROTECT;
13774+ retval = -EINVAL;
13775+ }
13776+
13777+ if ((*flags & MF_PAX_EMUTRAMP)
13778+
13779+#ifdef CONFIG_PAX_EMUTRAMP
13780+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
13781+#endif
13782+
13783+ )
13784+ {
13785+ *flags &= ~MF_PAX_EMUTRAMP;
13786+ retval = -EINVAL;
13787+ }
13788+
13789+ return retval;
13790+}
13791+
13792+EXPORT_SYMBOL(pax_check_flags);
13793+
13794+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
13795+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
13796+{
13797+ struct task_struct *tsk = current;
13798+ struct mm_struct *mm = current->mm;
13799+ char *buffer_exec = (char *)__get_free_page(GFP_ATOMIC);
13800+ char *buffer_fault = (char *)__get_free_page(GFP_ATOMIC);
13801+ char *path_exec = NULL;
13802+ char *path_fault = NULL;
13803+ unsigned long start = 0UL, end = 0UL, offset = 0UL;
13804+
13805+ if (buffer_exec && buffer_fault) {
13806+ struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
13807+
13808+ down_read(&mm->mmap_sem);
13809+ vma = mm->mmap;
13810+ while (vma && (!vma_exec || !vma_fault)) {
13811+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
13812+ vma_exec = vma;
13813+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
13814+ vma_fault = vma;
13815+ vma = vma->vm_next;
13816+ }
13817+ if (vma_exec) {
13818+ path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
13819+ if (IS_ERR(path_exec))
13820+ path_exec = "<path too long>";
13821+ }
13822+ if (vma_fault) {
13823+ start = vma_fault->vm_start;
13824+ end = vma_fault->vm_end;
13825+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
13826+ if (vma_fault->vm_file) {
13827+ path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
13828+ if (IS_ERR(path_fault))
13829+ path_fault = "<path too long>";
13830+ } else
13831+ path_fault = "<anonymous mapping>";
13832+ }
13833+ up_read(&mm->mmap_sem);
13834+ }
13835+ if (tsk->signal->curr_ip)
13836+ 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);
13837+ else
13838+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
13839+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
13840+ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
13841+ tsk->uid, tsk->euid, pc, sp);
13842+ free_page((unsigned long)buffer_exec);
13843+ free_page((unsigned long)buffer_fault);
13844+ pax_report_insns(pc, sp);
13845+ do_coredump(SIGKILL, SIGKILL, regs);
13846+}
13847+#endif
13848+
13849 static void zap_process(struct task_struct *start)
13850 {
13851 struct task_struct *t;
13852@@ -1530,6 +1774,10 @@ int do_coredump(long signr, int exit_cod
13853 */
13854 clear_thread_flag(TIF_SIGPENDING);
13855
13856+ if (signr == SIGKILL || signr == SIGILL)
13857+ gr_handle_brute_attach(current);
13858+
13859+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
13860 if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
13861 goto fail_unlock;
13862
13863diff -urNp linux-2.6.22.1/fs/ext2/balloc.c linux-2.6.22.1/fs/ext2/balloc.c
13864--- linux-2.6.22.1/fs/ext2/balloc.c 2007-07-10 14:56:30.000000000 -0400
13865+++ linux-2.6.22.1/fs/ext2/balloc.c 2007-08-02 11:09:15.000000000 -0400
13866@@ -114,7 +114,7 @@ static int reserve_blocks(struct super_b
13867 if (free_blocks < count)
13868 count = free_blocks;
13869
13870- if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
13871+ if (free_blocks < root_blocks + count && !capable_nolog(CAP_SYS_RESOURCE) &&
13872 sbi->s_resuid != current->fsuid &&
13873 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
13874 /*
13875diff -urNp linux-2.6.22.1/fs/ext3/xattr.c linux-2.6.22.1/fs/ext3/xattr.c
3ba9fddb 13876diff -urNp linux-2.6.22.1/fs/fcntl.c linux-2.6.22.1/fs/fcntl.c
13877--- linux-2.6.22.1/fs/fcntl.c 2007-07-10 14:56:30.000000000 -0400
13878+++ linux-2.6.22.1/fs/fcntl.c 2007-08-02 11:09:15.000000000 -0400
13879@@ -18,6 +18,7 @@
13880 #include <linux/signal.h>
13881 #include <linux/rcupdate.h>
13882 #include <linux/vs_limit.h>
13883+#include <linux/grsecurity.h>
13884
13885 #include <asm/poll.h>
13886 #include <asm/siginfo.h>
13887@@ -64,6 +65,7 @@ static int locate_fd(struct files_struct
13888 struct fdtable *fdt;
13889
13890 error = -EINVAL;
13891+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
13892 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13893 goto out;
13894
13895@@ -82,6 +84,7 @@ repeat:
13896 fdt->max_fds, start);
13897
13898 error = -EMFILE;
13899+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
13900 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13901 goto out;
13902 if (!vx_files_avail(1))
13903@@ -140,6 +143,8 @@ asmlinkage long sys_dup2(unsigned int ol
13904 struct files_struct * files = current->files;
13905 struct fdtable *fdt;
13906
13907+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
13908+
13909 spin_lock(&files->file_lock);
13910 if (!(file = fcheck(oldfd)))
13911 goto out_unlock;
13912@@ -458,7 +463,8 @@ static inline int sigio_perm(struct task
13913 return (((fown->euid == 0) ||
13914 (fown->euid == p->suid) || (fown->euid == p->uid) ||
13915 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
13916- !security_file_send_sigiotask(p, fown, sig));
13917+ !security_file_send_sigiotask(p, fown, sig) &&
13918+ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
13919 }
13920
13921 static void send_sigio_to_task(struct task_struct *p,
13922diff -urNp linux-2.6.22.1/fs/fuse/control.c linux-2.6.22.1/fs/fuse/control.c
13923--- linux-2.6.22.1/fs/fuse/control.c 2007-07-10 14:56:30.000000000 -0400
13924+++ linux-2.6.22.1/fs/fuse/control.c 2007-08-02 11:38:47.000000000 -0400
13925@@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
13926
13927 static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
13928 {
13929- struct tree_descr empty_descr = {""};
13930+ struct tree_descr empty_descr = {"", NULL, 0};
13931 struct fuse_conn *fc;
13932 int err;
13933
13934diff -urNp linux-2.6.22.1/fs/Kconfig linux-2.6.22.1/fs/Kconfig
13935--- linux-2.6.22.1/fs/Kconfig 2007-07-10 14:56:30.000000000 -0400
13936+++ linux-2.6.22.1/fs/Kconfig 2007-08-02 11:09:15.000000000 -0400
13937@@ -912,7 +912,7 @@ config PROC_FS
13938
13939 config PROC_KCORE
13940 bool "/proc/kcore support" if !ARM
13941- depends on PROC_FS && MMU
13942+ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
13943
13944 config PROC_VMCORE
13945 bool "/proc/vmcore support (EXPERIMENTAL)"
13946diff -urNp linux-2.6.22.1/fs/namei.c linux-2.6.22.1/fs/namei.c
13947--- linux-2.6.22.1/fs/namei.c 2007-07-10 14:56:30.000000000 -0400
13948+++ linux-2.6.22.1/fs/namei.c 2007-08-02 11:09:15.000000000 -0400
13949@@ -31,6 +31,7 @@
3ba9fddb 13950 #include <linux/vs_cowbl.h>
2b7bcf89 13951 #include <linux/vs_device.h
13952 #include <linux/vs_context.h>
3ba9fddb 13953+#include <linux/grsecurity.h>
13954 #include <asm/namei.h>
13955 #include <asm/uaccess.h>
13956
13957@@ -636,6 +637,13 @@ static inline int do_follow_link(struct
13958 err = security_inode_follow_link(path->dentry, nd);
13959 if (err)
13960 goto loop;
13961+
13962+ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
13963+ path->dentry->d_inode, path->dentry, nd->mnt)) {
13964+ err = -EACCES;
13965+ goto loop;
13966+ }
13967+
13968 current->link_count++;
13969 current->total_link_count++;
13970 nd->depth++;
13971@@ -981,11 +989,18 @@ return_reval:
13972 break;
13973 }
13974 return_base:
13975+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
13976+ path_release(nd);
13977+ return -ENOENT;
13978+ }
13979 return 0;
13980 out_dput:
13981 dput_path(&next, nd);
13982 break;
13983 }
13984+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
13985+ err = -ENOENT;
13986+
13987 path_release(nd);
13988 return_err:
13989 return err;
13990@@ -1616,9 +1631,17 @@ static int open_namei_create(struct name
13991 int error;
13992 struct dentry *dir = nd->dentry;
13993
13994+ if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
13995+ error = -EACCES;
13996+ goto out_unlock_dput;
13997+ }
13998+
13999 if (!IS_POSIXACL(dir->d_inode))
14000 mode &= ~current->fs->umask;
14001 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
14002+ if (!error)
14003+ gr_handle_create(path->dentry, nd->mnt);
14004+out_unlock_dput:
14005 mutex_unlock(&dir->d_inode->i_mutex);
14006 dput(nd->dentry);
14007 nd->dentry = path->dentry;
14008@@ -1669,6 +1692,17 @@ int open_namei(int dfd, const char *path
14009 nd, flag);
14010 if (error)
14011 return error;
14012+
14013+ if (gr_handle_rawio(nd->dentry->d_inode)) {
14014+ error = -EPERM;
14015+ goto exit;
14016+ }
14017+
14018+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
14019+ error = -EACCES;
14020+ goto exit;
14021+ }
14022+
14023 goto ok;
14024 }
14025
14026@@ -1718,6 +1752,23 @@ do_last:
14027 /*
14028 * It already exists.
14029 */
14030+
14031+ if (gr_handle_rawio(path.dentry->d_inode)) {
14032+ mutex_unlock(&dir->d_inode->i_mutex);
14033+ error = -EPERM;
14034+ goto exit_dput;
14035+ }
14036+ if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
14037+ mutex_unlock(&dir->d_inode->i_mutex);
14038+ error = -EACCES;
14039+ goto exit_dput;
14040+ }
14041+ if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
14042+ mutex_unlock(&dir->d_inode->i_mutex);
14043+ error = -EACCES;
14044+ goto exit_dput;
14045+ }
14046+
14047 mutex_unlock(&dir->d_inode->i_mutex);
14048 audit_inode(pathname, path.dentry->d_inode);
14049
14050@@ -1773,6 +1824,13 @@ do_link:
14051 error = security_inode_follow_link(path.dentry, nd);
14052 if (error)
14053 goto exit_dput;
14054+
14055+ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
14056+ path.dentry, nd->mnt)) {
14057+ error = -EACCES;
14058+ goto exit_dput;
14059+ }
14060+
14061 error = __do_follow_link(&path, nd);
14062 if (error) {
14063 /* Does someone understand code flow here? Or it is only
14064@@ -1901,6 +1959,22 @@ asmlinkage long sys_mknodat(int dfd, con
14065 if (!IS_POSIXACL(nd.dentry->d_inode))
14066 mode &= ~current->fs->umask;
14067 if (!IS_ERR(dentry)) {
14068+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
14069+ error = -EPERM;
14070+ dput(dentry);
14071+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
14072+ path_release(&nd);
14073+ goto out;
14074+ }
14075+
14076+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
14077+ error = -EACCES;
14078+ dput(dentry);
14079+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
14080+ path_release(&nd);
14081+ goto out;
14082+ }
14083+
14084 switch (mode & S_IFMT) {
14085 case 0: case S_IFREG:
14086 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
14087@@ -1918,6 +1992,10 @@ asmlinkage long sys_mknodat(int dfd, con
14088 default:
14089 error = -EINVAL;
14090 }
14091+
14092+ if (!error)
14093+ gr_handle_create(dentry, nd.mnt);
14094+
14095 dput(dentry);
14096 }
14097 mutex_unlock(&nd.dentry->d_inode->i_mutex);
14098@@ -1975,9 +2053,18 @@ asmlinkage long sys_mkdirat(int dfd, con
14099 if (IS_ERR(dentry))
14100 goto out_unlock;
14101
14102+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
14103+ error = -EACCES;
14104+ goto out_unlock_dput;
14105+ }
14106+
14107 if (!IS_POSIXACL(nd.dentry->d_inode))
14108 mode &= ~current->fs->umask;
14109 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
14110+
14111+ if (!error)
14112+ gr_handle_create(dentry, nd.mnt);
14113+out_unlock_dput:
14114 dput(dentry);
14115 out_unlock:
14116 mutex_unlock(&nd.dentry->d_inode->i_mutex);
14117@@ -2059,6 +2146,8 @@ static long do_rmdir(int dfd, const char
14118 char * name;
14119 struct dentry *dentry;
14120 struct nameidata nd;
14121+ ino_t saved_ino = 0;
14122+ dev_t saved_dev = 0;
14123
14124 name = getname(pathname);
14125 if(IS_ERR(name))
14126@@ -2084,7 +2173,22 @@ static long do_rmdir(int dfd, const char
14127 error = PTR_ERR(dentry);
14128 if (IS_ERR(dentry))
14129 goto exit2;
14130+
14131+ if (dentry->d_inode != NULL) {
14132+ if (dentry->d_inode->i_nlink <= 1) {
14133+ saved_ino = dentry->d_inode->i_ino;
14134+ saved_dev = dentry->d_inode->i_sb->s_dev;
14135+ }
14136+
14137+ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
14138+ error = -EACCES;
14139+ goto dput_exit2;
14140+ }
14141+ }
14142 error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
14143+ if (!error && (saved_dev || saved_ino))
14144+ gr_handle_delete(saved_ino, saved_dev);
14145+dput_exit2:
14146 dput(dentry);
14147 exit2:
14148 mutex_unlock(&nd.dentry->d_inode->i_mutex);
14149@@ -2143,6 +2247,8 @@ static long do_unlinkat(int dfd, const c
14150 struct dentry *dentry;
14151 struct nameidata nd;
14152 struct inode *inode = NULL;
14153+ ino_t saved_ino = 0;
14154+ dev_t saved_dev = 0;
14155
14156 name = getname(pathname);
14157 if(IS_ERR(name))
14158@@ -2158,13 +2264,26 @@ static long do_unlinkat(int dfd, const c
14159 dentry = lookup_hash(&nd);
14160 error = PTR_ERR(dentry);
14161 if (!IS_ERR(dentry)) {
14162+ error = 0;
14163 /* Why not before? Because we want correct error value */
14164 if (nd.last.name[nd.last.len])
14165 goto slashes;
14166 inode = dentry->d_inode;
14167- if (inode)
14168+ if (inode) {
14169+ if (inode->i_nlink <= 1) {
14170+ saved_ino = inode->i_ino;
14171+ saved_dev = inode->i_sb->s_dev;
14172+ }
14173+
14174+ if (!gr_acl_handle_unlink(dentry, nd.mnt))
14175+ error = -EACCES;
14176+
14177 atomic_inc(&inode->i_count);
14178- error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
14179+ }
14180+ if (!error)
14181+ error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
14182+ if (!error && (saved_ino || saved_dev))
14183+ gr_handle_delete(saved_ino, saved_dev);
14184 exit2:
14185 dput(dentry);
14186 }
14187@@ -2245,7 +2364,16 @@ asmlinkage long sys_symlinkat(const char
14188 if (IS_ERR(dentry))
14189 goto out_unlock;
14190
14191+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
14192+ error = -EACCES;
14193+ goto out_dput_unlock;
14194+ }
14195+
14196 error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
14197+
14198+ if (!error)
14199+ gr_handle_create(dentry, nd.mnt);
14200+out_dput_unlock:
14201 dput(dentry);
14202 out_unlock:
14203 mutex_unlock(&nd.dentry->d_inode->i_mutex);
14204@@ -2340,7 +2468,25 @@ asmlinkage long sys_linkat(int olddfd, c
14205 error = PTR_ERR(new_dentry);
14206 if (IS_ERR(new_dentry))
14207 goto out_unlock;
14208+
14209+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
14210+ old_nd.dentry->d_inode,
14211+ old_nd.dentry->d_inode->i_mode, to)) {
14212+ error = -EACCES;
14213+ goto out_unlock_dput;
14214+ }
14215+
14216+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
14217+ old_nd.dentry, old_nd.mnt, to)) {
14218+ error = -EACCES;
14219+ goto out_unlock_dput;
14220+ }
14221+
14222 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
14223+
14224+ if (!error)
14225+ gr_handle_create(new_dentry, nd.mnt);
14226+out_unlock_dput:
14227 dput(new_dentry);
14228 out_unlock:
14229 mutex_unlock(&nd.dentry->d_inode->i_mutex);
14230@@ -2566,8 +2712,16 @@ static int do_rename(int olddfd, const c
14231 if (new_dentry == trap)
14232 goto exit5;
14233
14234- error = vfs_rename(old_dir->d_inode, old_dentry,
14235+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
14236+ old_dentry, old_dir->d_inode, oldnd.mnt,
14237+ newname);
14238+
14239+ if (!error)
14240+ error = vfs_rename(old_dir->d_inode, old_dentry,
14241 new_dir->d_inode, new_dentry);
14242+ if (!error)
14243+ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
14244+ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
14245 exit5:
14246 dput(new_dentry);
14247 exit4:
14248diff -urNp linux-2.6.22.1/fs/namespace.c linux-2.6.22.1/fs/namespace.c
14249--- linux-2.6.22.1/fs/namespace.c 2007-07-10 14:56:30.000000000 -0400
14250+++ linux-2.6.22.1/fs/namespace.c 2007-08-02 11:09:15.000000000 -0400
14251@@ -25,6 +25,7 @@
14252 #include <linux/vs_tag.h>
14253 #include <linux/vserver/space.h>
14254 #include <linux/vserver/global.h>
14255+#include <linux/grsecurity.h>
14256 #include <asm/uaccess.h>
14257 #include <asm/unistd.h>
14258 #include "pnode.h"
14259@@ -602,6 +603,8 @@ static int do_umount(struct vfsmount *mn
14260 DQUOT_OFF(sb);
14261 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
14262 unlock_kernel();
14263+
14264+ gr_log_remount(mnt->mnt_devname, retval);
14265 }
14266 up_write(&sb->s_umount);
14267 return retval;
14268@@ -622,6 +625,9 @@ static int do_umount(struct vfsmount *mn
14269 security_sb_umount_busy(mnt);
14270 up_write(&namespace_sem);
14271 release_mounts(&umount_list);
14272+
14273+ gr_log_unmount(mnt->mnt_devname, retval);
14274+
14275 return retval;
14276 }
14277
14278@@ -1427,6 +1433,11 @@ long do_mount(char *dev_name, char *dir_
14279 if (retval)
14280 goto dput_out;
14281
14282+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
14283+ retval = -EPERM;
14284+ goto dput_out;
14285+ }
14286+
14287 if (flags & MS_REMOUNT)
14288 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
14289 data_page, tag);
14290@@ -1441,6 +1452,9 @@ long do_mount(char *dev_name, char *dir_
14291 dev_name, data_page);
14292 dput_out:
14293 path_release(&nd);
14294+
14295+ gr_log_mount(dev_name, dir_name, retval);
14296+
14297 return retval;
14298 }
14299
14300@@ -1678,6 +1692,9 @@ asmlinkage long sys_pivot_root(const cha
14301 if (!capable(CAP_SYS_ADMIN))
14302 return -EPERM;
14303
14304+ if (gr_handle_chroot_pivot())
14305+ return -EPERM;
14306+
14307 lock_kernel();
14308
14309 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
14310diff -urNp linux-2.6.22.1/fs/nfs/callback_xdr.c linux-2.6.22.1/fs/nfs/callback_xdr.c
14311--- linux-2.6.22.1/fs/nfs/callback_xdr.c 2007-07-10 14:56:30.000000000 -0400
14312+++ linux-2.6.22.1/fs/nfs/callback_xdr.c 2007-08-02 11:38:47.000000000 -0400
14313@@ -139,7 +139,7 @@ static __be32 decode_compound_hdr_arg(st
14314 if (unlikely(status != 0))
14315 return status;
14316 /* We do not like overly long tags! */
14317- if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12 || hdr->taglen < 0) {
14318+ if (hdr->taglen > CB_OP_TAGLEN_MAXSZ-12) {
14319 printk("NFSv4 CALLBACK %s: client sent tag of length %u\n",
14320 __FUNCTION__, hdr->taglen);
14321 return htonl(NFS4ERR_RESOURCE);
14322diff -urNp linux-2.6.22.1/fs/nfs/nfs4proc.c linux-2.6.22.1/fs/nfs/nfs4proc.c
14323--- linux-2.6.22.1/fs/nfs/nfs4proc.c 2007-07-10 14:56:30.000000000 -0400
14324+++ linux-2.6.22.1/fs/nfs/nfs4proc.c 2007-08-02 11:38:47.000000000 -0400
14325@@ -493,7 +493,7 @@ static int _nfs4_do_open_reclaim(struct
14326 static int nfs4_do_open_reclaim(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
14327 {
14328 struct nfs_server *server = NFS_SERVER(state->inode);
14329- struct nfs4_exception exception = { };
14330+ struct nfs4_exception exception = {0, 0};
14331 int err;
14332 do {
14333 err = _nfs4_do_open_reclaim(ctx, state);
14334@@ -538,7 +538,7 @@ static int _nfs4_open_delegation_recall(
14335
14336 int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
14337 {
14338- struct nfs4_exception exception = { };
14339+ struct nfs4_exception exception = {0, 0};
14340 struct nfs_server *server = NFS_SERVER(state->inode);
14341 int err;
14342 do {
14343@@ -843,7 +843,7 @@ static int _nfs4_open_expired(struct nfs
14344 static inline int nfs4_do_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state, struct dentry *dentry)
14345 {
14346 struct nfs_server *server = NFS_SERVER(state->inode);
14347- struct nfs4_exception exception = { };
14348+ struct nfs4_exception exception = {0, 0};
14349 int err;
14350
14351 do {
14352@@ -1090,7 +1090,7 @@ static int nfs4_do_setattr(struct inode
14353 struct iattr *sattr, struct nfs4_state *state)
14354 {
14355 struct nfs_server *server = NFS_SERVER(inode);
14356- struct nfs4_exception exception = { };
14357+ struct nfs4_exception exception = {0, 0};
14358 int err;
14359 do {
14360 err = nfs4_handle_exception(server,
14361@@ -1354,7 +1354,7 @@ static int _nfs4_server_capabilities(str
14362
14363 int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
14364 {
14365- struct nfs4_exception exception = { };
14366+ struct nfs4_exception exception = {0, 0};
14367 int err;
14368 do {
14369 err = nfs4_handle_exception(server,
14370@@ -1387,7 +1387,7 @@ static int _nfs4_lookup_root(struct nfs_
14371 static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
14372 struct nfs_fsinfo *info)
14373 {
14374- struct nfs4_exception exception = { };
14375+ struct nfs4_exception exception = {0, 0};
14376 int err;
14377 do {
14378 err = nfs4_handle_exception(server,
14379@@ -1476,7 +1476,7 @@ static int _nfs4_proc_getattr(struct nfs
14380
14381 static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
14382 {
14383- struct nfs4_exception exception = { };
14384+ struct nfs4_exception exception = {0, 0};
14385 int err;
14386 do {
14387 err = nfs4_handle_exception(server,
14388@@ -1568,7 +1568,7 @@ static int nfs4_proc_lookupfh(struct nfs
14389 struct qstr *name, struct nfs_fh *fhandle,
14390 struct nfs_fattr *fattr)
14391 {
14392- struct nfs4_exception exception = { };
14393+ struct nfs4_exception exception = {0, 0};
14394 int err;
14395 do {
14396 err = nfs4_handle_exception(server,
14397@@ -1612,7 +1612,7 @@ static int _nfs4_proc_lookup(struct inod
14398
14399 static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
14400 {
14401- struct nfs4_exception exception = { };
14402+ struct nfs4_exception exception = {0, 0};
14403 int err;
14404 do {
14405 err = nfs4_handle_exception(NFS_SERVER(dir),
14406@@ -1668,7 +1668,7 @@ static int _nfs4_proc_access(struct inod
14407
14408 static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
14409 {
14410- struct nfs4_exception exception = { };
14411+ struct nfs4_exception exception = {0, 0};
14412 int err;
14413 do {
14414 err = nfs4_handle_exception(NFS_SERVER(inode),
14415@@ -1723,7 +1723,7 @@ static int _nfs4_proc_readlink(struct in
14416 static int nfs4_proc_readlink(struct inode *inode, struct page *page,
14417 unsigned int pgbase, unsigned int pglen)
14418 {
14419- struct nfs4_exception exception = { };
14420+ struct nfs4_exception exception = {0, 0};
14421 int err;
14422 do {
14423 err = nfs4_handle_exception(NFS_SERVER(inode),
14424@@ -1813,7 +1813,7 @@ static int _nfs4_proc_remove(struct inod
14425
14426 static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
14427 {
14428- struct nfs4_exception exception = { };
14429+ struct nfs4_exception exception = {0, 0};
14430 int err;
14431 do {
14432 err = nfs4_handle_exception(NFS_SERVER(dir),
14433@@ -1907,7 +1907,7 @@ static int _nfs4_proc_rename(struct inod
14434 static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
14435 struct inode *new_dir, struct qstr *new_name)
14436 {
14437- struct nfs4_exception exception = { };
14438+ struct nfs4_exception exception = {0, 0};
14439 int err;
14440 do {
14441 err = nfs4_handle_exception(NFS_SERVER(old_dir),
14442@@ -1954,7 +1954,7 @@ static int _nfs4_proc_link(struct inode
14443
14444 static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
14445 {
14446- struct nfs4_exception exception = { };
14447+ struct nfs4_exception exception = {0, 0};
14448 int err;
14449 do {
14450 err = nfs4_handle_exception(NFS_SERVER(inode),
14451@@ -2011,7 +2011,7 @@ static int _nfs4_proc_symlink(struct ino
14452 static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
14453 struct page *page, unsigned int len, struct iattr *sattr)
14454 {
14455- struct nfs4_exception exception = { };
14456+ struct nfs4_exception exception = {0, 0};
14457 int err;
14458 do {
14459 err = nfs4_handle_exception(NFS_SERVER(dir),
14460@@ -2064,7 +2064,7 @@ static int _nfs4_proc_mkdir(struct inode
14461 static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
14462 struct iattr *sattr)
14463 {
14464- struct nfs4_exception exception = { };
14465+ struct nfs4_exception exception = {0, 0};
14466 int err;
14467 do {
14468 err = nfs4_handle_exception(NFS_SERVER(dir),
14469@@ -2110,7 +2110,7 @@ static int _nfs4_proc_readdir(struct den
14470 static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
14471 u64 cookie, struct page *page, unsigned int count, int plus)
14472 {
14473- struct nfs4_exception exception = { };
14474+ struct nfs4_exception exception = {0, 0};
14475 int err;
14476 do {
14477 err = nfs4_handle_exception(NFS_SERVER(state->inode),
14478@@ -2180,7 +2180,7 @@ static int _nfs4_proc_mknod(struct inode
14479 static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
14480 struct iattr *sattr, dev_t rdev)
14481 {
14482- struct nfs4_exception exception = { };
14483+ struct nfs4_exception exception = {0, 0};
14484 int err;
14485 do {
14486 err = nfs4_handle_exception(NFS_SERVER(dir),
14487@@ -2209,7 +2209,7 @@ static int _nfs4_proc_statfs(struct nfs_
14488
14489 static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
14490 {
14491- struct nfs4_exception exception = { };
14492+ struct nfs4_exception exception = {0, 0};
14493 int err;
14494 do {
14495 err = nfs4_handle_exception(server,
14496@@ -2237,7 +2237,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
14497
14498 static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
14499 {
14500- struct nfs4_exception exception = { };
14501+ struct nfs4_exception exception = {0, 0};
14502 int err;
14503
14504 do {
14505@@ -2280,7 +2280,7 @@ static int _nfs4_proc_pathconf(struct nf
14506 static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
14507 struct nfs_pathconf *pathconf)
14508 {
14509- struct nfs4_exception exception = { };
14510+ struct nfs4_exception exception = {0, 0};
14511 int err;
14512
14513 do {
14514@@ -2599,7 +2599,7 @@ out_free:
14515
14516 static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
14517 {
14518- struct nfs4_exception exception = { };
14519+ struct nfs4_exception exception = {0, 0};
14520 ssize_t ret;
14521 do {
14522 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
14523@@ -2653,7 +2653,7 @@ static int __nfs4_proc_set_acl(struct in
14524
14525 static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
14526 {
14527- struct nfs4_exception exception = { };
14528+ struct nfs4_exception exception = {0, 0};
14529 int err;
14530 do {
14531 err = nfs4_handle_exception(NFS_SERVER(inode),
14532@@ -2950,7 +2950,7 @@ static int _nfs4_proc_delegreturn(struct
14533 int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid)
14534 {
14535 struct nfs_server *server = NFS_SERVER(inode);
14536- struct nfs4_exception exception = { };
14537+ struct nfs4_exception exception = {0, 0};
14538 int err;
14539 do {
14540 err = _nfs4_proc_delegreturn(inode, cred, stateid);
14541@@ -3025,7 +3025,7 @@ out:
14542
14543 static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
14544 {
14545- struct nfs4_exception exception = { };
14546+ struct nfs4_exception exception = {0, 0};
14547 int err;
14548
14549 do {
14550@@ -3354,7 +3354,7 @@ static int _nfs4_do_setlk(struct nfs4_st
14551 static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
14552 {
14553 struct nfs_server *server = NFS_SERVER(state->inode);
14554- struct nfs4_exception exception = { };
14555+ struct nfs4_exception exception = {0, 0};
14556 int err;
14557
14558 do {
14559@@ -3372,7 +3372,7 @@ static int nfs4_lock_reclaim(struct nfs4
14560 static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
14561 {
14562 struct nfs_server *server = NFS_SERVER(state->inode);
14563- struct nfs4_exception exception = { };
14564+ struct nfs4_exception exception = {0, 0};
14565 int err;
14566
14567 err = nfs4_set_lock_state(state, request);
14568@@ -3433,7 +3433,7 @@ out:
14569
14570 static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
14571 {
14572- struct nfs4_exception exception = { };
14573+ struct nfs4_exception exception = {0, 0};
14574 int err;
14575
14576 do {
14577@@ -3483,7 +3483,7 @@ nfs4_proc_lock(struct file *filp, int cm
14578 int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
14579 {
14580 struct nfs_server *server = NFS_SERVER(state->inode);
14581- struct nfs4_exception exception = { };
14582+ struct nfs4_exception exception = {0, 0};
14583 int err;
14584
14585 err = nfs4_set_lock_state(state, fl);
14586diff -urNp linux-2.6.22.1/fs/nfsd/nfs4state.c linux-2.6.22.1/fs/nfsd/nfs4state.c
14587--- linux-2.6.22.1/fs/nfsd/nfs4state.c 2007-07-10 14:56:30.000000000 -0400
14588+++ linux-2.6.22.1/fs/nfsd/nfs4state.c 2007-08-02 11:38:47.000000000 -0400
14589@@ -1243,7 +1243,7 @@ static int access_valid(u32 x)
14590
14591 static int deny_valid(u32 x)
14592 {
14593- return (x >= 0 && x < 5);
14594+ return (x < 5);
14595 }
14596
14597 static void
14598diff -urNp linux-2.6.22.1/fs/nls/nls_base.c linux-2.6.22.1/fs/nls/nls_base.c
14599--- linux-2.6.22.1/fs/nls/nls_base.c 2007-07-10 14:56:30.000000000 -0400
14600+++ linux-2.6.22.1/fs/nls/nls_base.c 2007-08-02 11:38:47.000000000 -0400
14601@@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] =
14602 {0xF8, 0xF0, 3*6, 0x1FFFFF, 0x10000, /* 4 byte sequence */},
14603 {0xFC, 0xF8, 4*6, 0x3FFFFFF, 0x200000, /* 5 byte sequence */},
14604 {0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */},
14605- {0, /* end of table */}
14606+ {0, 0, 0, 0, 0, /* end of table */}
14607 };
14608
14609 int
14610diff -urNp linux-2.6.22.1/fs/ntfs/file.c linux-2.6.22.1/fs/ntfs/file.c
14611--- linux-2.6.22.1/fs/ntfs/file.c 2007-07-10 14:56:30.000000000 -0400
14612+++ linux-2.6.22.1/fs/ntfs/file.c 2007-08-02 11:38:47.000000000 -0400
14613@@ -2295,6 +2295,6 @@ const struct inode_operations ntfs_file_
14614 #endif /* NTFS_RW */
14615 };
14616
14617-const struct file_operations ntfs_empty_file_ops = {};
14618+const struct file_operations ntfs_empty_file_ops;
14619
14620-const struct inode_operations ntfs_empty_inode_ops = {};
14621+const struct inode_operations ntfs_empty_inode_ops;
14622diff -urNp linux-2.6.22.1/fs/open.c linux-2.6.22.1/fs/open.c
14623--- linux-2.6.22.1/fs/open.c 2007-07-10 14:56:30.000000000 -0400
14624+++ linux-2.6.22.1/fs/open.c 2007-08-02 11:09:15.000000000 -0400
14625@@ -26,6 +26,7 @@
14626 #include <linux/vs_dlimit.h>
14627 #include <linux/vs_tag.h>
14628 #include <linux/vs_cowbl.h>
14629+#include <linux/grsecurity.h>
14630
14631 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
14632 {
14633@@ -203,6 +204,9 @@ int do_truncate(struct dentry *dentry, l
14634 if (length < 0)
14635 return -EINVAL;
14636
14637+ if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
14638+ return -EACCES;
14639+
14640 newattrs.ia_size = length;
14641 newattrs.ia_valid = ATTR_SIZE | time_attrs;
14642 if (filp) {
14643@@ -400,6 +404,9 @@ asmlinkage long sys_faccessat(int dfd, c
14644 if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
14645 res = -EROFS;
14646
14647+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
14648+ res = -EACCES;
14649+
14650 out_path_release:
14651 path_release(&nd);
14652 out:
14653@@ -429,6 +436,8 @@ asmlinkage long sys_chdir(const char __u
14654 if (error)
14655 goto dput_and_out;
14656
14657+ gr_log_chdir(nd.dentry, nd.mnt);
14658+
14659 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
14660
14661 dput_and_out:
14662@@ -459,6 +468,13 @@ asmlinkage long sys_fchdir(unsigned int
14663 goto out_putf;
14664
14665 error = file_permission(file, MAY_EXEC);
14666+
14667+ if (!error && !gr_chroot_fchdir(dentry, mnt))
14668+ error = -EPERM;
14669+
14670+ if (!error)
14671+ gr_log_chdir(dentry, mnt);
14672+
14673 if (!error)
14674 set_fs_pwd(current->fs, mnt, dentry);
14675 out_putf:
14676@@ -484,8 +500,16 @@ asmlinkage long sys_chroot(const char __
14677 if (!capable(CAP_SYS_CHROOT))
14678 goto dput_and_out;
14679
14680+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
14681+ goto dput_and_out;
14682+
14683 set_fs_root(current->fs, nd.mnt, nd.dentry);
14684 set_fs_altroot();
14685+
14686+ gr_handle_chroot_caps(current);
14687+
14688+ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
14689+
14690 error = 0;
14691 dput_and_out:
14692 path_release(&nd);
14693@@ -516,9 +540,22 @@ asmlinkage long sys_fchmod(unsigned int
14694 err = -EPERM;
14695 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
14696 goto out_putf;
14697+
14698+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
14699+ err = -EACCES;
14700+ goto out_putf;
14701+ }
14702+
14703 mutex_lock(&inode->i_mutex);
14704 if (mode == (mode_t) -1)
14705 mode = inode->i_mode;
14706+
14707+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
14708+ err = -EPERM;
14709+ mutex_unlock(&inode->i_mutex);
14710+ goto out_putf;
14711+ }
14712+
14713 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
14714 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
14715 err = notify_change(dentry, &newattrs);
14716@@ -551,9 +588,21 @@ asmlinkage long sys_fchmodat(int dfd, co
14717 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
14718 goto dput_and_out;
14719
14720+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
14721+ error = -EACCES;
14722+ goto dput_and_out;
14723+ };
14724+
14725 mutex_lock(&inode->i_mutex);
14726 if (mode == (mode_t) -1)
14727 mode = inode->i_mode;
14728+
14729+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
14730+ error = -EACCES;
14731+ mutex_unlock(&inode->i_mutex);
14732+ goto dput_and_out;
14733+ }
14734+
14735 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
14736 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
14737 error = notify_change(nd.dentry, &newattrs);
14738@@ -587,6 +636,12 @@ static int chown_common(struct dentry *
14739 error = -EPERM;
14740 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
14741 goto out;
14742+
14743+ if (!gr_acl_handle_chown(dentry, mnt)) {
14744+ error = -EACCES;
14745+ goto out;
14746+ }
14747+
14748 newattrs.ia_valid = ATTR_CTIME;
14749 if (user != (uid_t) -1) {
14750 newattrs.ia_valid |= ATTR_UID;
14751@@ -873,6 +928,7 @@ repeat:
14752 * N.B. For clone tasks sharing a files structure, this test
14753 * will limit the total number of files that can be opened.
14754 */
14755+ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
14756 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
14757 goto out;
14758
14759diff -urNp linux-2.6.22.1/fs/partitions/efi.c linux-2.6.22.1/fs/partitions/efi.c
14760--- linux-2.6.22.1/fs/partitions/efi.c 2007-07-10 14:56:30.000000000 -0400
14761+++ linux-2.6.22.1/fs/partitions/efi.c 2007-08-02 11:38:47.000000000 -0400
14762@@ -99,7 +99,7 @@
14763 #ifdef EFI_DEBUG
14764 #define Dprintk(x...) printk(KERN_DEBUG x)
14765 #else
14766-#define Dprintk(x...)
14767+#define Dprintk(x...) do {} while (0)
14768 #endif
14769
14770 /* This allows a kernel command line option 'gpt' to override
14771diff -urNp linux-2.6.22.1/fs/pipe.c linux-2.6.22.1/fs/pipe.c
14772--- linux-2.6.22.1/fs/pipe.c 2007-07-10 14:56:30.000000000 -0400
14773+++ linux-2.6.22.1/fs/pipe.c 2007-08-02 11:09:15.000000000 -0400
14774@@ -828,7 +828,7 @@ void free_pipe_info(struct inode *inode)
14775 inode->i_pipe = NULL;
14776 }
14777
14778-static struct vfsmount *pipe_mnt __read_mostly;
14779+struct vfsmount *pipe_mnt __read_mostly;
14780 static int pipefs_delete_dentry(struct dentry *dentry)
14781 {
14782 /*
14783diff -urNp linux-2.6.22.1/fs/proc/array.c linux-2.6.22.1/fs/proc/array.c
14784--- linux-2.6.22.1/fs/proc/array.c 2007-07-10 14:56:30.000000000 -0400
14785+++ linux-2.6.22.1/fs/proc/array.c 2007-08-02 11:38:47.000000000 -0400
14786@@ -291,6 +291,21 @@ static inline char *task_cap(struct task
14787 (unsigned)vx_info_mbcap(vxi, p->cap_effective));
14788 }
14789
14790+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14791+static inline char *task_pax(struct task_struct *p, char *buffer)
14792+{
14793+ if (p->mm)
14794+ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
14795+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
14796+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
14797+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
14798+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
14799+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
14800+ else
14801+ return buffer + sprintf(buffer, "PaX:\t-----\n");
14802+}
14803+#endif
14804+
14805 int proc_pid_status(struct task_struct *task, char * buffer)
14806 {
14807 char * orig = buffer;
14808@@ -309,9 +324,20 @@ int proc_pid_status(struct task_struct *
14809 #if defined(CONFIG_S390)
14810 buffer = task_show_regs(task, buffer);
14811 #endif
14812+
14813+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14814+ buffer = task_pax(task, buffer);
14815+#endif
14816+
14817 return buffer - orig;
14818 }
14819
14820+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14821+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
14822+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
14823+ _mm->pax_flags & MF_PAX_SEGMEXEC))
14824+#endif
14825+
14826 static int do_task_stat(struct task_struct *task, char * buffer, int whole)
14827 {
14828 unsigned long vsize, eip, esp, wchan = ~0UL;
14829@@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
14830 stime = task->stime;
14831 }
14832
14833+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14834+ if (PAX_RAND_FLAGS(mm)) {
14835+ eip = 0;
14836+ esp = 0;
14837+ wchan = 0;
14838+ }
14839+#endif
14840+#ifdef CONFIG_GRKERNSEC_HIDESYM
14841+ wchan = 0;
14842+ eip =0;
14843+ esp =0;
14844+#endif
14845+
14846 /* scale priority and nice values from timeslices to -20..20 */
14847 /* to make it look like a "normal" Unix priority/nice value */
14848 priority = task_prio(task);
14849@@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
14850 vsize,
14851 mm ? get_mm_rss(mm) : 0,
14852 rsslim,
14853+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14854+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
14855+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
14856+ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
14857+#else
14858 mm ? mm->start_code : 0,
14859 mm ? mm->end_code : 0,
14860 mm ? mm->start_stack : 0,
14861+#endif
14862 esp,
14863 eip,
14864 /* The signal information here is obsolete.
14865@@ -486,3 +531,14 @@ int proc_pid_statm(struct task_struct *t
14866 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
14867 size, resident, shared, text, lib, data, 0);
14868 }
14869+
14870+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
14871+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
14872+{
14873+ int len;
14874+
14875+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
14876+ return len;
14877+}
14878+#endif
14879+
14880diff -urNp linux-2.6.22.1/fs/proc/base.c linux-2.6.22.1/fs/proc/base.c
14881--- linux-2.6.22.1/fs/proc/base.c 2007-07-10 14:56:30.000000000 -0400
14882+++ linux-2.6.22.1/fs/proc/base.c 2007-08-02 11:38:47.000000000 -0400
14883@@ -73,6 +73,7 @@
14884 #include <linux/oom.h>
14885 #include <linux/vs_context.h>
14886 #include <linux/vs_network.h>
14887+#include <linux/grsecurity.h>
14888
14889 #include "internal.h"
14890
14891@@ -123,7 +124,7 @@ struct pid_entry {
14892 NULL, &proc_info_file_operations, \
14893 { .proc_read = &proc_##OTYPE } )
14894
14895-int maps_protect;
14896+int maps_protect = 1;
14897 EXPORT_SYMBOL(maps_protect);
14898
14899 static struct fs_struct *get_fs_struct(struct task_struct *task)
14900@@ -197,7 +198,7 @@ static int proc_root_link(struct inode *
14901 (task->parent == current && \
14902 (task->ptrace & PT_PTRACED) && \
14903 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
14904- security_ptrace(current,task) == 0))
14905+ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
14906
14907 static int proc_pid_environ(struct task_struct *task, char * buffer)
14908 {
14909@@ -258,9 +259,9 @@ static int proc_pid_auxv(struct task_str
14910 struct mm_struct *mm = get_task_mm(task);
14911 if (mm) {
14912 unsigned int nwords = 0;
14913- do
14914+ do {
14915 nwords += 2;
14916- while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
14917+ } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
14918 res = nwords * sizeof(mm->saved_auxv[0]);
14919 if (res > PAGE_SIZE)
14920 res = PAGE_SIZE;
14921@@ -333,6 +334,8 @@ static int proc_fd_access_allowed(struct
14922 task = get_proc_task(inode);
14923 if (task) {
14924 allowed = ptrace_may_attach(task);
14925+ if (allowed != 0)
14926+ allowed = !gr_acl_handle_procpidmem(task);
14927 put_task_struct(task);
14928 }
14929 return allowed;
14930@@ -523,7 +526,7 @@ static ssize_t mem_read(struct file * fi
14931 if (!task)
14932 goto out_no_task;
14933
14934- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
14935+ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
14936 goto out;
14937
14938 ret = -ENOMEM;
14939@@ -593,7 +596,7 @@ static ssize_t mem_write(struct file * f
14940 if (!task)
14941 goto out_no_task;
14942
14943- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
14944+ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
14945 goto out;
14946
14947 copied = -ENOMEM;
14948@@ -1050,7 +1053,11 @@ static struct inode *proc_pid_make_inode
14949 inode->i_gid = 0;
14950 if (task_dumpable(task)) {
14951 inode->i_uid = task->euid;
14952+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
14953+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
14954+#else
14955 inode->i_gid = task->egid;
14956+#endif
14957 }
14958 /* procfs is xid tagged */
14959 inode->i_tag = (tag_t)vx_task_xid(task);
14960@@ -1063,17 +1070,45 @@ static int pid_getattr(struct vfsmount *
14961 {
14962 struct inode *inode = dentry->d_inode;
14963 struct task_struct *task;
14964+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14965+ struct task_struct *tmp = current;
14966+#endif
14967+
14968 generic_fillattr(inode, stat);
14969
14970 rcu_read_lock();
14971 stat->uid = 0;
14972 stat->gid = 0;
14973 task = pid_task(proc_pid(inode), PIDTYPE_PID);
14974- if (task) {
14975+
14976+ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
14977+ rcu_read_unlock();
14978+ return -ENOENT;
14979+ }
14980+
14981+
14982+ if (task
14983+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14984+ && (!tmp->uid || (tmp->uid == task->uid)
14985+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
14986+ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
14987+#endif
14988+ )
14989+#endif
14990+ ) {
14991 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
14992+#ifdef CONFIG_GRKERNSEC_PROC_USER
14993+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
14994+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
14995+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
14996+#endif
14997 task_dumpable(task)) {
14998 stat->uid = task->euid;
14999+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
15000+ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
15001+#else
15002 stat->gid = task->egid;
15003+#endif
15004 }
15005 }
15006 rcu_read_unlock();
15007@@ -1101,6 +1136,12 @@ static int pid_revalidate(struct dentry
15008 {
15009 struct inode *inode = dentry->d_inode;
15010 struct task_struct *task = get_proc_task(inode);
15011+
15012+ if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
15013+ put_task_struct(task);
15014+ goto drop;
15015+ }
15016+
15017 if (task) {
15018 unsigned pid = name_to_int(dentry);
15019 if (pid != ~0U && pid != vx_map_pid(task->pid)) {
15020@@ -1151,9 +1194,18 @@ static int pid_revalidate(struct dentry
15021 }
15022
15023 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
15024+#ifdef CONFIG_GRKERNSEC_PROC_USER
15025+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
15026+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
15027+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
15028+#endif
15029 task_dumpable(task)) {
15030 inode->i_uid = task->euid;
15031+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
15032+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
15033+#else
15034 inode->i_gid = task->egid;
15035+#endif
15036 } else {
15037 inode->i_uid = 0;
15038 inode->i_gid = 0;
15039@@ -1371,6 +1435,9 @@ static struct dentry *proc_lookupfd_comm
15040 if (fd == ~0U)
15041 goto out;
15042
15043+ if (gr_acl_handle_procpidmem(task))
15044+ goto out;
15045+
15046 result = instantiate(dir, dentry, task, &fd);
15047 out:
15048 put_task_struct(task);
15049@@ -1407,6 +1461,8 @@ static int proc_readfd_common(struct fil
15050 goto out;
15051 filp->f_pos++;
15052 default:
15053+ if (gr_acl_handle_procpidmem(p))
15054+ goto out;
15055 files = get_files_struct(p);
15056 if (!files)
15057 goto out;
15058@@ -1595,6 +1651,9 @@ static struct dentry *proc_pident_lookup
15059 !memcmp(dentry->d_name.name, "ninfo", 5)))
15060 goto out;
15061
15062+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
15063+ goto out;
15064+
15065 /*
15066 * Yes, it does not scale. And it should not. Don't add
15067 * new entries into /proc/<tgid>/ without very good reasons.
15068@@ -1640,6 +1699,9 @@ static int proc_pident_readdir(struct fi
15069 if (!task)
15070 goto out_no_task;
15071
15072+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
15073+ goto out;
15074+
15075 ret = 0;
15076 pid = task->pid;
15077 i = filp->f_pos;
15078@@ -1910,6 +1972,9 @@ static struct dentry *proc_base_lookup(s
15079 if (p > last)
15080 goto out;
15081
15082+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
15083+ goto out;
15084+
15085 error = proc_base_instantiate(dir, dentry, task, p);
15086
15087 out:
15088@@ -2006,6 +2071,9 @@ static const struct pid_entry tgid_base_
15089 #ifdef CONFIG_TASK_IO_ACCOUNTING
15090 INF("io", S_IRUGO, pid_io_accounting),
15091 #endif
15092+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
15093+ INF("ipaddr", S_IRUSR, pid_ipaddr),
15094+#endif
15095 };
15096
15097 static int proc_tgid_base_readdir(struct file * filp,
15098@@ -2109,7 +2177,14 @@ static struct dentry *proc_pid_instantia
15099 if (!inode)
15100 goto out;
15101
15102+#ifdef CONFIG_GRKERNSEC_PROC_USER
15103+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
15104+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
15105+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
15106+ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
15107+#else
15108 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
15109+#endif
15110 inode->i_op = &proc_tgid_base_inode_operations;
15111 inode->i_fop = &proc_tgid_base_operations;
15112 inode->i_flags|=S_IMMUTABLE;
15113@@ -2150,7 +2225,11 @@ struct dentry *proc_pid_lookup(struct in
15114 if (!task)
15115 goto out;
15116
15117+ if (gr_check_hidden_task(task))
15118+ goto out_put_task;
15119+
15120 result = proc_pid_instantiate(dir, dentry, task, NULL);
15121+out_put_task:
15122 put_task_struct(task);
15123 out:
15124 return result;
15125@@ -2208,6 +2287,9 @@ int proc_pid_readdir(struct file * filp,
15126 {
15127 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
15128 struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
15129+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15130+ struct task_struct *tmp = current;
15131+#endif
15132 struct task_struct *task;
15133 int tgid;
15134
15135@@ -2225,6 +2307,18 @@ int proc_pid_readdir(struct file * filp,
15136 task;
15137 put_task_struct(task), task = next_tgid(tgid + 1)) {
15138 tgid = task->pid;
15139+
15140+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
15141+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15142+ || (tmp->uid && (task->uid != tmp->uid)
15143+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
15144+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
15145+#endif
15146+ )
15147+#endif
15148+ )
15149+ continue;
15150+
15151 filp->f_pos = tgid + TGID_OFFSET;
15152 if (!vx_proc_task_visible(task))
15153 continue;
15154diff -urNp linux-2.6.22.1/fs/proc/inode.c linux-2.6.22.1/fs/proc/inode.c
15155--- linux-2.6.22.1/fs/proc/inode.c 2007-07-10 14:56:30.000000000 -0400
15156+++ linux-2.6.22.1/fs/proc/inode.c 2007-08-02 11:09:15.000000000 -0400
15157@@ -158,7 +158,11 @@ struct inode *proc_get_inode(struct supe
15158 if (de->mode) {
15159 inode->i_mode = de->mode;
15160 inode->i_uid = de->uid;
15161+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
15162+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
15163+#else
15164 inode->i_gid = de->gid;
15165+#endif
15166 }
15167 if (de->vx_flags)
15168 PROC_I(inode)->vx_flags = de->vx_flags;
15169diff -urNp linux-2.6.22.1/fs/proc/internal.h linux-2.6.22.1/fs/proc/internal.h
15170--- linux-2.6.22.1/fs/proc/internal.h 2007-07-10 14:56:30.000000000 -0400
15171+++ linux-2.6.22.1/fs/proc/internal.h 2007-08-02 11:09:15.000000000 -0400
15172@@ -45,6 +45,9 @@ extern int proc_tid_stat(struct task_str
15173 extern int proc_tgid_stat(struct task_struct *, char *);
15174 extern int proc_pid_status(struct task_struct *, char *);
15175 extern int proc_pid_statm(struct task_struct *, char *);
15176+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
15177+extern int proc_pid_ipaddr(struct task_struct*,char*);
15178+#endif
15179
15180 extern const struct file_operations proc_maps_operations;
15181 extern const struct file_operations proc_numa_maps_operations;
15182diff -urNp linux-2.6.22.1/fs/proc/proc_misc.c linux-2.6.22.1/fs/proc/proc_misc.c
15183--- linux-2.6.22.1/fs/proc/proc_misc.c 2007-07-10 14:56:30.000000000 -0400
15184+++ linux-2.6.22.1/fs/proc/proc_misc.c 2007-08-02 11:09:15.000000000 -0400
15185@@ -657,6 +657,8 @@ void create_seq_entry(char *name, mode_t
15186
15187 void __init proc_misc_init(void)
15188 {
15189+ int gr_mode = 0;
15190+
15191 static struct {
15192 char *name;
15193 int (*read_proc)(char*,char**,off_t,int,int*,void*);
15194@@ -672,7 +674,9 @@ void __init proc_misc_init(void)
15195 {"stram", stram_read_proc},
15196 #endif
15197 {"filesystems", filesystems_read_proc},
15198+#ifndef CONFIG_GRKERNSEC_PROC_ADD
15199 {"cmdline", cmdline_read_proc},
15200+#endif
15201 {"locks", locks_read_proc},
15202 {"execdomains", execdomains_read_proc},
15203 {NULL,}
15204@@ -680,6 +684,15 @@ void __init proc_misc_init(void)
15205 for (p = simple_ones; p->name; p++)
15206 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
15207
15208+#ifdef CONFIG_GRKERNSEC_PROC_USER
15209+ gr_mode = S_IRUSR;
15210+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15211+ gr_mode = S_IRUSR | S_IRGRP;
15212+#endif
15213+#ifdef CONFIG_GRKERNSEC_PROC_ADD
15214+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
15215+#endif
15216+
15217 proc_symlink("mounts", NULL, "self/mounts");
15218
15219 /* And now for trickier ones */
15220@@ -691,7 +704,11 @@ void __init proc_misc_init(void)
15221 entry->proc_fops = &proc_kmsg_operations;
15222 }
15223 #endif
15224+#ifdef CONFIG_GRKERNSEC_PROC_ADD
15225+ create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
15226+#else
15227 create_seq_entry("devices", 0, &proc_devinfo_operations);
15228+#endif
15229 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
15230 #ifdef CONFIG_BLOCK
15231 create_seq_entry("partitions", 0, &proc_partitions_operations);
15232@@ -699,7 +716,11 @@ void __init proc_misc_init(void)
15233 create_seq_entry("stat", 0, &proc_stat_operations);
15234 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
15235 #ifdef CONFIG_SLAB
15236+#ifdef CONFIG_GRKERNSEC_PROC_ADD
15237+ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
15238+#else
15239 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
15240+#endif
15241 #ifdef CONFIG_DEBUG_SLAB_LEAK
15242 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
15243 #endif
15244@@ -716,7 +737,7 @@ void __init proc_misc_init(void)
15245 #ifdef CONFIG_SCHEDSTATS
15246 create_seq_entry("schedstat", 0, &proc_schedstat_operations);
15247 #endif
15248-#ifdef CONFIG_PROC_KCORE
15249+#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
15250 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
15251 if (proc_root_kcore) {
15252 proc_root_kcore->proc_fops = &proc_kcore_operations;
15253diff -urNp linux-2.6.22.1/fs/proc/proc_sysctl.c linux-2.6.22.1/fs/proc/proc_sysctl.c
15254--- linux-2.6.22.1/fs/proc/proc_sysctl.c 2007-07-10 14:56:30.000000000 -0400
15255+++ linux-2.6.22.1/fs/proc/proc_sysctl.c 2007-08-02 11:09:15.000000000 -0400
15256@@ -7,6 +7,8 @@
15257 #include <linux/security.h>
15258 #include "internal.h"
15259
15260+extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
15261+
15262 static struct dentry_operations proc_sys_dentry_operations;
15263 static const struct file_operations proc_sys_file_operations;
15264 static struct inode_operations proc_sys_inode_operations;
15265@@ -151,6 +153,9 @@ static struct dentry *proc_sys_lookup(st
15266 if (!table)
15267 goto out;
15268
15269+ if (gr_handle_sysctl(table, 001))
15270+ goto out;
15271+
15272 err = ERR_PTR(-ENOMEM);
15273 inode = proc_sys_make_inode(dir, table);
15274 if (!inode)
15275@@ -358,6 +363,9 @@ static int proc_sys_readdir(struct file
15276 if (pos < filp->f_pos)
15277 continue;
15278
15279+ if (gr_handle_sysctl(table, 0))
15280+ continue;
15281+
15282 if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
15283 goto out;
15284 filp->f_pos = pos + 1;
15285@@ -420,6 +428,30 @@ out:
15286 return error;
15287 }
15288
15289+/* Eric Biederman is to blame */
15290+static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
15291+{
15292+ int error = 0;
15293+ struct ctl_table_header *head;
15294+ struct ctl_table *table;
15295+
15296+ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
15297+ /* Has the sysctl entry disappeared on us? */
15298+ if (!table)
15299+ goto out;
15300+
15301+ if (gr_handle_sysctl(table, 001)) {
15302+ error = -ENOENT;
15303+ goto out;
15304+ }
15305+
15306+out:
15307+ sysctl_head_finish(head);
15308+
15309+ generic_fillattr(dentry->d_inode, stat);
15310+
15311+ return error;
15312+}
15313 static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
15314 {
15315 struct inode *inode = dentry->d_inode;
15316@@ -448,6 +480,7 @@ static struct inode_operations proc_sys_
15317 .lookup = proc_sys_lookup,
15318 .permission = proc_sys_permission,
15319 .setattr = proc_sys_setattr,
15320+ .getattr = proc_sys_getattr,
15321 };
15322
15323 static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
15324diff -urNp linux-2.6.22.1/fs/proc/root.c linux-2.6.22.1/fs/proc/root.c
15325--- linux-2.6.22.1/fs/proc/root.c 2007-07-10 14:56:30.000000000 -0400
15326+++ linux-2.6.22.1/fs/proc/root.c 2007-08-02 11:09:15.000000000 -0400
15327@@ -64,7 +64,13 @@ void __init proc_root_init(void)
15328 return;
15329 }
15330 proc_misc_init();
15331+#ifdef CONFIG_GRKERNSEC_PROC_USER
15332+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
15333+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15334+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
15335+#else
15336 proc_net = proc_mkdir("net", NULL);
15337+#endif
15338 proc_net_stat = proc_mkdir("net/stat", NULL);
15339
15340 #ifdef CONFIG_SYSVIPC
15341@@ -78,7 +84,15 @@ void __init proc_root_init(void)
15342 #ifdef CONFIG_PROC_DEVICETREE
15343 proc_device_tree_init();
15344 #endif
15345+#ifdef CONFIG_GRKERNSEC_PROC_ADD
15346+#ifdef CONFIG_GRKERNSEC_PROC_USER
15347+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
15348+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
15349+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
15350+#endif
15351+#else
15352 proc_bus = proc_mkdir("bus", NULL);
15353+#endif
15354 proc_vx_init();
15355 proc_sys_init();
15356 }
15357diff -urNp linux-2.6.22.1/fs/proc/task_mmu.c linux-2.6.22.1/fs/proc/task_mmu.c
15358--- linux-2.6.22.1/fs/proc/task_mmu.c 2007-07-10 14:56:30.000000000 -0400
15359+++ linux-2.6.22.1/fs/proc/task_mmu.c 2007-08-02 11:38:47.000000000 -0400
15360@@ -44,15 +44,27 @@ char *task_mem(struct mm_struct *mm, cha
15361 "VmStk:\t%8lu kB\n"
15362 "VmExe:\t%8lu kB\n"
15363 "VmLib:\t%8lu kB\n"
15364- "VmPTE:\t%8lu kB\n",
15365- hiwater_vm << (PAGE_SHIFT-10),
15366+ "VmPTE:\t%8lu kB\n"
15367+
15368+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
15369+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
15370+#endif
15371+
15372+ ,hiwater_vm << (PAGE_SHIFT-10),
15373 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
15374 mm->locked_vm << (PAGE_SHIFT-10),
15375 hiwater_rss << (PAGE_SHIFT-10),
15376 total_rss << (PAGE_SHIFT-10),
15377 data << (PAGE_SHIFT-10),
15378 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
15379- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
15380+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
15381+
15382+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
15383+ , mm->context.user_cs_base, mm->context.user_cs_limit
15384+#endif
15385+
15386+ );
15387+
15388 return buffer;
15389 }
15390
15391@@ -131,6 +143,12 @@ struct pmd_walker {
15392 unsigned long, void *);
15393 };
15394
15395+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
15396+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
15397+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
15398+ _mm->pax_flags & MF_PAX_SEGMEXEC))
15399+#endif
15400+
15401 static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
15402 {
15403 struct proc_maps_private *priv = m->private;
15404@@ -153,13 +171,22 @@ static int show_map_internal(struct seq_
15405 }
15406
15407 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
15408+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
15409+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
15410+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
15411+#else
15412 vma->vm_start,
15413 vma->vm_end,
15414+#endif
15415 flags & VM_READ ? 'r' : '-',
15416 flags & VM_WRITE ? 'w' : '-',
15417 flags & VM_EXEC ? 'x' : '-',
15418 flags & VM_MAYSHARE ? 's' : 'p',
15419+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
15420+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
15421+#else
15422 vma->vm_pgoff << PAGE_SHIFT,
15423+#endif
15424 MAJOR(dev), MINOR(dev), ino, &len);
15425
15426 /*
15427@@ -173,11 +200,11 @@ static int show_map_internal(struct seq_
15428 const char *name = arch_vma_name(vma);
15429 if (!name) {
15430 if (mm) {
15431- if (vma->vm_start <= mm->start_brk &&
15432- vma->vm_end >= mm->brk) {
15433+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
15434 name = "[heap]";
15435- } else if (vma->vm_start <= mm->start_stack &&
15436- vma->vm_end >= mm->start_stack) {
15437+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
15438+ (vma->vm_start <= mm->start_stack &&
15439+ vma->vm_end >= mm->start_stack)) {
15440 name = "[stack]";
15441 }
15442 } else {
15443@@ -191,7 +218,27 @@ static int show_map_internal(struct seq_
15444 }
15445 seq_putc(m, '\n');
15446
15447- if (mss)
15448+
15449+ if (mss) {
15450+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
15451+ if (PAX_RAND_FLAGS(mm))
15452+ seq_printf(m,
15453+ "Size: %8lu kB\n"
15454+ "Rss: %8lu kB\n"
15455+ "Shared_Clean: %8lu kB\n"
15456+ "Shared_Dirty: %8lu kB\n"
15457+ "Private_Clean: %8lu kB\n"
15458+ "Private_Dirty: %8lu kB\n",
15459+ "Referenced: %8lu kB\n",
15460+ 0UL,
15461+ 0UL,
15462+ 0UL,
15463+ 0UL,
15464+ 0UL,
15465+ 0UL,
15466+ 0UL);
15467+ else
15468+#endif
15469 seq_printf(m,
15470 "Size: %8lu kB\n"
15471 "Rss: %8lu kB\n"
15472@@ -207,6 +254,7 @@ static int show_map_internal(struct seq_
15473 mss->private_clean >> 10,
15474 mss->private_dirty >> 10,
15475 mss->referenced >> 10);
15476+ }
15477
15478 if (m->count < m->size) /* vma is copied successfully */
15479 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
15480diff -urNp linux-2.6.22.1/fs/readdir.c linux-2.6.22.1/fs/readdir.c
15481--- linux-2.6.22.1/fs/readdir.c 2007-07-10 14:56:30.000000000 -0400
15482+++ linux-2.6.22.1/fs/readdir.c 2007-08-02 11:09:15.000000000 -0400
15483@@ -16,6 +16,8 @@
15484 #include <linux/security.h>
15485 #include <linux/syscalls.h>
15486 #include <linux/unistd.h>
15487+#include <linux/namei.h>
15488+#include <linux/grsecurity.h>
15489
15490 #include <asm/uaccess.h>
15491
15492@@ -64,6 +66,7 @@ struct old_linux_dirent {
15493
15494 struct readdir_callback {
15495 struct old_linux_dirent __user * dirent;
15496+ struct file * file;
15497 int result;
15498 };
15499
15500@@ -79,6 +82,10 @@ static int fillonedir(void * __buf, cons
15501 d_ino = ino;
15502 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
15503 return -EOVERFLOW;
15504+
15505+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
15506+ return 0;
15507+
15508 buf->result++;
15509 dirent = buf->dirent;
15510 if (!access_ok(VERIFY_WRITE, dirent,
15511@@ -110,6 +117,7 @@ asmlinkage long old_readdir(unsigned int
15512
15513 buf.result = 0;
15514 buf.dirent = dirent;
15515+ buf.file = file;
15516
15517 error = vfs_readdir(file, fillonedir, &buf);
15518 if (error >= 0)
15519@@ -136,6 +144,7 @@ struct linux_dirent {
15520 struct getdents_callback {
15521 struct linux_dirent __user * current_dir;
15522 struct linux_dirent __user * previous;
15523+ struct file * file;
15524 int count;
15525 int error;
15526 };
15527@@ -154,6 +163,10 @@ static int filldir(void * __buf, const c
15528 d_ino = ino;
15529 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
15530 return -EOVERFLOW;
15531+
15532+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
15533+ return 0;
15534+
15535 dirent = buf->previous;
15536 if (dirent) {
15537 if (__put_user(offset, &dirent->d_off))
15538@@ -200,6 +213,7 @@ asmlinkage long sys_getdents(unsigned in
15539 buf.previous = NULL;
15540 buf.count = count;
15541 buf.error = 0;
15542+ buf.file = file;
15543
15544 error = vfs_readdir(file, filldir, &buf);
15545 if (error < 0)
15546@@ -222,6 +236,7 @@ out:
15547 struct getdents_callback64 {
15548 struct linux_dirent64 __user * current_dir;
15549 struct linux_dirent64 __user * previous;
15550+ struct file *file;
15551 int count;
15552 int error;
15553 };
15554@@ -236,6 +251,10 @@ static int filldir64(void * __buf, const
15555 buf->error = -EINVAL; /* only used if we fail.. */
15556 if (reclen > buf->count)
15557 return -EINVAL;
15558+
15559+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
15560+ return 0;
15561+
15562 dirent = buf->previous;
15563 if (dirent) {
15564 if (__put_user(offset, &dirent->d_off))
15565@@ -282,6 +301,7 @@ asmlinkage long sys_getdents64(unsigned
15566
15567 buf.current_dir = dirent;
15568 buf.previous = NULL;
15569+ buf.file = file;
15570 buf.count = count;
15571 buf.error = 0;
15572
15573diff -urNp linux-2.6.22.1/fs/udf/balloc.c linux-2.6.22.1/fs/udf/balloc.c
15574--- linux-2.6.22.1/fs/udf/balloc.c 2007-07-10 14:56:30.000000000 -0400
15575+++ linux-2.6.22.1/fs/udf/balloc.c 2007-08-02 11:38:47.000000000 -0400
15576@@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
15577 unsigned long overflow;
15578
15579 mutex_lock(&sbi->s_alloc_mutex);
15580- if (bloc.logicalBlockNum < 0 ||
15581- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
15582+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
15583 {
15584 udf_debug("%d < %d || %d + %d > %d\n",
15585 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
15586@@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
15587 struct buffer_head *bh;
15588
15589 mutex_lock(&sbi->s_alloc_mutex);
15590- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
15591+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
15592 goto out;
15593
15594 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
15595@@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
15596 mutex_lock(&sbi->s_alloc_mutex);
15597
15598 repeat:
15599- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
15600+ if (goal >= UDF_SB_PARTLEN(sb, partition))
15601 goal = 0;
15602
15603 nr_groups = bitmap->s_nr_groups;
15604@@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
15605 int i;
15606
15607 mutex_lock(&sbi->s_alloc_mutex);
15608- if (bloc.logicalBlockNum < 0 ||
15609- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
15610+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
15611 {
15612 udf_debug("%d < %d || %d + %d > %d\n",
15613 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
15614@@ -679,7 +677,7 @@ static int udf_table_prealloc_blocks(str
15615 struct extent_position epos;
15616 int8_t etype = -1;
15617
15618- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
15619+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
15620 return 0;
15621
15622 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
15623@@ -758,7 +756,7 @@ static int udf_table_new_block(struct su
15624 return newblock;
15625
15626 mutex_lock(&sbi->s_alloc_mutex);
15627- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
15628+ if (goal >= UDF_SB_PARTLEN(sb, partition))
15629 goal = 0;
15630
15631 /* We search for the closest matching block to goal. If we find a exact hit,
15632diff -urNp linux-2.6.22.1/fs/udf/inode.c linux-2.6.22.1/fs/udf/inode.c
15633--- linux-2.6.22.1/fs/udf/inode.c 2007-07-10 14:56:30.000000000 -0400
15634+++ linux-2.6.22.1/fs/udf/inode.c 2007-08-02 11:38:47.000000000 -0400
15635@@ -311,9 +311,6 @@ static int udf_get_block(struct inode *i
15636
15637 lock_kernel();
15638
15639- if (block < 0)
15640- goto abort_negative;
15641-
15642 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
15643 {
15644 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
15645@@ -334,10 +331,6 @@ static int udf_get_block(struct inode *i
15646 abort:
15647 unlock_kernel();
15648 return err;
15649-
15650-abort_negative:
15651- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
15652- goto abort;
15653 }
15654
15655 static struct buffer_head *
15656diff -urNp linux-2.6.22.1/fs/ufs/inode.c linux-2.6.22.1/fs/ufs/inode.c
15657--- linux-2.6.22.1/fs/ufs/inode.c 2007-07-10 14:56:30.000000000 -0400
15658+++ linux-2.6.22.1/fs/ufs/inode.c 2007-08-02 11:38:47.000000000 -0400
15659@@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
15660
15661
15662 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
15663- if (i_block < 0) {
15664- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
15665- } else if (i_block < direct_blocks) {
15666+ if (i_block < direct_blocks) {
15667 offsets[n++] = i_block;
15668 } else if ((i_block -= direct_blocks) < indirect_blocks) {
15669 offsets[n++] = UFS_IND_BLOCK;
15670@@ -439,8 +437,6 @@ int ufs_getfrag_block(struct inode *inod
15671 lock_kernel();
15672
15673 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
15674- if (fragment < 0)
15675- goto abort_negative;
15676 if (fragment >
15677 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
15678 << uspi->s_fpbshift))
15679@@ -503,10 +499,6 @@ abort:
15680 unlock_kernel();
15681 return err;
15682
15683-abort_negative:
15684- ufs_warning(sb, "ufs_get_block", "block < 0");
15685- goto abort;
15686-
15687 abort_too_big:
15688 ufs_warning(sb, "ufs_get_block", "block > big");
15689 goto abort;
15690diff -urNp linux-2.6.22.1/fs/utimes.c linux-2.6.22.1/fs/utimes.c
15691--- linux-2.6.22.1/fs/utimes.c 2007-07-10 14:56:30.000000000 -0400
15692+++ linux-2.6.22.1/fs/utimes.c 2007-08-02 11:09:15.000000000 -0400
15693@@ -6,6 +6,7 @@
15694 #include <linux/utime.h>
15695 #include <linux/mount.h>
15696 #include <linux/vs_cowbl.h>
15697+#include <linux/grsecurity.h>
15698 #include <asm/uaccess.h>
15699 #include <asm/unistd.h>
15700
15701@@ -47,6 +48,7 @@ long do_utimes(int dfd, char __user *fil
15702 int error;
15703 struct nameidata nd;
15704 struct dentry *dentry;
15705+ struct vfsmount *mnt;
15706 struct inode *inode;
15707 struct iattr newattrs;
15708 struct file *f = NULL;
15709@@ -65,6 +67,7 @@ long do_utimes(int dfd, char __user *fil
15710 if (!f)
15711 goto out;
15712 dentry = f->f_path.dentry;
15713+ mnt = f->f_path.mnt;
15714 } else {
15715 error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
15716 if (error)
15717@@ -78,6 +81,7 @@ long do_utimes(int dfd, char __user *fil
15718 if (error)
15719 goto dput_and_out;
15720 dentry = nd.dentry;
15721+ mnt = nd.mnt;
15722 }
15723
15724 inode = dentry->d_inode;
15725@@ -117,6 +121,12 @@ long do_utimes(int dfd, char __user *fil
15726 }
15727 }
15728 }
15729+
15730+ if (!gr_acl_handle_utime(dentry, mnt)) {
15731+ error = -EACCES;
15732+ goto dput_and_out;
15733+ }
15734+
15735 mutex_lock(&inode->i_mutex);
15736 error = notify_change(dentry, &newattrs);
15737 mutex_unlock(&inode->i_mutex);
15738diff -urNp linux-2.6.22.1/fs/xfs/xfs_bmap.c linux-2.6.22.1/fs/xfs/xfs_bmap.c
15739--- linux-2.6.22.1/fs/xfs/xfs_bmap.c 2007-07-10 14:56:30.000000000 -0400
15740+++ linux-2.6.22.1/fs/xfs/xfs_bmap.c 2007-08-02 11:38:47.000000000 -0400
15741@@ -365,7 +365,7 @@ xfs_bmap_validate_ret(
15742 int nmap,
15743 int ret_nmap);
15744 #else
15745-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
15746+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
15747 #endif /* DEBUG */
15748
15749 #if defined(XFS_RW_TRACE)
15750diff -urNp linux-2.6.22.1/grsecurity/gracl_alloc.c linux-2.6.22.1/grsecurity/gracl_alloc.c
15751--- linux-2.6.22.1/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
15752+++ linux-2.6.22.1/grsecurity/gracl_alloc.c 2007-08-02 11:09:15.000000000 -0400
15753@@ -0,0 +1,91 @@
15754+#include <linux/kernel.h>
15755+#include <linux/mm.h>
15756+#include <linux/slab.h>
15757+#include <linux/vmalloc.h>
15758+#include <linux/gracl.h>
15759+#include <linux/grsecurity.h>
15760+
15761+static unsigned long alloc_stack_next = 1;
15762+static unsigned long alloc_stack_size = 1;
15763+static void **alloc_stack;
15764+
15765+static __inline__ int
15766+alloc_pop(void)
15767+{
15768+ if (alloc_stack_next == 1)
15769+ return 0;
15770+
15771+ kfree(alloc_stack[alloc_stack_next - 2]);
15772+
15773+ alloc_stack_next--;
15774+
15775+ return 1;
15776+}
15777+
15778+static __inline__ void
15779+alloc_push(void *buf)
15780+{
15781+ if (alloc_stack_next >= alloc_stack_size)
15782+ BUG();
15783+
15784+ alloc_stack[alloc_stack_next - 1] = buf;
15785+
15786+ alloc_stack_next++;
15787+
15788+ return;
15789+}
15790+
15791+void *
15792+acl_alloc(unsigned long len)
15793+{
15794+ void *ret;
15795+
15796+ if (len > PAGE_SIZE)
15797+ BUG();
15798+
15799+ ret = kmalloc(len, GFP_KERNEL);
15800+
15801+ if (ret)
15802+ alloc_push(ret);
15803+
15804+ return ret;
15805+}
15806+
15807+void
15808+acl_free_all(void)
15809+{
15810+ if (gr_acl_is_enabled() || !alloc_stack)
15811+ return;
15812+
15813+ while (alloc_pop()) ;
15814+
15815+ if (alloc_stack) {
15816+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
15817+ kfree(alloc_stack);
15818+ else
15819+ vfree(alloc_stack);
15820+ }
15821+
15822+ alloc_stack = NULL;
15823+ alloc_stack_size = 1;
15824+ alloc_stack_next = 1;
15825+
15826+ return;
15827+}
15828+
15829+int
15830+acl_alloc_stack_init(unsigned long size)
15831+{
15832+ if ((size * sizeof (void *)) <= PAGE_SIZE)
15833+ alloc_stack =
15834+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
15835+ else
15836+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
15837+
15838+ alloc_stack_size = size;
15839+
15840+ if (!alloc_stack)
15841+ return 0;
15842+ else
15843+ return 1;
15844+}
15845diff -urNp linux-2.6.22.1/grsecurity/gracl.c linux-2.6.22.1/grsecurity/gracl.c
15846--- linux-2.6.22.1/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
15847+++ linux-2.6.22.1/grsecurity/gracl.c 2007-08-03 10:51:44.000000000 -0400
15848@@ -0,0 +1,3675 @@
15849+#include <linux/kernel.h>
15850+#include <linux/module.h>
15851+#include <linux/sched.h>
15852+#include <linux/mm.h>
15853+#include <linux/file.h>
15854+#include <linux/fs.h>
15855+#include <linux/namei.h>
15856+#include <linux/mount.h>
15857+#include <linux/tty.h>
15858+#include <linux/proc_fs.h>
15859+#include <linux/smp_lock.h>
15860+#include <linux/slab.h>
15861+#include <linux/vmalloc.h>
15862+#include <linux/types.h>
15863+#include <linux/capability.h>
15864+#include <linux/sysctl.h>
15865+#include <linux/netdevice.h>
15866+#include <linux/ptrace.h>
15867+#include <linux/gracl.h>
15868+#include <linux/gralloc.h>
15869+#include <linux/grsecurity.h>
15870+#include <linux/grinternal.h>
15871+#include <linux/pid_namespace.h>
15872+#include <linux/percpu.h>
15873+
15874+#include <asm/uaccess.h>
15875+#include <asm/errno.h>
15876+#include <asm/mman.h>
15877+
15878+static struct acl_role_db acl_role_set;
15879+static struct name_db name_set;
15880+static struct inodev_db inodev_set;
15881+
15882+/* for keeping track of userspace pointers used for subjects, so we
15883+ can share references in the kernel as well
15884+*/
15885+
15886+static struct dentry *real_root;
15887+static struct vfsmount *real_root_mnt;
15888+
15889+static struct acl_subj_map_db subj_map_set;
15890+
15891+static struct acl_role_label *default_role;
15892+
15893+static u16 acl_sp_role_value;
15894+
15895+extern char *gr_shared_page[4];
15896+static DECLARE_MUTEX(gr_dev_sem);
15897+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
15898+
15899+struct gr_arg *gr_usermode;
15900+
15901+static unsigned int gr_status = GR_STATUS_INIT;
15902+
15903+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
15904+extern void gr_clear_learn_entries(void);
15905+
15906+#ifdef CONFIG_GRKERNSEC_RESLOG
15907+extern void gr_log_resource(const struct task_struct *task,
15908+ const int res, const unsigned long wanted, const int gt);
15909+#endif
15910+
15911+unsigned char *gr_system_salt;
15912+unsigned char *gr_system_sum;
15913+
15914+static struct sprole_pw **acl_special_roles = NULL;
15915+static __u16 num_sprole_pws = 0;
15916+
15917+static struct acl_role_label *kernel_role = NULL;
15918+
15919+static unsigned int gr_auth_attempts = 0;
15920+static unsigned long gr_auth_expires = 0UL;
15921+
15922+extern struct vfsmount *sock_mnt;
15923+extern struct vfsmount *pipe_mnt;
15924+extern struct vfsmount *shm_mnt;
15925+static struct acl_object_label *fakefs_obj;
15926+
15927+extern int gr_init_uidset(void);
15928+extern void gr_free_uidset(void);
15929+extern void gr_remove_uid(uid_t uid);
15930+extern int gr_find_uid(uid_t uid);
15931+
15932+__inline__ int
15933+gr_acl_is_enabled(void)
15934+{
15935+ return (gr_status & GR_READY);
15936+}
15937+
15938+char gr_roletype_to_char(void)
15939+{
15940+ switch (current->role->roletype &
15941+ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
15942+ GR_ROLE_SPECIAL)) {
15943+ case GR_ROLE_DEFAULT:
15944+ return 'D';
15945+ case GR_ROLE_USER:
15946+ return 'U';
15947+ case GR_ROLE_GROUP:
15948+ return 'G';
15949+ case GR_ROLE_SPECIAL:
15950+ return 'S';
15951+ }
15952+
15953+ return 'X';
15954+}
15955+
15956+__inline__ int
15957+gr_acl_tpe_check(void)
15958+{
15959+ if (unlikely(!(gr_status & GR_READY)))
15960+ return 0;
15961+ if (current->role->roletype & GR_ROLE_TPE)
15962+ return 1;
15963+ else
15964+ return 0;
15965+}
15966+
15967+int
15968+gr_handle_rawio(const struct inode *inode)
15969+{
15970+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
15971+ if (inode && S_ISBLK(inode->i_mode) &&
15972+ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
15973+ !capable(CAP_SYS_RAWIO))
15974+ return 1;
15975+#endif
15976+ return 0;
15977+}
15978+
15979+static int
15980+gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
15981+{
15982+ int i;
15983+ unsigned long *l1;
15984+ unsigned long *l2;
15985+ unsigned char *c1;
15986+ unsigned char *c2;
15987+ int num_longs;
15988+
15989+ if (likely(lena != lenb))
15990+ return 0;
15991+
15992+ l1 = (unsigned long *)a;
15993+ l2 = (unsigned long *)b;
15994+
15995+ num_longs = lena / sizeof(unsigned long);
15996+
15997+ for (i = num_longs; i--; l1++, l2++) {
15998+ if (unlikely(*l1 != *l2))
15999+ return 0;
16000+ }
16001+
16002+ c1 = (unsigned char *) l1;
16003+ c2 = (unsigned char *) l2;
16004+
16005+ i = lena - (num_longs * sizeof(unsigned long));
16006+
16007+ for (; i--; c1++, c2++) {
16008+ if (unlikely(*c1 != *c2))
16009+ return 0;
16010+ }
16011+
16012+ return 1;
16013+}
16014+
16015+static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
16016+ struct dentry *root, struct vfsmount *rootmnt,
16017+ char *buffer, int buflen)
16018+{
16019+ char * end = buffer+buflen;
16020+ char * retval;
16021+ int namelen;
16022+
16023+ *--end = '\0';
16024+ buflen--;
16025+
16026+ if (buflen < 1)
16027+ goto Elong;
16028+ /* Get '/' right */
16029+ retval = end-1;
16030+ *retval = '/';
16031+
16032+ for (;;) {
16033+ struct dentry * parent;
16034+
16035+ if (dentry == root && vfsmnt == rootmnt)
16036+ break;
16037+ if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
16038+ /* Global root? */
16039+ spin_lock(&vfsmount_lock);
16040+ if (vfsmnt->mnt_parent == vfsmnt) {
16041+ spin_unlock(&vfsmount_lock);
16042+ goto global_root;
16043+ }
16044+ dentry = vfsmnt->mnt_mountpoint;
16045+ vfsmnt = vfsmnt->mnt_parent;
16046+ spin_unlock(&vfsmount_lock);
16047+ continue;
16048+ }
16049+ parent = dentry->d_parent;
16050+ prefetch(parent);
16051+ namelen = dentry->d_name.len;
16052+ buflen -= namelen + 1;
16053+ if (buflen < 0)
16054+ goto Elong;
16055+ end -= namelen;
16056+ memcpy(end, dentry->d_name.name, namelen);
16057+ *--end = '/';
16058+ retval = end;
16059+ dentry = parent;
16060+ }
16061+
16062+ return retval;
16063+
16064+global_root:
16065+ namelen = dentry->d_name.len;
16066+ buflen -= namelen;
16067+ if (buflen < 0)
16068+ goto Elong;
16069+ retval -= namelen-1; /* hit the slash */
16070+ memcpy(retval, dentry->d_name.name, namelen);
16071+ return retval;
16072+Elong:
16073+ return ERR_PTR(-ENAMETOOLONG);
16074+}
16075+
16076+static char *
16077+gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
16078+ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
16079+{
16080+ char *retval;
16081+
16082+ retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
16083+ if (unlikely(IS_ERR(retval)))
16084+ retval = strcpy(buf, "<path too long>");
16085+ else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
16086+ retval[1] = '\0';
16087+
16088+ return retval;
16089+}
16090+
16091+static char *
16092+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
16093+ char *buf, int buflen)
16094+{
16095+ char *res;
16096+
16097+ /* we can use real_root, real_root_mnt, because this is only called
16098+ by the RBAC system */
16099+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
16100+
16101+ return res;
16102+}
16103+
16104+static char *
16105+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
16106+ char *buf, int buflen)
16107+{
16108+ char *res;
16109+ struct dentry *root;
16110+ struct vfsmount *rootmnt;
16111+ struct task_struct *reaper = child_reaper(current);
16112+
16113+ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
16114+ read_lock(&reaper->fs->lock);
16115+ root = dget(reaper->fs->root);
16116+ rootmnt = mntget(reaper->fs->rootmnt);
16117+ read_unlock(&reaper->fs->lock);
16118+
16119+ spin_lock(&dcache_lock);
16120+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
16121+ spin_unlock(&dcache_lock);
16122+
16123+ dput(root);
16124+ mntput(rootmnt);
16125+ return res;
16126+}
16127+
16128+static char *
16129+gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
16130+{
16131+ char *ret;
16132+ spin_lock(&dcache_lock);
16133+ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
16134+ PAGE_SIZE);
16135+ spin_unlock(&dcache_lock);
16136+ return ret;
16137+}
16138+
16139+char *
16140+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
16141+{
16142+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
16143+ PAGE_SIZE);
16144+}
16145+
16146+char *
16147+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
16148+{
16149+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
16150+ PAGE_SIZE);
16151+}
16152+
16153+char *
16154+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
16155+{
16156+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
16157+ PAGE_SIZE);
16158+}
16159+
16160+char *
16161+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
16162+{
16163+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
16164+ PAGE_SIZE);
16165+}
16166+
16167+char *
16168+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
16169+{
16170+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
16171+ PAGE_SIZE);
16172+}
16173+
16174+__inline__ __u32
16175+to_gr_audit(const __u32 reqmode)
16176+{
16177+ /* masks off auditable permission flags, then shifts them to create
16178+ auditing flags, and adds the special case of append auditing if
16179+ we're requesting write */
16180+ return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
16181+}
16182+
16183+struct acl_subject_label *
16184+lookup_subject_map(const struct acl_subject_label *userp)
16185+{
16186+ unsigned int index = shash(userp, subj_map_set.s_size);
16187+ struct subject_map *match;
16188+
16189+ match = subj_map_set.s_hash[index];
16190+
16191+ while (match && match->user != userp)
16192+ match = match->next;
16193+
16194+ if (match != NULL)
16195+ return match->kernel;
16196+ else
16197+ return NULL;
16198+}
16199+
16200+static void
16201+insert_subj_map_entry(struct subject_map *subjmap)
16202+{
16203+ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
16204+ struct subject_map **curr;
16205+
16206+ subjmap->prev = NULL;
16207+
16208+ curr = &subj_map_set.s_hash[index];
16209+ if (*curr != NULL)
16210+ (*curr)->prev = subjmap;
16211+
16212+ subjmap->next = *curr;
16213+ *curr = subjmap;
16214+
16215+ return;
16216+}
16217+
16218+static struct acl_role_label *
16219+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
16220+ const gid_t gid)
16221+{
16222+ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
16223+ struct acl_role_label *match;
16224+ struct role_allowed_ip *ipp;
16225+ unsigned int x;
16226+
16227+ match = acl_role_set.r_hash[index];
16228+
16229+ while (match) {
16230+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
16231+ for (x = 0; x < match->domain_child_num; x++) {
16232+ if (match->domain_children[x] == uid)
16233+ goto found;
16234+ }
16235+ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
16236+ break;
16237+ match = match->next;
16238+ }
16239+found:
16240+ if (match == NULL) {
16241+ try_group:
16242+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
16243+ match = acl_role_set.r_hash[index];
16244+
16245+ while (match) {
16246+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
16247+ for (x = 0; x < match->domain_child_num; x++) {
16248+ if (match->domain_children[x] == gid)
16249+ goto found2;
16250+ }
16251+ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
16252+ break;
16253+ match = match->next;
16254+ }
16255+found2:
16256+ if (match == NULL)
16257+ match = default_role;
16258+ if (match->allowed_ips == NULL)
16259+ return match;
16260+ else {
16261+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
16262+ if (likely
16263+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
16264+ (ntohl(ipp->addr) & ipp->netmask)))
16265+ return match;
16266+ }
16267+ match = default_role;
16268+ }
16269+ } else if (match->allowed_ips == NULL) {
16270+ return match;
16271+ } else {
16272+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
16273+ if (likely
16274+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
16275+ (ntohl(ipp->addr) & ipp->netmask)))
16276+ return match;
16277+ }
16278+ goto try_group;
16279+ }
16280+
16281+ return match;
16282+}
16283+
16284+struct acl_subject_label *
16285+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
16286+ const struct acl_role_label *role)
16287+{
16288+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
16289+ struct acl_subject_label *match;
16290+
16291+ match = role->subj_hash[index];
16292+
16293+ while (match && (match->inode != ino || match->device != dev ||
16294+ (match->mode & GR_DELETED))) {
16295+ match = match->next;
16296+ }
16297+
16298+ if (match && !(match->mode & GR_DELETED))
16299+ return match;
16300+ else
16301+ return NULL;
16302+}
16303+
16304+static struct acl_object_label *
16305+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
16306+ const struct acl_subject_label *subj)
16307+{
16308+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
16309+ struct acl_object_label *match;
16310+
16311+ match = subj->obj_hash[index];
16312+
16313+ while (match && (match->inode != ino || match->device != dev ||
16314+ (match->mode & GR_DELETED))) {
16315+ match = match->next;
16316+ }
16317+
16318+ if (match && !(match->mode & GR_DELETED))
16319+ return match;
16320+ else
16321+ return NULL;
16322+}
16323+
16324+static struct acl_object_label *
16325+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
16326+ const struct acl_subject_label *subj)
16327+{
16328+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
16329+ struct acl_object_label *match;
16330+
16331+ match = subj->obj_hash[index];
16332+
16333+ while (match && (match->inode != ino || match->device != dev ||
16334+ !(match->mode & GR_DELETED))) {
16335+ match = match->next;
16336+ }
16337+
16338+ if (match && (match->mode & GR_DELETED))
16339+ return match;
16340+
16341+ match = subj->obj_hash[index];
16342+
16343+ while (match && (match->inode != ino || match->device != dev ||
16344+ (match->mode & GR_DELETED))) {
16345+ match = match->next;
16346+ }
16347+
16348+ if (match && !(match->mode & GR_DELETED))
16349+ return match;
16350+ else
16351+ return NULL;
16352+}
16353+
16354+static struct name_entry *
16355+lookup_name_entry(const char *name)
16356+{
16357+ unsigned int len = strlen(name);
16358+ unsigned int key = full_name_hash(name, len);
16359+ unsigned int index = key % name_set.n_size;
16360+ struct name_entry *match;
16361+
16362+ match = name_set.n_hash[index];
16363+
16364+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
16365+ match = match->next;
16366+
16367+ return match;
16368+}
16369+
16370+static struct inodev_entry *
16371+lookup_inodev_entry(const ino_t ino, const dev_t dev)
16372+{
16373+ unsigned int index = fhash(ino, dev, inodev_set.i_size);
16374+ struct inodev_entry *match;
16375+
16376+ match = inodev_set.i_hash[index];
16377+
16378+ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
16379+ match = match->next;
16380+
16381+ return match;
16382+}
16383+
16384+static void
16385+insert_inodev_entry(struct inodev_entry *entry)
16386+{
16387+ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
16388+ inodev_set.i_size);
16389+ struct inodev_entry **curr;
16390+
16391+ entry->prev = NULL;
16392+
16393+ curr = &inodev_set.i_hash[index];
16394+ if (*curr != NULL)
16395+ (*curr)->prev = entry;
16396+
16397+ entry->next = *curr;
16398+ *curr = entry;
16399+
16400+ return;
16401+}
16402+
16403+static void
16404+__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
16405+{
16406+ unsigned int index =
16407+ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
16408+ struct acl_role_label **curr;
16409+
16410+ role->prev = NULL;
16411+
16412+ curr = &acl_role_set.r_hash[index];
16413+ if (*curr != NULL)
16414+ (*curr)->prev = role;
16415+
16416+ role->next = *curr;
16417+ *curr = role;
16418+
16419+ return;
16420+}
16421+
16422+static void
16423+insert_acl_role_label(struct acl_role_label *role)
16424+{
16425+ int i;
16426+
16427+ if (role->roletype & GR_ROLE_DOMAIN) {
16428+ for (i = 0; i < role->domain_child_num; i++)
16429+ __insert_acl_role_label(role, role->domain_children[i]);
16430+ } else
16431+ __insert_acl_role_label(role, role->uidgid);
16432+}
16433+
16434+static int
16435+insert_name_entry(char *name, const ino_t inode, const dev_t device)
16436+{
16437+ struct name_entry **curr, *nentry;
16438+ struct inodev_entry *ientry;
16439+ unsigned int len = strlen(name);
16440+ unsigned int key = full_name_hash(name, len);
16441+ unsigned int index = key % name_set.n_size;
16442+
16443+ curr = &name_set.n_hash[index];
16444+
16445+ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
16446+ curr = &((*curr)->next);
16447+
16448+ if (*curr != NULL)
16449+ return 1;
16450+
16451+ nentry = acl_alloc(sizeof (struct name_entry));
16452+ if (nentry == NULL)
16453+ return 0;
16454+ ientry = acl_alloc(sizeof (struct inodev_entry));
16455+ if (ientry == NULL)
16456+ return 0;
16457+ ientry->nentry = nentry;
16458+
16459+ nentry->key = key;
16460+ nentry->name = name;
16461+ nentry->inode = inode;
16462+ nentry->device = device;
16463+ nentry->len = len;
16464+
16465+ nentry->prev = NULL;
16466+ curr = &name_set.n_hash[index];
16467+ if (*curr != NULL)
16468+ (*curr)->prev = nentry;
16469+ nentry->next = *curr;
16470+ *curr = nentry;
16471+
16472+ /* insert us into the table searchable by inode/dev */
16473+ insert_inodev_entry(ientry);
16474+
16475+ return 1;
16476+}
16477+
16478+static void
16479+insert_acl_obj_label(struct acl_object_label *obj,
16480+ struct acl_subject_label *subj)
16481+{
16482+ unsigned int index =
16483+ fhash(obj->inode, obj->device, subj->obj_hash_size);
16484+ struct acl_object_label **curr;
16485+
16486+
16487+ obj->prev = NULL;
16488+
16489+ curr = &subj->obj_hash[index];
16490+ if (*curr != NULL)
16491+ (*curr)->prev = obj;
16492+
16493+ obj->next = *curr;
16494+ *curr = obj;
16495+
16496+ return;
16497+}
16498+
16499+static void
16500+insert_acl_subj_label(struct acl_subject_label *obj,
16501+ struct acl_role_label *role)
16502+{
16503+ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
16504+ struct acl_subject_label **curr;
16505+
16506+ obj->prev = NULL;
16507+
16508+ curr = &role->subj_hash[index];
16509+ if (*curr != NULL)
16510+ (*curr)->prev = obj;
16511+
16512+ obj->next = *curr;
16513+ *curr = obj;
16514+
16515+ return;
16516+}
16517+
16518+/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
16519+
16520+static void *
16521+create_table(__u32 * len, int elementsize)
16522+{
16523+ unsigned int table_sizes[] = {
16524+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
16525+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
16526+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
16527+ 268435399, 536870909, 1073741789, 2147483647
16528+ };
16529+ void *newtable = NULL;
16530+ unsigned int pwr = 0;
16531+
16532+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
16533+ table_sizes[pwr] <= *len)
16534+ pwr++;
16535+
16536+ if (table_sizes[pwr] <= *len)
16537+ return newtable;
16538+
16539+ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
16540+ newtable =
16541+ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
16542+ else
16543+ newtable = vmalloc(table_sizes[pwr] * elementsize);
16544+
16545+ *len = table_sizes[pwr];
16546+
16547+ return newtable;
16548+}
16549+
16550+static int
16551+init_variables(const struct gr_arg *arg)
16552+{
16553+ struct task_struct *reaper = child_reaper(current);
16554+ unsigned int stacksize;
16555+
16556+ subj_map_set.s_size = arg->role_db.num_subjects;
16557+ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
16558+ name_set.n_size = arg->role_db.num_objects;
16559+ inodev_set.i_size = arg->role_db.num_objects;
16560+
16561+ if (!subj_map_set.s_size || !acl_role_set.r_size ||
16562+ !name_set.n_size || !inodev_set.i_size)
16563+ return 1;
16564+
16565+ if (!gr_init_uidset())
16566+ return 1;
16567+
16568+ /* set up the stack that holds allocation info */
16569+
16570+ stacksize = arg->role_db.num_pointers + 5;
16571+
16572+ if (!acl_alloc_stack_init(stacksize))
16573+ return 1;
16574+
16575+ /* grab reference for the real root dentry and vfsmount */
16576+ read_lock(&reaper->fs->lock);
16577+ real_root_mnt = mntget(reaper->fs->rootmnt);
16578+ real_root = dget(reaper->fs->root);
16579+ read_unlock(&reaper->fs->lock);
16580+
16581+ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
16582+ if (fakefs_obj == NULL)
16583+ return 1;
16584+ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
16585+
16586+ subj_map_set.s_hash =
16587+ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
16588+ acl_role_set.r_hash =
16589+ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
16590+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
16591+ inodev_set.i_hash =
16592+ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
16593+
16594+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
16595+ !name_set.n_hash || !inodev_set.i_hash)
16596+ return 1;
16597+
16598+ memset(subj_map_set.s_hash, 0,
16599+ sizeof(struct subject_map *) * subj_map_set.s_size);
16600+ memset(acl_role_set.r_hash, 0,
16601+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
16602+ memset(name_set.n_hash, 0,
16603+ sizeof (struct name_entry *) * name_set.n_size);
16604+ memset(inodev_set.i_hash, 0,
16605+ sizeof (struct inodev_entry *) * inodev_set.i_size);
16606+
16607+ return 0;
16608+}
16609+
16610+/* free information not needed after startup
16611+ currently contains user->kernel pointer mappings for subjects
16612+*/
16613+
16614+static void
16615+free_init_variables(void)
16616+{
16617+ __u32 i;
16618+
16619+ if (subj_map_set.s_hash) {
16620+ for (i = 0; i < subj_map_set.s_size; i++) {
16621+ if (subj_map_set.s_hash[i]) {
16622+ kfree(subj_map_set.s_hash[i]);
16623+ subj_map_set.s_hash[i] = NULL;
16624+ }
16625+ }
16626+
16627+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
16628+ PAGE_SIZE)
16629+ kfree(subj_map_set.s_hash);
16630+ else
16631+ vfree(subj_map_set.s_hash);
16632+ }
16633+
16634+ return;
16635+}
16636+
16637+static void
16638+free_variables(void)
16639+{
16640+ struct acl_subject_label *s;
16641+ struct acl_role_label *r;
16642+ struct task_struct *task, *task2;
16643+ unsigned int i, x;
16644+
16645+ gr_clear_learn_entries();
16646+
16647+ read_lock(&tasklist_lock);
16648+ do_each_thread(task2, task) {
16649+ task->acl_sp_role = 0;
16650+ task->acl_role_id = 0;
16651+ task->acl = NULL;
16652+ task->role = NULL;
16653+ } while_each_thread(task2, task);
16654+ read_unlock(&tasklist_lock);
16655+
16656+ /* release the reference to the real root dentry and vfsmount */
16657+ if (real_root)
16658+ dput(real_root);
16659+ real_root = NULL;
16660+ if (real_root_mnt)
16661+ mntput(real_root_mnt);
16662+ real_root_mnt = NULL;
16663+
16664+ /* free all object hash tables */
16665+
16666+ FOR_EACH_ROLE_START(r, i)
16667+ if (r->subj_hash == NULL)
16668+ break;
16669+ FOR_EACH_SUBJECT_START(r, s, x)
16670+ if (s->obj_hash == NULL)
16671+ break;
16672+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
16673+ kfree(s->obj_hash);
16674+ else
16675+ vfree(s->obj_hash);
16676+ FOR_EACH_SUBJECT_END(s, x)
16677+ FOR_EACH_NESTED_SUBJECT_START(r, s)
16678+ if (s->obj_hash == NULL)
16679+ break;
16680+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
16681+ kfree(s->obj_hash);
16682+ else
16683+ vfree(s->obj_hash);
16684+ FOR_EACH_NESTED_SUBJECT_END(s)
16685+ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
16686+ kfree(r->subj_hash);
16687+ else
16688+ vfree(r->subj_hash);
16689+ r->subj_hash = NULL;
16690+ FOR_EACH_ROLE_END(r,i)
16691+
16692+ acl_free_all();
16693+
16694+ if (acl_role_set.r_hash) {
16695+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
16696+ PAGE_SIZE)
16697+ kfree(acl_role_set.r_hash);
16698+ else
16699+ vfree(acl_role_set.r_hash);
16700+ }
16701+ if (name_set.n_hash) {
16702+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
16703+ PAGE_SIZE)
16704+ kfree(name_set.n_hash);
16705+ else
16706+ vfree(name_set.n_hash);
16707+ }
16708+
16709+ if (inodev_set.i_hash) {
16710+ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
16711+ PAGE_SIZE)
16712+ kfree(inodev_set.i_hash);
16713+ else
16714+ vfree(inodev_set.i_hash);
16715+ }
16716+
16717+ gr_free_uidset();
16718+
16719+ memset(&name_set, 0, sizeof (struct name_db));
16720+ memset(&inodev_set, 0, sizeof (struct inodev_db));
16721+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
16722+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
16723+
16724+ default_role = NULL;
16725+
16726+ return;
16727+}
16728+
16729+static __u32
16730+count_user_objs(struct acl_object_label *userp)
16731+{
16732+ struct acl_object_label o_tmp;
16733+ __u32 num = 0;
16734+
16735+ while (userp) {
16736+ if (copy_from_user(&o_tmp, userp,
16737+ sizeof (struct acl_object_label)))
16738+ break;
16739+
16740+ userp = o_tmp.prev;
16741+ num++;
16742+ }
16743+
16744+ return num;
16745+}
16746+
16747+static struct acl_subject_label *
16748+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
16749+
16750+static int
16751+copy_user_glob(struct acl_object_label *obj)
16752+{
16753+ struct acl_object_label *g_tmp, **guser;
16754+ unsigned int len;
16755+ char *tmp;
16756+
16757+ if (obj->globbed == NULL)
16758+ return 0;
16759+
16760+ guser = &obj->globbed;
16761+ while (*guser) {
16762+ g_tmp = (struct acl_object_label *)
16763+ acl_alloc(sizeof (struct acl_object_label));
16764+ if (g_tmp == NULL)
16765+ return -ENOMEM;
16766+
16767+ if (copy_from_user(g_tmp, *guser,
16768+ sizeof (struct acl_object_label)))
16769+ return -EFAULT;
16770+
16771+ len = strnlen_user(g_tmp->filename, PATH_MAX);
16772+
16773+ if (!len || len >= PATH_MAX)
16774+ return -EINVAL;
16775+
16776+ if ((tmp = (char *) acl_alloc(len)) == NULL)
16777+ return -ENOMEM;
16778+
16779+ if (copy_from_user(tmp, g_tmp->filename, len))
16780+ return -EFAULT;
16781+
16782+ g_tmp->filename = tmp;
16783+
16784+ *guser = g_tmp;
16785+ guser = &(g_tmp->next);
16786+ }
16787+
16788+ return 0;
16789+}
16790+
16791+static int
16792+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
16793+ struct acl_role_label *role)
16794+{
16795+ struct acl_object_label *o_tmp;
16796+ unsigned int len;
16797+ int ret;
16798+ char *tmp;
16799+
16800+ while (userp) {
16801+ if ((o_tmp = (struct acl_object_label *)
16802+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
16803+ return -ENOMEM;
16804+
16805+ if (copy_from_user(o_tmp, userp,
16806+ sizeof (struct acl_object_label)))
16807+ return -EFAULT;
16808+
16809+ userp = o_tmp->prev;
16810+
16811+ len = strnlen_user(o_tmp->filename, PATH_MAX);
16812+
16813+ if (!len || len >= PATH_MAX)
16814+ return -EINVAL;
16815+
16816+ if ((tmp = (char *) acl_alloc(len)) == NULL)
16817+ return -ENOMEM;
16818+
16819+ if (copy_from_user(tmp, o_tmp->filename, len))
16820+ return -EFAULT;
16821+
16822+ o_tmp->filename = tmp;
16823+
16824+ insert_acl_obj_label(o_tmp, subj);
16825+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
16826+ o_tmp->device))
16827+ return -ENOMEM;
16828+
16829+ ret = copy_user_glob(o_tmp);
16830+ if (ret)
16831+ return ret;
16832+
16833+ if (o_tmp->nested) {
16834+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
16835+ if (IS_ERR(o_tmp->nested))
16836+ return PTR_ERR(o_tmp->nested);
16837+
16838+ /* insert into nested subject list */
16839+ o_tmp->nested->next = role->hash->first;
16840+ role->hash->first = o_tmp->nested;
16841+ }
16842+ }
16843+
16844+ return 0;
16845+}
16846+
16847+static __u32
16848+count_user_subjs(struct acl_subject_label *userp)
16849+{
16850+ struct acl_subject_label s_tmp;
16851+ __u32 num = 0;
16852+
16853+ while (userp) {
16854+ if (copy_from_user(&s_tmp, userp,
16855+ sizeof (struct acl_subject_label)))
16856+ break;
16857+
16858+ userp = s_tmp.prev;
16859+ /* do not count nested subjects against this count, since
16860+ they are not included in the hash table, but are
16861+ attached to objects. We have already counted
16862+ the subjects in userspace for the allocation
16863+ stack
16864+ */
16865+ if (!(s_tmp.mode & GR_NESTED))
16866+ num++;
16867+ }
16868+
16869+ return num;
16870+}
16871+
16872+static int
16873+copy_user_allowedips(struct acl_role_label *rolep)
16874+{
16875+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
16876+
16877+ ruserip = rolep->allowed_ips;
16878+
16879+ while (ruserip) {
16880+ rlast = rtmp;
16881+
16882+ if ((rtmp = (struct role_allowed_ip *)
16883+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
16884+ return -ENOMEM;
16885+
16886+ if (copy_from_user(rtmp, ruserip,
16887+ sizeof (struct role_allowed_ip)))
16888+ return -EFAULT;
16889+
16890+ ruserip = rtmp->prev;
16891+
16892+ if (!rlast) {
16893+ rtmp->prev = NULL;
16894+ rolep->allowed_ips = rtmp;
16895+ } else {
16896+ rlast->next = rtmp;
16897+ rtmp->prev = rlast;
16898+ }
16899+
16900+ if (!ruserip)
16901+ rtmp->next = NULL;
16902+ }
16903+
16904+ return 0;
16905+}
16906+
16907+static int
16908+copy_user_transitions(struct acl_role_label *rolep)
16909+{
16910+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
16911+
16912+ unsigned int len;
16913+ char *tmp;
16914+
16915+ rusertp = rolep->transitions;
16916+
16917+ while (rusertp) {
16918+ rlast = rtmp;
16919+
16920+ if ((rtmp = (struct role_transition *)
16921+ acl_alloc(sizeof (struct role_transition))) == NULL)
16922+ return -ENOMEM;
16923+
16924+ if (copy_from_user(rtmp, rusertp,
16925+ sizeof (struct role_transition)))
16926+ return -EFAULT;
16927+
16928+ rusertp = rtmp->prev;
16929+
16930+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
16931+
16932+ if (!len || len >= GR_SPROLE_LEN)
16933+ return -EINVAL;
16934+
16935+ if ((tmp = (char *) acl_alloc(len)) == NULL)
16936+ return -ENOMEM;
16937+
16938+ if (copy_from_user(tmp, rtmp->rolename, len))
16939+ return -EFAULT;
16940+
16941+ rtmp->rolename = tmp;
16942+
16943+ if (!rlast) {
16944+ rtmp->prev = NULL;
16945+ rolep->transitions = rtmp;
16946+ } else {
16947+ rlast->next = rtmp;
16948+ rtmp->prev = rlast;
16949+ }
16950+
16951+ if (!rusertp)
16952+ rtmp->next = NULL;
16953+ }
16954+
16955+ return 0;
16956+}
16957+
16958+static struct acl_subject_label *
16959+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
16960+{
16961+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
16962+ unsigned int len;
16963+ char *tmp;
16964+ __u32 num_objs;
16965+ struct acl_ip_label **i_tmp, *i_utmp2;
16966+ struct gr_hash_struct ghash;
16967+ struct subject_map *subjmap;
16968+ unsigned int i_num;
16969+ int err;
16970+
16971+ s_tmp = lookup_subject_map(userp);
16972+
16973+ /* we've already copied this subject into the kernel, just return
16974+ the reference to it, and don't copy it over again
16975+ */
16976+ if (s_tmp)
16977+ return(s_tmp);
16978+
16979+ if ((s_tmp = (struct acl_subject_label *)
16980+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
16981+ return ERR_PTR(-ENOMEM);
16982+
16983+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
16984+ if (subjmap == NULL)
16985+ return ERR_PTR(-ENOMEM);
16986+
16987+ subjmap->user = userp;
16988+ subjmap->kernel = s_tmp;
16989+ insert_subj_map_entry(subjmap);
16990+
16991+ if (copy_from_user(s_tmp, userp,
16992+ sizeof (struct acl_subject_label)))
16993+ return ERR_PTR(-EFAULT);
16994+
16995+ len = strnlen_user(s_tmp->filename, PATH_MAX);
16996+
16997+ if (!len || len >= PATH_MAX)
16998+ return ERR_PTR(-EINVAL);
16999+
17000+ if ((tmp = (char *) acl_alloc(len)) == NULL)
17001+ return ERR_PTR(-ENOMEM);
17002+
17003+ if (copy_from_user(tmp, s_tmp->filename, len))
17004+ return ERR_PTR(-EFAULT);
17005+
17006+ s_tmp->filename = tmp;
17007+
17008+ if (!strcmp(s_tmp->filename, "/"))
17009+ role->root_label = s_tmp;
17010+
17011+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
17012+ return ERR_PTR(-EFAULT);
17013+
17014+ /* copy user and group transition tables */
17015+
17016+ if (s_tmp->user_trans_num) {
17017+ uid_t *uidlist;
17018+
17019+ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
17020+ if (uidlist == NULL)
17021+ return ERR_PTR(-ENOMEM);
17022+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
17023+ return ERR_PTR(-EFAULT);
17024+
17025+ s_tmp->user_transitions = uidlist;
17026+ }
17027+
17028+ if (s_tmp->group_trans_num) {
17029+ gid_t *gidlist;
17030+
17031+ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
17032+ if (gidlist == NULL)
17033+ return ERR_PTR(-ENOMEM);
17034+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
17035+ return ERR_PTR(-EFAULT);
17036+
17037+ s_tmp->group_transitions = gidlist;
17038+ }
17039+
17040+ /* set up object hash table */
17041+ num_objs = count_user_objs(ghash.first);
17042+
17043+ s_tmp->obj_hash_size = num_objs;
17044+ s_tmp->obj_hash =
17045+ (struct acl_object_label **)
17046+ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
17047+
17048+ if (!s_tmp->obj_hash)
17049+ return ERR_PTR(-ENOMEM);
17050+
17051+ memset(s_tmp->obj_hash, 0,
17052+ s_tmp->obj_hash_size *
17053+ sizeof (struct acl_object_label *));
17054+
17055+ /* add in objects */
17056+ err = copy_user_objs(ghash.first, s_tmp, role);
17057+
17058+ if (err)
17059+ return ERR_PTR(err);
17060+
17061+ /* set pointer for parent subject */
17062+ if (s_tmp->parent_subject) {
17063+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
17064+
17065+ if (IS_ERR(s_tmp2))
17066+ return s_tmp2;
17067+
17068+ s_tmp->parent_subject = s_tmp2;
17069+ }
17070+
17071+ /* add in ip acls */
17072+
17073+ if (!s_tmp->ip_num) {
17074+ s_tmp->ips = NULL;
17075+ goto insert;
17076+ }
17077+
17078+ i_tmp =
17079+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
17080+ sizeof (struct
17081+ acl_ip_label *));
17082+
17083+ if (!i_tmp)
17084+ return ERR_PTR(-ENOMEM);
17085+
17086+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
17087+ *(i_tmp + i_num) =
17088+ (struct acl_ip_label *)
17089+ acl_alloc(sizeof (struct acl_ip_label));
17090+ if (!*(i_tmp + i_num))
17091+ return ERR_PTR(-ENOMEM);
17092+
17093+ if (copy_from_user
17094+ (&i_utmp2, s_tmp->ips + i_num,
17095+ sizeof (struct acl_ip_label *)))
17096+ return ERR_PTR(-EFAULT);
17097+
17098+ if (copy_from_user
17099+ (*(i_tmp + i_num), i_utmp2,
17100+ sizeof (struct acl_ip_label)))
17101+ return ERR_PTR(-EFAULT);
17102+
17103+ if ((*(i_tmp + i_num))->iface == NULL)
17104+ continue;
17105+
17106+ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
17107+ if (!len || len >= IFNAMSIZ)
17108+ return ERR_PTR(-EINVAL);
17109+ tmp = acl_alloc(len);
17110+ if (tmp == NULL)
17111+ return ERR_PTR(-ENOMEM);
17112+ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
17113+ return ERR_PTR(-EFAULT);
17114+ (*(i_tmp + i_num))->iface = tmp;
17115+ }
17116+
17117+ s_tmp->ips = i_tmp;
17118+
17119+insert:
17120+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
17121+ s_tmp->device))
17122+ return ERR_PTR(-ENOMEM);
17123+
17124+ return s_tmp;
17125+}
17126+
17127+static int
17128+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
17129+{
17130+ struct acl_subject_label s_pre;
17131+ struct acl_subject_label * ret;
17132+ int err;
17133+
17134+ while (userp) {
17135+ if (copy_from_user(&s_pre, userp,
17136+ sizeof (struct acl_subject_label)))
17137+ return -EFAULT;
17138+
17139+ /* do not add nested subjects here, add
17140+ while parsing objects
17141+ */
17142+
17143+ if (s_pre.mode & GR_NESTED) {
17144+ userp = s_pre.prev;
17145+ continue;
17146+ }
17147+
17148+ ret = do_copy_user_subj(userp, role);
17149+
17150+ err = PTR_ERR(ret);
17151+ if (IS_ERR(ret))
17152+ return err;
17153+
17154+ insert_acl_subj_label(ret, role);
17155+
17156+ userp = s_pre.prev;
17157+ }
17158+
17159+ return 0;
17160+}
17161+
17162+static int
17163+copy_user_acl(struct gr_arg *arg)
17164+{
17165+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
17166+ struct sprole_pw *sptmp;
17167+ struct gr_hash_struct *ghash;
17168+ uid_t *domainlist;
17169+ unsigned int r_num;
17170+ unsigned int len;
17171+ char *tmp;
17172+ int err = 0;
17173+ __u16 i;
17174+ __u32 num_subjs;
17175+
17176+ /* we need a default and kernel role */
17177+ if (arg->role_db.num_roles < 2)
17178+ return -EINVAL;
17179+
17180+ /* copy special role authentication info from userspace */
17181+
17182+ num_sprole_pws = arg->num_sprole_pws;
17183+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
17184+
17185+ if (!acl_special_roles) {
17186+ err = -ENOMEM;
17187+ goto cleanup;
17188+ }
17189+
17190+ for (i = 0; i < num_sprole_pws; i++) {
17191+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
17192+ if (!sptmp) {
17193+ err = -ENOMEM;
17194+ goto cleanup;
17195+ }
17196+ if (copy_from_user(sptmp, arg->sprole_pws + i,
17197+ sizeof (struct sprole_pw))) {
17198+ err = -EFAULT;
17199+ goto cleanup;
17200+ }
17201+
17202+ len =
17203+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
17204+
17205+ if (!len || len >= GR_SPROLE_LEN) {
17206+ err = -EINVAL;
17207+ goto cleanup;
17208+ }
17209+
17210+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
17211+ err = -ENOMEM;
17212+ goto cleanup;
17213+ }
17214+
17215+ if (copy_from_user(tmp, sptmp->rolename, len)) {
17216+ err = -EFAULT;
17217+ goto cleanup;
17218+ }
17219+
17220+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
17221+ printk(KERN_ALERT "Copying special role %s\n", tmp);
17222+#endif
17223+ sptmp->rolename = tmp;
17224+ acl_special_roles[i] = sptmp;
17225+ }
17226+
17227+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
17228+
17229+ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
17230+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
17231+
17232+ if (!r_tmp) {
17233+ err = -ENOMEM;
17234+ goto cleanup;
17235+ }
17236+
17237+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
17238+ sizeof (struct acl_role_label *))) {
17239+ err = -EFAULT;
17240+ goto cleanup;
17241+ }
17242+
17243+ if (copy_from_user(r_tmp, r_utmp2,
17244+ sizeof (struct acl_role_label))) {
17245+ err = -EFAULT;
17246+ goto cleanup;
17247+ }
17248+
17249+ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
17250+
17251+ if (!len || len >= PATH_MAX) {
17252+ err = -EINVAL;
17253+ goto cleanup;
17254+ }
17255+
17256+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
17257+ err = -ENOMEM;
17258+ goto cleanup;
17259+ }
17260+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
17261+ err = -EFAULT;
17262+ goto cleanup;
17263+ }
17264+ r_tmp->rolename = tmp;
17265+
17266+ if (!strcmp(r_tmp->rolename, "default")
17267+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
17268+ default_role = r_tmp;
17269+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
17270+ kernel_role = r_tmp;
17271+ }
17272+
17273+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
17274+ err = -ENOMEM;
17275+ goto cleanup;
17276+ }
17277+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
17278+ err = -EFAULT;
17279+ goto cleanup;
17280+ }
17281+
17282+ r_tmp->hash = ghash;
17283+
17284+ num_subjs = count_user_subjs(r_tmp->hash->first);
17285+
17286+ r_tmp->subj_hash_size = num_subjs;
17287+ r_tmp->subj_hash =
17288+ (struct acl_subject_label **)
17289+ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
17290+
17291+ if (!r_tmp->subj_hash) {
17292+ err = -ENOMEM;
17293+ goto cleanup;
17294+ }
17295+
17296+ err = copy_user_allowedips(r_tmp);
17297+ if (err)
17298+ goto cleanup;
17299+
17300+ /* copy domain info */
17301+ if (r_tmp->domain_children != NULL) {
17302+ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
17303+ if (domainlist == NULL) {
17304+ err = -ENOMEM;
17305+ goto cleanup;
17306+ }
17307+ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
17308+ err = -EFAULT;
17309+ goto cleanup;
17310+ }
17311+ r_tmp->domain_children = domainlist;
17312+ }
17313+
17314+ err = copy_user_transitions(r_tmp);
17315+ if (err)
17316+ goto cleanup;
17317+
17318+ memset(r_tmp->subj_hash, 0,
17319+ r_tmp->subj_hash_size *
17320+ sizeof (struct acl_subject_label *));
17321+
17322+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
17323+
17324+ if (err)
17325+ goto cleanup;
17326+
17327+ /* set nested subject list to null */
17328+ r_tmp->hash->first = NULL;
17329+
17330+ insert_acl_role_label(r_tmp);
17331+ }
17332+
17333+ goto return_err;
17334+ cleanup:
17335+ free_variables();
17336+ return_err:
17337+ return err;
17338+
17339+}
17340+
17341+static int
17342+gracl_init(struct gr_arg *args)
17343+{
17344+ int error = 0;
17345+
17346+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
17347+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
17348+
17349+ if (init_variables(args)) {
17350+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
17351+ error = -ENOMEM;
17352+ free_variables();
17353+ goto out;
17354+ }
17355+
17356+ error = copy_user_acl(args);
17357+ free_init_variables();
17358+ if (error) {
17359+ free_variables();
17360+ goto out;
17361+ }
17362+
17363+ if ((error = gr_set_acls(0))) {
17364+ free_variables();
17365+ goto out;
17366+ }
17367+
17368+ gr_status |= GR_READY;
17369+ out:
17370+ return error;
17371+}
17372+
17373+/* derived from glibc fnmatch() 0: match, 1: no match*/
17374+
17375+static int
17376+glob_match(const char *p, const char *n)
17377+{
17378+ char c;
17379+
17380+ while ((c = *p++) != '\0') {
17381+ switch (c) {
17382+ case '?':
17383+ if (*n == '\0')
17384+ return 1;
17385+ else if (*n == '/')
17386+ return 1;
17387+ break;
17388+ case '\\':
17389+ if (*n != c)
17390+ return 1;
17391+ break;
17392+ case '*':
17393+ for (c = *p++; c == '?' || c == '*'; c = *p++) {
17394+ if (*n == '/')
17395+ return 1;
17396+ else if (c == '?') {
17397+ if (*n == '\0')
17398+ return 1;
17399+ else
17400+ ++n;
17401+ }
17402+ }
17403+ if (c == '\0') {
17404+ return 0;
17405+ } else {
17406+ const char *endp;
17407+
17408+ if ((endp = strchr(n, '/')) == NULL)
17409+ endp = n + strlen(n);
17410+
17411+ if (c == '[') {
17412+ for (--p; n < endp; ++n)
17413+ if (!glob_match(p, n))
17414+ return 0;
17415+ } else if (c == '/') {
17416+ while (*n != '\0' && *n != '/')
17417+ ++n;
17418+ if (*n == '/' && !glob_match(p, n + 1))
17419+ return 0;
17420+ } else {
17421+ for (--p; n < endp; ++n)
17422+ if (*n == c && !glob_match(p, n))
17423+ return 0;
17424+ }
17425+
17426+ return 1;
17427+ }
17428+ case '[':
17429+ {
17430+ int not;
17431+ char cold;
17432+
17433+ if (*n == '\0' || *n == '/')
17434+ return 1;
17435+
17436+ not = (*p == '!' || *p == '^');
17437+ if (not)
17438+ ++p;
17439+
17440+ c = *p++;
17441+ for (;;) {
17442+ unsigned char fn = (unsigned char)*n;
17443+
17444+ if (c == '\0')
17445+ return 1;
17446+ else {
17447+ if (c == fn)
17448+ goto matched;
17449+ cold = c;
17450+ c = *p++;
17451+
17452+ if (c == '-' && *p != ']') {
17453+ unsigned char cend = *p++;
17454+
17455+ if (cend == '\0')
17456+ return 1;
17457+
17458+ if (cold <= fn && fn <= cend)
17459+ goto matched;
17460+
17461+ c = *p++;
17462+ }
17463+ }
17464+
17465+ if (c == ']')
17466+ break;
17467+ }
17468+ if (!not)
17469+ return 1;
17470+ break;
17471+ matched:
17472+ while (c != ']') {
17473+ if (c == '\0')
17474+ return 1;
17475+
17476+ c = *p++;
17477+ }
17478+ if (not)
17479+ return 1;
17480+ }
17481+ break;
17482+ default:
17483+ if (c != *n)
17484+ return 1;
17485+ }
17486+
17487+ ++n;
17488+ }
17489+
17490+ if (*n == '\0')
17491+ return 0;
17492+
17493+ if (*n == '/')
17494+ return 0;
17495+
17496+ return 1;
17497+}
17498+
17499+static struct acl_object_label *
17500+chk_glob_label(struct acl_object_label *globbed,
17501+ struct dentry *dentry, struct vfsmount *mnt, char **path)
17502+{
17503+ struct acl_object_label *tmp;
17504+
17505+ if (*path == NULL)
17506+ *path = gr_to_filename_nolock(dentry, mnt);
17507+
17508+ tmp = globbed;
17509+
17510+ while (tmp) {
17511+ if (!glob_match(tmp->filename, *path))
17512+ return tmp;
17513+ tmp = tmp->next;
17514+ }
17515+
17516+ return NULL;
17517+}
17518+
17519+static struct acl_object_label *
17520+__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
17521+ const ino_t curr_ino, const dev_t curr_dev,
17522+ const struct acl_subject_label *subj, char **path)
17523+{
17524+ struct acl_subject_label *tmpsubj;
17525+ struct acl_object_label *retval;
17526+ struct acl_object_label *retval2;
17527+
17528+ tmpsubj = (struct acl_subject_label *) subj;
17529+ read_lock(&gr_inode_lock);
17530+ do {
17531+ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
17532+ if (retval) {
17533+ if (retval->globbed) {
17534+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
17535+ (struct vfsmount *)orig_mnt, path);
17536+ if (retval2)
17537+ retval = retval2;
17538+ }
17539+ break;
17540+ }
17541+ } while ((tmpsubj = tmpsubj->parent_subject));
17542+ read_unlock(&gr_inode_lock);
17543+
17544+ return retval;
17545+}
17546+
17547+static __inline__ struct acl_object_label *
17548+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
17549+ const struct dentry *curr_dentry,
17550+ const struct acl_subject_label *subj, char **path)
17551+{
17552+ return __full_lookup(orig_dentry, orig_mnt,
17553+ curr_dentry->d_inode->i_ino,
17554+ curr_dentry->d_inode->i_sb->s_dev, subj, path);
17555+}
17556+
17557+static struct acl_object_label *
17558+__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
17559+ const struct acl_subject_label *subj, char *path)
17560+{
17561+ struct dentry *dentry = (struct dentry *) l_dentry;
17562+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
17563+ struct acl_object_label *retval;
17564+
17565+ spin_lock(&dcache_lock);
17566+
17567+ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
17568+ /* ignore Eric Biederman */
17569+ IS_PRIVATE(l_dentry->d_inode))) {
17570+ retval = fakefs_obj;
17571+ goto out;
17572+ }
17573+
17574+ for (;;) {
17575+ if (dentry == real_root && mnt == real_root_mnt)
17576+ break;
17577+
17578+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
17579+ if (mnt->mnt_parent == mnt)
17580+ break;
17581+
17582+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
17583+ if (retval != NULL)
17584+ goto out;
17585+
17586+ dentry = mnt->mnt_mountpoint;
17587+ mnt = mnt->mnt_parent;
17588+ continue;
17589+ }
17590+
17591+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
17592+ if (retval != NULL)
17593+ goto out;
17594+
17595+ dentry = dentry->d_parent;
17596+ }
17597+
17598+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
17599+
17600+ if (retval == NULL)
17601+ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
17602+out:
17603+ spin_unlock(&dcache_lock);
17604+ return retval;
17605+}
17606+
17607+static __inline__ struct acl_object_label *
17608+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
17609+ const struct acl_subject_label *subj)
17610+{
17611+ char *path = NULL;
17612+ return __chk_obj_label(l_dentry, l_mnt, subj, path);
17613+}
17614+
17615+static __inline__ struct acl_object_label *
17616+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
17617+ const struct acl_subject_label *subj, char *path)
17618+{
17619+ return __chk_obj_label(l_dentry, l_mnt, subj, path);
17620+}
17621+
17622+static struct acl_subject_label *
17623+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
17624+ const struct acl_role_label *role)
17625+{
17626+ struct dentry *dentry = (struct dentry *) l_dentry;
17627+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
17628+ struct acl_subject_label *retval;
17629+
17630+ spin_lock(&dcache_lock);
17631+
17632+ for (;;) {
17633+ if (dentry == real_root && mnt == real_root_mnt)
17634+ break;
17635+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
17636+ if (mnt->mnt_parent == mnt)
17637+ break;
17638+
17639+ read_lock(&gr_inode_lock);
17640+ retval =
17641+ lookup_acl_subj_label(dentry->d_inode->i_ino,
17642+ dentry->d_inode->i_sb->s_dev, role);
17643+ read_unlock(&gr_inode_lock);
17644+ if (retval != NULL)
17645+ goto out;
17646+
17647+ dentry = mnt->mnt_mountpoint;
17648+ mnt = mnt->mnt_parent;
17649+ continue;
17650+ }
17651+
17652+ read_lock(&gr_inode_lock);
17653+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
17654+ dentry->d_inode->i_sb->s_dev, role);
17655+ read_unlock(&gr_inode_lock);
17656+ if (retval != NULL)
17657+ goto out;
17658+
17659+ dentry = dentry->d_parent;
17660+ }
17661+
17662+ read_lock(&gr_inode_lock);
17663+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
17664+ dentry->d_inode->i_sb->s_dev, role);
17665+ read_unlock(&gr_inode_lock);
17666+
17667+ if (unlikely(retval == NULL)) {
17668+ read_lock(&gr_inode_lock);
17669+ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
17670+ real_root->d_inode->i_sb->s_dev, role);
17671+ read_unlock(&gr_inode_lock);
17672+ }
17673+out:
17674+ spin_unlock(&dcache_lock);
17675+
17676+ return retval;
17677+}
17678+
17679+static void
17680+gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
17681+{
17682+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
17683+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
17684+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
17685+ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
17686+
17687+ return;
17688+}
17689+
17690+static void
17691+gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
17692+{
17693+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
17694+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
17695+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
17696+ 1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
17697+
17698+ return;
17699+}
17700+
17701+static void
17702+gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
17703+ const unsigned int effective, const unsigned int fs)
17704+{
17705+ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
17706+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
17707+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
17708+ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
17709+
17710+ return;
17711+}
17712+
17713+__u32
17714+gr_check_link(const struct dentry * new_dentry,
17715+ const struct dentry * parent_dentry,
17716+ const struct vfsmount * parent_mnt,
17717+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
17718+{
17719+ struct acl_object_label *obj;
17720+ __u32 oldmode, newmode;
17721+ __u32 needmode;
17722+
17723+ if (unlikely(!(gr_status & GR_READY)))
17724+ return (GR_CREATE | GR_LINK);
17725+
17726+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
17727+ oldmode = obj->mode;
17728+
17729+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
17730+ oldmode |= (GR_CREATE | GR_LINK);
17731+
17732+ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
17733+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
17734+ needmode |= GR_SETID | GR_AUDIT_SETID;
17735+
17736+ newmode =
17737+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
17738+ oldmode | needmode);
17739+
17740+ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
17741+ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
17742+ GR_INHERIT | GR_AUDIT_INHERIT);
17743+
17744+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
17745+ goto bad;
17746+
17747+ if ((oldmode & needmode) != needmode)
17748+ goto bad;
17749+
17750+ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
17751+ if ((newmode & needmode) != needmode)
17752+ goto bad;
17753+
17754+ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
17755+ return newmode;
17756+bad:
17757+ needmode = oldmode;
17758+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
17759+ needmode |= GR_SETID;
17760+
17761+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
17762+ gr_log_learn(current, old_dentry, old_mnt, needmode);
17763+ return (GR_CREATE | GR_LINK);
17764+ } else if (newmode & GR_SUPPRESS)
17765+ return GR_SUPPRESS;
17766+ else
17767+ return 0;
17768+}
17769+
17770+__u32
17771+gr_search_file(const struct dentry * dentry, const __u32 mode,
17772+ const struct vfsmount * mnt)
17773+{
17774+ __u32 retval = mode;
17775+ struct acl_subject_label *curracl;
17776+ struct acl_object_label *currobj;
17777+
17778+ if (unlikely(!(gr_status & GR_READY)))
17779+ return (mode & ~GR_AUDITS);
17780+
17781+ curracl = current->acl;
17782+
17783+ currobj = chk_obj_label(dentry, mnt, curracl);
17784+ retval = currobj->mode & mode;
17785+
17786+ if (unlikely
17787+ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
17788+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
17789+ __u32 new_mode = mode;
17790+
17791+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
17792+
17793+ retval = new_mode;
17794+
17795+ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
17796+ new_mode |= GR_INHERIT;
17797+
17798+ if (!(mode & GR_NOLEARN))
17799+ gr_log_learn(current, dentry, mnt, new_mode);
17800+ }
17801+
17802+ return retval;
17803+}
17804+
17805+__u32
17806+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
17807+ const struct vfsmount * mnt, const __u32 mode)
17808+{
17809+ struct name_entry *match;
17810+ struct acl_object_label *matchpo;
17811+ struct acl_subject_label *curracl;
17812+ char *path;
17813+ __u32 retval;
17814+
17815+ if (unlikely(!(gr_status & GR_READY)))
17816+ return (mode & ~GR_AUDITS);
17817+
17818+ preempt_disable();
17819+ path = gr_to_filename_rbac(new_dentry, mnt);
17820+ match = lookup_name_entry(path);
17821+
17822+ if (!match)
17823+ goto check_parent;
17824+
17825+ curracl = current->acl;
17826+
17827+ read_lock(&gr_inode_lock);
17828+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
17829+ read_unlock(&gr_inode_lock);
17830+
17831+ if (matchpo) {
17832+ if ((matchpo->mode & mode) !=
17833+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
17834+ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
17835+ __u32 new_mode = mode;
17836+
17837+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
17838+
17839+ gr_log_learn(current, new_dentry, mnt, new_mode);
17840+
17841+ preempt_enable();
17842+ return new_mode;
17843+ }
17844+ preempt_enable();
17845+ return (matchpo->mode & mode);
17846+ }
17847+
17848+ check_parent:
17849+ curracl = current->acl;
17850+
17851+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
17852+ retval = matchpo->mode & mode;
17853+
17854+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
17855+ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
17856+ __u32 new_mode = mode;
17857+
17858+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
17859+
17860+ gr_log_learn(current, new_dentry, mnt, new_mode);
17861+ preempt_enable();
17862+ return new_mode;
17863+ }
17864+
17865+ preempt_enable();
17866+ return retval;
17867+}
17868+
17869+int
17870+gr_check_hidden_task(const struct task_struct *task)
17871+{
17872+ if (unlikely(!(gr_status & GR_READY)))
17873+ return 0;
17874+
17875+ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
17876+ return 1;
17877+
17878+ return 0;
17879+}
17880+
17881+int
17882+gr_check_protected_task(const struct task_struct *task)
17883+{
17884+ if (unlikely(!(gr_status & GR_READY) || !task))
17885+ return 0;
17886+
17887+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
17888+ task->acl != current->acl)
17889+ return 1;
17890+
17891+ return 0;
17892+}
17893+
17894+void
17895+gr_copy_label(struct task_struct *tsk)
17896+{
17897+ tsk->signal->used_accept = 0;
17898+ tsk->acl_sp_role = 0;
17899+ tsk->acl_role_id = current->acl_role_id;
17900+ tsk->acl = current->acl;
17901+ tsk->role = current->role;
17902+ tsk->signal->curr_ip = current->signal->curr_ip;
17903+ if (current->exec_file)
17904+ get_file(current->exec_file);
17905+ tsk->exec_file = current->exec_file;
17906+ tsk->is_writable = current->is_writable;
17907+ if (unlikely(current->signal->used_accept))
17908+ current->signal->curr_ip = 0;
17909+
17910+ return;
17911+}
17912+
17913+static void
17914+gr_set_proc_res(struct task_struct *task)
17915+{
17916+ struct acl_subject_label *proc;
17917+ unsigned short i;
17918+
17919+ proc = task->acl;
17920+
17921+ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
17922+ return;
17923+
17924+ for (i = 0; i < (GR_NLIMITS - 1); i++) {
17925+ if (!(proc->resmask & (1 << i)))
17926+ continue;
17927+
17928+ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
17929+ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
17930+ }
17931+
17932+ return;
17933+}
17934+
17935+int
17936+gr_check_user_change(int real, int effective, int fs)
17937+{
17938+ unsigned int i;
17939+ __u16 num;
17940+ uid_t *uidlist;
17941+ int curuid;
17942+ int realok = 0;
17943+ int effectiveok = 0;
17944+ int fsok = 0;
17945+
17946+ if (unlikely(!(gr_status & GR_READY)))
17947+ return 0;
17948+
17949+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
17950+ gr_log_learn_id_change(current, 'u', real, effective, fs);
17951+
17952+ num = current->acl->user_trans_num;
17953+ uidlist = current->acl->user_transitions;
17954+
17955+ if (uidlist == NULL)
17956+ return 0;
17957+
17958+ if (real == -1)
17959+ realok = 1;
17960+ if (effective == -1)
17961+ effectiveok = 1;
17962+ if (fs == -1)
17963+ fsok = 1;
17964+
17965+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
17966+ for (i = 0; i < num; i++) {
17967+ curuid = (int)uidlist[i];
17968+ if (real == curuid)
17969+ realok = 1;
17970+ if (effective == curuid)
17971+ effectiveok = 1;
17972+ if (fs == curuid)
17973+ fsok = 1;
17974+ }
17975+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
17976+ for (i = 0; i < num; i++) {
17977+ curuid = (int)uidlist[i];
17978+ if (real == curuid)
17979+ break;
17980+ if (effective == curuid)
17981+ break;
17982+ if (fs == curuid)
17983+ break;
17984+ }
17985+ /* not in deny list */
17986+ if (i == num) {
17987+ realok = 1;
17988+ effectiveok = 1;
17989+ fsok = 1;
17990+ }
17991+ }
17992+
17993+ if (realok && effectiveok && fsok)
17994+ return 0;
17995+ else {
17996+ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
17997+ return 1;
17998+ }
17999+}
18000+
18001+int
18002+gr_check_group_change(int real, int effective, int fs)
18003+{
18004+ unsigned int i;
18005+ __u16 num;
18006+ gid_t *gidlist;
18007+ int curgid;
18008+ int realok = 0;
18009+ int effectiveok = 0;
18010+ int fsok = 0;
18011+
18012+ if (unlikely(!(gr_status & GR_READY)))
18013+ return 0;
18014+
18015+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
18016+ gr_log_learn_id_change(current, 'g', real, effective, fs);
18017+
18018+ num = current->acl->group_trans_num;
18019+ gidlist = current->acl->group_transitions;
18020+
18021+ if (gidlist == NULL)
18022+ return 0;
18023+
18024+ if (real == -1)
18025+ realok = 1;
18026+ if (effective == -1)
18027+ effectiveok = 1;
18028+ if (fs == -1)
18029+ fsok = 1;
18030+
18031+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
18032+ for (i = 0; i < num; i++) {
18033+ curgid = (int)gidlist[i];
18034+ if (real == curgid)
18035+ realok = 1;
18036+ if (effective == curgid)
18037+ effectiveok = 1;
18038+ if (fs == curgid)
18039+ fsok = 1;
18040+ }
18041+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
18042+ for (i = 0; i < num; i++) {
18043+ curgid = (int)gidlist[i];
18044+ if (real == curgid)
18045+ break;
18046+ if (effective == curgid)
18047+ break;
18048+ if (fs == curgid)
18049+ break;
18050+ }
18051+ /* not in deny list */
18052+ if (i == num) {
18053+ realok = 1;
18054+ effectiveok = 1;
18055+ fsok = 1;
18056+ }
18057+ }
18058+
18059+ if (realok && effectiveok && fsok)
18060+ return 0;
18061+ else {
18062+ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
18063+ return 1;
18064+ }
18065+}
18066+
18067+void
18068+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
18069+{
18070+ struct acl_role_label *role = task->role;
18071+ struct acl_subject_label *subj = NULL;
18072+ struct acl_object_label *obj;
18073+ struct file *filp;
18074+
18075+ if (unlikely(!(gr_status & GR_READY)))
18076+ return;
18077+
18078+ filp = task->exec_file;
18079+
18080+ /* kernel process, we'll give them the kernel role */
18081+ if (unlikely(!filp)) {
18082+ task->role = kernel_role;
18083+ task->acl = kernel_role->root_label;
18084+ return;
18085+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
18086+ role = lookup_acl_role_label(task, uid, gid);
18087+
18088+ /* perform subject lookup in possibly new role
18089+ we can use this result below in the case where role == task->role
18090+ */
18091+ subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
18092+
18093+ /* if we changed uid/gid, but result in the same role
18094+ and are using inheritance, don't lose the inherited subject
18095+ if current subject is other than what normal lookup
18096+ would result in, we arrived via inheritance, don't
18097+ lose subject
18098+ */
18099+ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
18100+ (subj == task->acl)))
18101+ task->acl = subj;
18102+
18103+ task->role = role;
18104+
18105+ task->is_writable = 0;
18106+
18107+ /* ignore additional mmap checks for processes that are writable
18108+ by the default ACL */
18109+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
18110+ if (unlikely(obj->mode & GR_WRITE))
18111+ task->is_writable = 1;
18112+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
18113+ if (unlikely(obj->mode & GR_WRITE))
18114+ task->is_writable = 1;
18115+
18116+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18117+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
18118+#endif
18119+
18120+ gr_set_proc_res(task);
18121+
18122+ return;
18123+}
18124+
18125+int
18126+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
18127+{
18128+ struct task_struct *task = current;
18129+ struct acl_subject_label *newacl;
18130+ struct acl_object_label *obj;
18131+ __u32 retmode;
18132+
18133+ if (unlikely(!(gr_status & GR_READY)))
18134+ return 0;
18135+
18136+ newacl = chk_subj_label(dentry, mnt, task->role);
18137+
18138+ task_lock(task);
18139+ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
18140+ GR_POVERRIDE) && (task->acl != newacl) &&
18141+ !(task->role->roletype & GR_ROLE_GOD) &&
18142+ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
18143+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
18144+ (atomic_read(&task->fs->count) > 1 ||
18145+ atomic_read(&task->files->count) > 1 ||
18146+ atomic_read(&task->sighand->count) > 1)) {
18147+ task_unlock(task);
18148+ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
18149+ return -EACCES;
18150+ }
18151+ task_unlock(task);
18152+
18153+ obj = chk_obj_label(dentry, mnt, task->acl);
18154+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
18155+
18156+ if (!(task->acl->mode & GR_INHERITLEARN) &&
18157+ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
18158+ if (obj->nested)
18159+ task->acl = obj->nested;
18160+ else
18161+ task->acl = newacl;
18162+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
18163+ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
18164+
18165+ task->is_writable = 0;
18166+
18167+ /* ignore additional mmap checks for processes that are writable
18168+ by the default ACL */
18169+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
18170+ if (unlikely(obj->mode & GR_WRITE))
18171+ task->is_writable = 1;
18172+ obj = chk_obj_label(dentry, mnt, task->role->root_label);
18173+ if (unlikely(obj->mode & GR_WRITE))
18174+ task->is_writable = 1;
18175+
18176+ gr_set_proc_res(task);
18177+
18178+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18179+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
18180+#endif
18181+ return 0;
18182+}
18183+
18184+static void
18185+do_handle_delete(const ino_t ino, const dev_t dev)
18186+{
18187+ struct acl_object_label *matchpo;
18188+ struct acl_subject_label *matchps;
18189+ struct acl_subject_label *subj;
18190+ struct acl_role_label *role;
18191+ unsigned int i, x;
18192+
18193+ FOR_EACH_ROLE_START(role, i)
18194+ FOR_EACH_SUBJECT_START(role, subj, x)
18195+ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
18196+ matchpo->mode |= GR_DELETED;
18197+ FOR_EACH_SUBJECT_END(subj,x)
18198+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
18199+ if (subj->inode == ino && subj->device == dev)
18200+ subj->mode |= GR_DELETED;
18201+ FOR_EACH_NESTED_SUBJECT_END(subj)
18202+ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
18203+ matchps->mode |= GR_DELETED;
18204+ FOR_EACH_ROLE_END(role,i)
18205+
18206+ return;
18207+}
18208+
18209+void
18210+gr_handle_delete(const ino_t ino, const dev_t dev)
18211+{
18212+ if (unlikely(!(gr_status & GR_READY)))
18213+ return;
18214+
18215+ write_lock(&gr_inode_lock);
18216+ if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
18217+ do_handle_delete(ino, dev);
18218+ write_unlock(&gr_inode_lock);
18219+
18220+ return;
18221+}
18222+
18223+static void
18224+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
18225+ const ino_t newinode, const dev_t newdevice,
18226+ struct acl_subject_label *subj)
18227+{
18228+ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
18229+ struct acl_object_label *match;
18230+
18231+ match = subj->obj_hash[index];
18232+
18233+ while (match && (match->inode != oldinode ||
18234+ match->device != olddevice ||
18235+ !(match->mode & GR_DELETED)))
18236+ match = match->next;
18237+
18238+ if (match && (match->inode == oldinode)
18239+ && (match->device == olddevice)
18240+ && (match->mode & GR_DELETED)) {
18241+ if (match->prev == NULL) {
18242+ subj->obj_hash[index] = match->next;
18243+ if (match->next != NULL)
18244+ match->next->prev = NULL;
18245+ } else {
18246+ match->prev->next = match->next;
18247+ if (match->next != NULL)
18248+ match->next->prev = match->prev;
18249+ }
18250+ match->prev = NULL;
18251+ match->next = NULL;
18252+ match->inode = newinode;
18253+ match->device = newdevice;
18254+ match->mode &= ~GR_DELETED;
18255+
18256+ insert_acl_obj_label(match, subj);
18257+ }
18258+
18259+ return;
18260+}
18261+
18262+static void
18263+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
18264+ const ino_t newinode, const dev_t newdevice,
18265+ struct acl_role_label *role)
18266+{
18267+ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
18268+ struct acl_subject_label *match;
18269+
18270+ match = role->subj_hash[index];
18271+
18272+ while (match && (match->inode != oldinode ||
18273+ match->device != olddevice ||
18274+ !(match->mode & GR_DELETED)))
18275+ match = match->next;
18276+
18277+ if (match && (match->inode == oldinode)
18278+ && (match->device == olddevice)
18279+ && (match->mode & GR_DELETED)) {
18280+ if (match->prev == NULL) {
18281+ role->subj_hash[index] = match->next;
18282+ if (match->next != NULL)
18283+ match->next->prev = NULL;
18284+ } else {
18285+ match->prev->next = match->next;
18286+ if (match->next != NULL)
18287+ match->next->prev = match->prev;
18288+ }
18289+ match->prev = NULL;
18290+ match->next = NULL;
18291+ match->inode = newinode;
18292+ match->device = newdevice;
18293+ match->mode &= ~GR_DELETED;
18294+
18295+ insert_acl_subj_label(match, role);
18296+ }
18297+
18298+ return;
18299+}
18300+
18301+static void
18302+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
18303+ const ino_t newinode, const dev_t newdevice)
18304+{
18305+ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
18306+ struct inodev_entry *match;
18307+
18308+ match = inodev_set.i_hash[index];
18309+
18310+ while (match && (match->nentry->inode != oldinode ||
18311+ match->nentry->device != olddevice))
18312+ match = match->next;
18313+
18314+ if (match && (match->nentry->inode == oldinode)
18315+ && (match->nentry->device == olddevice)) {
18316+ if (match->prev == NULL) {
18317+ inodev_set.i_hash[index] = match->next;
18318+ if (match->next != NULL)
18319+ match->next->prev = NULL;
18320+ } else {
18321+ match->prev->next = match->next;
18322+ if (match->next != NULL)
18323+ match->next->prev = match->prev;
18324+ }
18325+ match->prev = NULL;
18326+ match->next = NULL;
18327+ match->nentry->inode = newinode;
18328+ match->nentry->device = newdevice;
18329+
18330+ insert_inodev_entry(match);
18331+ }
18332+
18333+ return;
18334+}
18335+
18336+static void
18337+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
18338+ const struct vfsmount *mnt)
18339+{
18340+ struct acl_subject_label *subj;
18341+ struct acl_role_label *role;
18342+ unsigned int i, x;
18343+
18344+ FOR_EACH_ROLE_START(role, i)
18345+ update_acl_subj_label(matchn->inode, matchn->device,
18346+ dentry->d_inode->i_ino,
18347+ dentry->d_inode->i_sb->s_dev, role);
18348+
18349+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
18350+ if ((subj->inode == dentry->d_inode->i_ino) &&
18351+ (subj->device == dentry->d_inode->i_sb->s_dev)) {
18352+ subj->inode = dentry->d_inode->i_ino;
18353+ subj->device = dentry->d_inode->i_sb->s_dev;
18354+ }
18355+ FOR_EACH_NESTED_SUBJECT_END(subj)
18356+ FOR_EACH_SUBJECT_START(role, subj, x)
18357+ update_acl_obj_label(matchn->inode, matchn->device,
18358+ dentry->d_inode->i_ino,
18359+ dentry->d_inode->i_sb->s_dev, subj);
18360+ FOR_EACH_SUBJECT_END(subj,x)
18361+ FOR_EACH_ROLE_END(role,i)
18362+
18363+ update_inodev_entry(matchn->inode, matchn->device,
18364+ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
18365+
18366+ return;
18367+}
18368+
18369+void
18370+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
18371+{
18372+ struct name_entry *matchn;
18373+
18374+ if (unlikely(!(gr_status & GR_READY)))
18375+ return;
18376+
18377+ preempt_disable();
18378+ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
18379+
18380+ if (unlikely((unsigned long)matchn)) {
18381+ write_lock(&gr_inode_lock);
18382+ do_handle_create(matchn, dentry, mnt);
18383+ write_unlock(&gr_inode_lock);
18384+ }
18385+ preempt_enable();
18386+
18387+ return;
18388+}
18389+
18390+void
18391+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
18392+ struct dentry *old_dentry,
18393+ struct dentry *new_dentry,
18394+ struct vfsmount *mnt, const __u8 replace)
18395+{
18396+ struct name_entry *matchn;
18397+
18398+ if (unlikely(!(gr_status & GR_READY)))
18399+ return;
18400+
18401+ preempt_disable();
18402+ matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
18403+
18404+ /* we wouldn't have to check d_inode if it weren't for
18405+ NFS silly-renaming
18406+ */
18407+
18408+ write_lock(&gr_inode_lock);
18409+ if (unlikely(replace && new_dentry->d_inode)) {
18410+ if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
18411+ new_dentry->d_inode->i_sb->s_dev) &&
18412+ (old_dentry->d_inode->i_nlink <= 1)))
18413+ do_handle_delete(new_dentry->d_inode->i_ino,
18414+ new_dentry->d_inode->i_sb->s_dev);
18415+ }
18416+
18417+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
18418+ old_dentry->d_inode->i_sb->s_dev) &&
18419+ (old_dentry->d_inode->i_nlink <= 1)))
18420+ do_handle_delete(old_dentry->d_inode->i_ino,
18421+ old_dentry->d_inode->i_sb->s_dev);
18422+
18423+ if (unlikely((unsigned long)matchn))
18424+ do_handle_create(matchn, old_dentry, mnt);
18425+
18426+ write_unlock(&gr_inode_lock);
18427+ preempt_enable();
18428+
18429+ return;
18430+}
18431+
18432+static int
18433+lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
18434+ unsigned char **sum)
18435+{
18436+ struct acl_role_label *r;
18437+ struct role_allowed_ip *ipp;
18438+ struct role_transition *trans;
18439+ unsigned int i;
18440+ int found = 0;
18441+
18442+ /* check transition table */
18443+
18444+ for (trans = current->role->transitions; trans; trans = trans->next) {
18445+ if (!strcmp(rolename, trans->rolename)) {
18446+ found = 1;
18447+ break;
18448+ }
18449+ }
18450+
18451+ if (!found)
18452+ return 0;
18453+
18454+ /* handle special roles that do not require authentication
18455+ and check ip */
18456+
18457+ FOR_EACH_ROLE_START(r, i)
18458+ if (!strcmp(rolename, r->rolename) &&
18459+ (r->roletype & GR_ROLE_SPECIAL)) {
18460+ found = 0;
18461+ if (r->allowed_ips != NULL) {
18462+ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
18463+ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
18464+ (ntohl(ipp->addr) & ipp->netmask))
18465+ found = 1;
18466+ }
18467+ } else
18468+ found = 2;
18469+ if (!found)
18470+ return 0;
18471+
18472+ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
18473+ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
18474+ *salt = NULL;
18475+ *sum = NULL;
18476+ return 1;
18477+ }
18478+ }
18479+ FOR_EACH_ROLE_END(r,i)
18480+
18481+ for (i = 0; i < num_sprole_pws; i++) {
18482+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
18483+ *salt = acl_special_roles[i]->salt;
18484+ *sum = acl_special_roles[i]->sum;
18485+ return 1;
18486+ }
18487+ }
18488+
18489+ return 0;
18490+}
18491+
18492+static void
18493+assign_special_role(char *rolename)
18494+{
18495+ struct acl_object_label *obj;
18496+ struct acl_role_label *r;
18497+ struct acl_role_label *assigned = NULL;
18498+ struct task_struct *tsk;
18499+ struct file *filp;
18500+ unsigned int i;
18501+
18502+ FOR_EACH_ROLE_START(r, i)
18503+ if (!strcmp(rolename, r->rolename) &&
18504+ (r->roletype & GR_ROLE_SPECIAL))
18505+ assigned = r;
18506+ FOR_EACH_ROLE_END(r,i)
18507+
18508+ if (!assigned)
18509+ return;
18510+
18511+ read_lock(&tasklist_lock);
18512+ read_lock(&grsec_exec_file_lock);
18513+
18514+ tsk = current->parent;
18515+ if (tsk == NULL)
18516+ goto out_unlock;
18517+
18518+ filp = tsk->exec_file;
18519+ if (filp == NULL)
18520+ goto out_unlock;
18521+
18522+ tsk->is_writable = 0;
18523+
18524+ tsk->acl_sp_role = 1;
18525+ tsk->acl_role_id = ++acl_sp_role_value;
18526+ tsk->role = assigned;
18527+ tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
18528+
18529+ /* ignore additional mmap checks for processes that are writable
18530+ by the default ACL */
18531+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
18532+ if (unlikely(obj->mode & GR_WRITE))
18533+ tsk->is_writable = 1;
18534+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
18535+ if (unlikely(obj->mode & GR_WRITE))
18536+ tsk->is_writable = 1;
18537+
18538+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18539+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
18540+#endif
18541+
18542+out_unlock:
18543+ read_unlock(&grsec_exec_file_lock);
18544+ read_unlock(&tasklist_lock);
18545+ return;
18546+}
18547+
18548+int gr_check_secure_terminal(struct task_struct *task)
18549+{
18550+ struct task_struct *p, *p2, *p3;
18551+ struct files_struct *files;
18552+ struct fdtable *fdt;
18553+ struct file *our_file = NULL, *file;
18554+ int i;
18555+
18556+ if (task->signal->tty == NULL)
18557+ return 1;
18558+
18559+ files = get_files_struct(task);
18560+ if (files != NULL) {
18561+ rcu_read_lock();
18562+ fdt = files_fdtable(files);
18563+ for (i=0; i < fdt->max_fds; i++) {
18564+ file = fcheck_files(files, i);
18565+ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
18566+ get_file(file);
18567+ our_file = file;
18568+ }
18569+ }
18570+ rcu_read_unlock();
18571+ put_files_struct(files);
18572+ }
18573+
18574+ if (our_file == NULL)
18575+ return 1;
18576+
18577+ read_lock(&tasklist_lock);
18578+ do_each_thread(p2, p) {
18579+ files = get_files_struct(p);
18580+ if (files == NULL ||
18581+ (p->signal && p->signal->tty == task->signal->tty)) {
18582+ if (files != NULL)
18583+ put_files_struct(files);
18584+ continue;
18585+ }
18586+ rcu_read_lock();
18587+ fdt = files_fdtable(files);
18588+ for (i=0; i < fdt->max_fds; i++) {
18589+ file = fcheck_files(files, i);
18590+ if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
18591+ file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
18592+ p3 = task;
18593+ while (p3->pid > 0) {
18594+ if (p3 == p)
18595+ break;
18596+ p3 = p3->parent;
18597+ }
18598+ if (p3 == p)
18599+ break;
18600+ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
18601+ gr_handle_alertkill(p);
18602+ rcu_read_unlock();
18603+ put_files_struct(files);
18604+ read_unlock(&tasklist_lock);
18605+ fput(our_file);
18606+ return 0;
18607+ }
18608+ }
18609+ rcu_read_unlock();
18610+ put_files_struct(files);
18611+ } while_each_thread(p2, p);
18612+ read_unlock(&tasklist_lock);
18613+
18614+ fput(our_file);
18615+ return 1;
18616+}
18617+
18618+ssize_t
18619+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
18620+{
18621+ struct gr_arg_wrapper uwrap;
18622+ unsigned char *sprole_salt;
18623+ unsigned char *sprole_sum;
18624+ int error = sizeof (struct gr_arg_wrapper);
18625+ int error2 = 0;
18626+
18627+ down(&gr_dev_sem);
18628+
18629+ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
18630+ error = -EPERM;
18631+ goto out;
18632+ }
18633+
18634+ if (count != sizeof (struct gr_arg_wrapper)) {
18635+ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
18636+ error = -EINVAL;
18637+ goto out;
18638+ }
18639+
18640+
18641+ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
18642+ gr_auth_expires = 0;
18643+ gr_auth_attempts = 0;
18644+ }
18645+
18646+ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
18647+ error = -EFAULT;
18648+ goto out;
18649+ }
18650+
18651+ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
18652+ error = -EINVAL;
18653+ goto out;
18654+ }
18655+
18656+ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
18657+ error = -EFAULT;
18658+ goto out;
18659+ }
18660+
18661+ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
18662+ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
18663+ time_after(gr_auth_expires, get_seconds())) {
18664+ error = -EBUSY;
18665+ goto out;
18666+ }
18667+
18668+ /* if non-root trying to do anything other than use a special role,
18669+ do not attempt authentication, do not count towards authentication
18670+ locking
18671+ */
18672+
18673+ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
18674+ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
18675+ current->uid) {
18676+ error = -EPERM;
18677+ goto out;
18678+ }
18679+
18680+ /* ensure pw and special role name are null terminated */
18681+
18682+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
18683+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
18684+
18685+ /* Okay.
18686+ * We have our enough of the argument structure..(we have yet
18687+ * to copy_from_user the tables themselves) . Copy the tables
18688+ * only if we need them, i.e. for loading operations. */
18689+
18690+ switch (gr_usermode->mode) {
18691+ case STATUS:
18692+ if (gr_status & GR_READY) {
18693+ error = 1;
18694+ if (!gr_check_secure_terminal(current))
18695+ error = 3;
18696+ } else
18697+ error = 2;
18698+ goto out;
18699+ case SHUTDOWN:
18700+ if ((gr_status & GR_READY)
18701+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
18702+ gr_status &= ~GR_READY;
18703+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
18704+ free_variables();
18705+ memset(gr_usermode, 0, sizeof (struct gr_arg));
18706+ memset(gr_system_salt, 0, GR_SALT_LEN);
18707+ memset(gr_system_sum, 0, GR_SHA_LEN);
18708+ } else if (gr_status & GR_READY) {
18709+ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
18710+ error = -EPERM;
18711+ } else {
18712+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
18713+ error = -EAGAIN;
18714+ }
18715+ break;
18716+ case ENABLE:
18717+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
18718+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
18719+ else {
18720+ if (gr_status & GR_READY)
18721+ error = -EAGAIN;
18722+ else
18723+ error = error2;
18724+ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
18725+ }
18726+ break;
18727+ case RELOAD:
18728+ if (!(gr_status & GR_READY)) {
18729+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
18730+ error = -EAGAIN;
18731+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
18732+ lock_kernel();
18733+ gr_status &= ~GR_READY;
18734+ free_variables();
18735+ if (!(error2 = gracl_init(gr_usermode))) {
18736+ unlock_kernel();
18737+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
18738+ } else {
18739+ unlock_kernel();
18740+ error = error2;
18741+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
18742+ }
18743+ } else {
18744+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
18745+ error = -EPERM;
18746+ }
18747+ break;
18748+ case SEGVMOD:
18749+ if (unlikely(!(gr_status & GR_READY))) {
18750+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
18751+ error = -EAGAIN;
18752+ break;
18753+ }
18754+
18755+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
18756+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
18757+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
18758+ struct acl_subject_label *segvacl;
18759+ segvacl =
18760+ lookup_acl_subj_label(gr_usermode->segv_inode,
18761+ gr_usermode->segv_device,
18762+ current->role);
18763+ if (segvacl) {
18764+ segvacl->crashes = 0;
18765+ segvacl->expires = 0;
18766+ }
18767+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
18768+ gr_remove_uid(gr_usermode->segv_uid);
18769+ }
18770+ } else {
18771+ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
18772+ error = -EPERM;
18773+ }
18774+ break;
18775+ case SPROLE:
18776+ case SPROLEPAM:
18777+ if (unlikely(!(gr_status & GR_READY))) {
18778+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
18779+ error = -EAGAIN;
18780+ break;
18781+ }
18782+
18783+ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
18784+ current->role->expires = 0;
18785+ current->role->auth_attempts = 0;
18786+ }
18787+
18788+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
18789+ time_after(current->role->expires, get_seconds())) {
18790+ error = -EBUSY;
18791+ goto out;
18792+ }
18793+
18794+ if (lookup_special_role_auth
18795+ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
18796+ && ((!sprole_salt && !sprole_sum)
18797+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
18798+ char *p = "";
18799+ assign_special_role(gr_usermode->sp_role);
18800+ read_lock(&tasklist_lock);
18801+ if (current->parent)
18802+ p = current->parent->role->rolename;
18803+ read_unlock(&tasklist_lock);
18804+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
18805+ p, acl_sp_role_value);
18806+ } else {
18807+ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
18808+ error = -EPERM;
18809+ if(!(current->role->auth_attempts++))
18810+ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
18811+
18812+ goto out;
18813+ }
18814+ break;
18815+ case UNSPROLE:
18816+ if (unlikely(!(gr_status & GR_READY))) {
18817+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
18818+ error = -EAGAIN;
18819+ break;
18820+ }
18821+
18822+ if (current->role->roletype & GR_ROLE_SPECIAL) {
18823+ char *p = "";
18824+ int i = 0;
18825+
18826+ read_lock(&tasklist_lock);
18827+ if (current->parent) {
18828+ p = current->parent->role->rolename;
18829+ i = current->parent->acl_role_id;
18830+ }
18831+ read_unlock(&tasklist_lock);
18832+
18833+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
18834+ gr_set_acls(1);
18835+ } else {
18836+ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
18837+ error = -EPERM;
18838+ goto out;
18839+ }
18840+ break;
18841+ default:
18842+ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
18843+ error = -EINVAL;
18844+ break;
18845+ }
18846+
18847+ if (error != -EPERM)
18848+ goto out;
18849+
18850+ if(!(gr_auth_attempts++))
18851+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
18852+
18853+ out:
18854+ up(&gr_dev_sem);
18855+ return error;
18856+}
18857+
18858+int
18859+gr_set_acls(const int type)
18860+{
18861+ struct acl_object_label *obj;
18862+ struct task_struct *task, *task2;
18863+ struct file *filp;
18864+ struct acl_role_label *role = current->role;
18865+ __u16 acl_role_id = current->acl_role_id;
18866+
18867+ read_lock(&tasklist_lock);
18868+ read_lock(&grsec_exec_file_lock);
18869+ do_each_thread(task2, task) {
18870+ /* check to see if we're called from the exit handler,
18871+ if so, only replace ACLs that have inherited the admin
18872+ ACL */
18873+
18874+ if (type && (task->role != role ||
18875+ task->acl_role_id != acl_role_id))
18876+ continue;
18877+
18878+ task->acl_role_id = 0;
18879+ task->acl_sp_role = 0;
18880+
18881+ if ((filp = task->exec_file)) {
18882+ task->role = lookup_acl_role_label(task, task->uid, task->gid);
18883+
18884+ task->acl =
18885+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
18886+ task->role);
18887+ if (task->acl) {
18888+ struct acl_subject_label *curr;
18889+ curr = task->acl;
18890+
18891+ task->is_writable = 0;
18892+ /* ignore additional mmap checks for processes that are writable
18893+ by the default ACL */
18894+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
18895+ if (unlikely(obj->mode & GR_WRITE))
18896+ task->is_writable = 1;
18897+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
18898+ if (unlikely(obj->mode & GR_WRITE))
18899+ task->is_writable = 1;
18900+
18901+ gr_set_proc_res(task);
18902+
18903+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
18904+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
18905+#endif
18906+ } else {
18907+ read_unlock(&grsec_exec_file_lock);
18908+ read_unlock(&tasklist_lock);
18909+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
18910+ return 1;
18911+ }
18912+ } else {
18913+ // it's a kernel process
18914+ task->role = kernel_role;
18915+ task->acl = kernel_role->root_label;
18916+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
18917+ task->acl->mode &= ~GR_PROCFIND;
18918+#endif
18919+ }
18920+ } while_each_thread(task2, task);
18921+ read_unlock(&grsec_exec_file_lock);
18922+ read_unlock(&tasklist_lock);
18923+ return 0;
18924+}
18925+
18926+void
18927+gr_learn_resource(const struct task_struct *task,
18928+ const int res, const unsigned long wanted, const int gt)
18929+{
18930+ struct acl_subject_label *acl;
18931+
18932+ if (unlikely((gr_status & GR_READY) &&
18933+ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
18934+ goto skip_reslog;
18935+
18936+#ifdef CONFIG_GRKERNSEC_RESLOG
18937+ gr_log_resource(task, res, wanted, gt);
18938+#endif
18939+ skip_reslog:
18940+
18941+ if (unlikely(!(gr_status & GR_READY) || !wanted))
18942+ return;
18943+
18944+ acl = task->acl;
18945+
18946+ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
18947+ !(acl->resmask & (1 << (unsigned short) res))))
18948+ return;
18949+
18950+ if (wanted >= acl->res[res].rlim_cur) {
18951+ unsigned long res_add;
18952+
18953+ res_add = wanted;
18954+ switch (res) {
18955+ case RLIMIT_CPU:
18956+ res_add += GR_RLIM_CPU_BUMP;
18957+ break;
18958+ case RLIMIT_FSIZE:
18959+ res_add += GR_RLIM_FSIZE_BUMP;
18960+ break;
18961+ case RLIMIT_DATA:
18962+ res_add += GR_RLIM_DATA_BUMP;
18963+ break;
18964+ case RLIMIT_STACK:
18965+ res_add += GR_RLIM_STACK_BUMP;
18966+ break;
18967+ case RLIMIT_CORE:
18968+ res_add += GR_RLIM_CORE_BUMP;
18969+ break;
18970+ case RLIMIT_RSS:
18971+ res_add += GR_RLIM_RSS_BUMP;
18972+ break;
18973+ case RLIMIT_NPROC:
18974+ res_add += GR_RLIM_NPROC_BUMP;
18975+ break;
18976+ case RLIMIT_NOFILE:
18977+ res_add += GR_RLIM_NOFILE_BUMP;
18978+ break;
18979+ case RLIMIT_MEMLOCK:
18980+ res_add += GR_RLIM_MEMLOCK_BUMP;
18981+ break;
18982+ case RLIMIT_AS:
18983+ res_add += GR_RLIM_AS_BUMP;
18984+ break;
18985+ case RLIMIT_LOCKS:
18986+ res_add += GR_RLIM_LOCKS_BUMP;
18987+ break;
18988+ }
18989+
18990+ acl->res[res].rlim_cur = res_add;
18991+
18992+ if (wanted > acl->res[res].rlim_max)
18993+ acl->res[res].rlim_max = res_add;
18994+
18995+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
18996+ task->role->roletype, acl->filename,
18997+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
18998+ "", (unsigned long) res);
18999+ }
19000+
19001+ return;
19002+}
19003+
19004+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
19005+void
19006+pax_set_initial_flags(struct linux_binprm *bprm)
19007+{
19008+ struct task_struct *task = current;
19009+ struct acl_subject_label *proc;
19010+ unsigned long flags;
19011+
19012+ if (unlikely(!(gr_status & GR_READY)))
19013+ return;
19014+
19015+ flags = pax_get_flags(task);
19016+
19017+ proc = task->acl;
19018+
19019+ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
19020+ flags &= ~MF_PAX_PAGEEXEC;
19021+ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
19022+ flags &= ~MF_PAX_SEGMEXEC;
19023+ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
19024+ flags &= ~MF_PAX_RANDMMAP;
19025+ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
19026+ flags &= ~MF_PAX_EMUTRAMP;
19027+ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
19028+ flags &= ~MF_PAX_MPROTECT;
19029+
19030+ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
19031+ flags |= MF_PAX_PAGEEXEC;
19032+ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
19033+ flags |= MF_PAX_SEGMEXEC;
19034+ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
19035+ flags |= MF_PAX_RANDMMAP;
19036+ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
19037+ flags |= MF_PAX_EMUTRAMP;
19038+ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
19039+ flags |= MF_PAX_MPROTECT;
19040+
19041+ pax_set_flags(task, flags);
19042+
19043+ return;
19044+}
19045+#endif
19046+
19047+#ifdef CONFIG_SYSCTL
19048+/* Eric Biederman likes breaking userland ABI and every inode-based security
19049+ system to save 35kb of memory */
19050+
19051+/* we modify the passed in filename, but adjust it back before returning */
19052+static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
19053+{
19054+ struct name_entry *nmatch;
19055+ char *p, *lastp = NULL;
19056+ struct acl_object_label *obj = NULL, *tmp;
19057+ struct acl_subject_label *tmpsubj;
19058+ int done = 0;
19059+ char c = '\0';
19060+
19061+ read_lock(&gr_inode_lock);
19062+
19063+ p = name + len - 1;
19064+ do {
19065+ nmatch = lookup_name_entry(name);
19066+ if (lastp != NULL)
19067+ *lastp = c;
19068+
19069+ if (nmatch == NULL)
19070+ goto next_component;
19071+ tmpsubj = current->acl;
19072+ do {
19073+ obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
19074+ if (obj != NULL) {
19075+ tmp = obj->globbed;
19076+ while (tmp) {
19077+ if (!glob_match(tmp->filename, name)) {
19078+ obj = tmp;
19079+ goto found_obj;
19080+ }
19081+ tmp = tmp->next;
19082+ }
19083+ goto found_obj;
19084+ }
19085+ } while ((tmpsubj = tmpsubj->parent_subject));
19086+next_component:
19087+ /* end case */
19088+ if (p == name)
19089+ break;
19090+
19091+ while (*p != '/')
19092+ p--;
19093+ if (p == name)
19094+ lastp = p + 1;
19095+ else {
19096+ lastp = p;
19097+ p--;
19098+ }
19099+ c = *lastp;
19100+ *lastp = '\0';
19101+ } while (1);
19102+found_obj:
19103+ read_unlock(&gr_inode_lock);
19104+ /* obj returned will always be non-null */
19105+ return obj;
19106+}
19107+
19108+/* returns 0 when allowing, non-zero on error
19109+ op of 0 is used for readdir, so we don't log the names of hidden files
19110+*/
19111+__u32
19112+gr_handle_sysctl(const struct ctl_table *table, const int op)
19113+{
19114+ ctl_table *tmp;
19115+ struct nameidata nd;
19116+ const char *proc_sys = "/proc/sys";
19117+ char *path;
19118+ struct acl_object_label *obj;
19119+ unsigned short len = 0, pos = 0, depth = 0, i;
19120+ __u32 err = 0;
19121+ __u32 mode = 0;
19122+
19123+ if (unlikely(!(gr_status & GR_READY)))
19124+ return 0;
19125+
19126+ /* for now, ignore operations on non-sysctl entries if it's not a
19127+ readdir*/
19128+ if (table->child != NULL && op != 0)
19129+ return 0;
19130+
19131+ mode |= GR_FIND;
19132+ /* it's only a read if it's an entry, read on dirs is for readdir */
19133+ if (op & 004)
19134+ mode |= GR_READ;
19135+ if (op & 002)
19136+ mode |= GR_WRITE;
19137+
19138+ preempt_disable();
19139+
19140+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
19141+
19142+ /* it's only a read/write if it's an actual entry, not a dir
19143+ (which are opened for readdir)
19144+ */
19145+
19146+ /* convert the requested sysctl entry into a pathname */
19147+
19148+ for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
19149+ len += strlen(tmp->procname);
19150+ len++;
19151+ depth++;
19152+ }
19153+
19154+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
19155+ /* deny */
19156+ goto out;
19157+ }
19158+
19159+ memset(path, 0, PAGE_SIZE);
19160+
19161+ memcpy(path, proc_sys, strlen(proc_sys));
19162+
19163+ pos += strlen(proc_sys);
19164+
19165+ for (; depth > 0; depth--) {
19166+ path[pos] = '/';
19167+ pos++;
19168+ for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
19169+ if (depth == i) {
19170+ memcpy(path + pos, tmp->procname,
19171+ strlen(tmp->procname));
19172+ pos += strlen(tmp->procname);
19173+ }
19174+ i++;
19175+ }
19176+ }
19177+
19178+ obj = gr_lookup_by_name(path, pos);
19179+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
19180+
19181+ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
19182+ ((err & mode) != mode))) {
19183+ __u32 new_mode = mode;
19184+
19185+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19186+
19187+ err = 0;
19188+ gr_log_learn_sysctl(current, path, new_mode);
19189+ } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
19190+ gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
19191+ err = -ENOENT;
19192+ } else if (!(err & GR_FIND)) {
19193+ err = -ENOENT;
19194+ } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
19195+ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
19196+ path, (mode & GR_READ) ? " reading" : "",
19197+ (mode & GR_WRITE) ? " writing" : "");
19198+ err = -EACCES;
19199+ } else if ((err & mode) != mode) {
19200+ err = -EACCES;
19201+ } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
19202+ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
19203+ path, (mode & GR_READ) ? " reading" : "",
19204+ (mode & GR_WRITE) ? " writing" : "");
19205+ err = 0;
19206+ } else
19207+ err = 0;
19208+
19209+ out:
19210+ preempt_enable();
19211+
19212+ return err;
19213+}
19214+#endif
19215+
19216+int
19217+gr_handle_proc_ptrace(struct task_struct *task)
19218+{
19219+ struct file *filp;
19220+ struct task_struct *tmp = task;
19221+ struct task_struct *curtemp = current;
19222+ __u32 retmode;
19223+
19224+ if (unlikely(!(gr_status & GR_READY)))
19225+ return 0;
19226+
19227+ read_lock(&tasklist_lock);
19228+ read_lock(&grsec_exec_file_lock);
19229+ filp = task->exec_file;
19230+
19231+ while (tmp->pid > 0) {
19232+ if (tmp == curtemp)
19233+ break;
19234+ tmp = tmp->parent;
19235+ }
19236+
19237+ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
19238+ read_unlock(&grsec_exec_file_lock);
19239+ read_unlock(&tasklist_lock);
19240+ return 1;
19241+ }
19242+
19243+ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
19244+ read_unlock(&grsec_exec_file_lock);
19245+ read_unlock(&tasklist_lock);
19246+
19247+ if (retmode & GR_NOPTRACE)
19248+ return 1;
19249+
19250+ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
19251+ && (current->acl != task->acl || (current->acl != current->role->root_label
19252+ && current->pid != task->pid)))
19253+ return 1;
19254+
19255+ return 0;
19256+}
19257+
19258+int
19259+gr_handle_ptrace(struct task_struct *task, const long request)
19260+{
19261+ struct task_struct *tmp = task;
19262+ struct task_struct *curtemp = current;
19263+ __u32 retmode;
19264+
19265+ if (unlikely(!(gr_status & GR_READY)))
19266+ return 0;
19267+
19268+ read_lock(&tasklist_lock);
19269+ while (tmp->pid > 0) {
19270+ if (tmp == curtemp)
19271+ break;
19272+ tmp = tmp->parent;
19273+ }
19274+
19275+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
19276+ read_unlock(&tasklist_lock);
19277+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
19278+ return 1;
19279+ }
19280+ read_unlock(&tasklist_lock);
19281+
19282+ read_lock(&grsec_exec_file_lock);
19283+ if (unlikely(!task->exec_file)) {
19284+ read_unlock(&grsec_exec_file_lock);
19285+ return 0;
19286+ }
19287+
19288+ retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
19289+ read_unlock(&grsec_exec_file_lock);
19290+
19291+ if (retmode & GR_NOPTRACE) {
19292+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
19293+ return 1;
19294+ }
19295+
19296+ if (retmode & GR_PTRACERD) {
19297+ switch (request) {
19298+ case PTRACE_POKETEXT:
19299+ case PTRACE_POKEDATA:
19300+ case PTRACE_POKEUSR:
19301+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
19302+ case PTRACE_SETREGS:
19303+ case PTRACE_SETFPREGS:
19304+#endif
19305+#ifdef CONFIG_X86
19306+ case PTRACE_SETFPXREGS:
19307+#endif
19308+#ifdef CONFIG_ALTIVEC
19309+ case PTRACE_SETVRREGS:
19310+#endif
19311+ return 1;
19312+ default:
19313+ return 0;
19314+ }
19315+ } else if (!(current->acl->mode & GR_POVERRIDE) &&
19316+ !(current->role->roletype & GR_ROLE_GOD) &&
19317+ (current->acl != task->acl)) {
19318+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
19319+ return 1;
19320+ }
19321+
19322+ return 0;
19323+}
19324+
19325+static int is_writable_mmap(const struct file *filp)
19326+{
19327+ struct task_struct *task = current;
19328+ struct acl_object_label *obj, *obj2;
19329+
19330+ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
19331+ !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
19332+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
19333+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
19334+ task->role->root_label);
19335+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
19336+ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
19337+ return 1;
19338+ }
19339+ }
19340+ return 0;
19341+}
19342+
19343+int
19344+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
19345+{
19346+ __u32 mode;
19347+
19348+ if (unlikely(!file || !(prot & PROT_EXEC)))
19349+ return 1;
19350+
19351+ if (is_writable_mmap(file))
19352+ return 0;
19353+
19354+ mode =
19355+ gr_search_file(file->f_dentry,
19356+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
19357+ file->f_vfsmnt);
19358+
19359+ if (!gr_tpe_allow(file))
19360+ return 0;
19361+
19362+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
19363+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
19364+ return 0;
19365+ } else if (unlikely(!(mode & GR_EXEC))) {
19366+ return 0;
19367+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
19368+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
19369+ return 1;
19370+ }
19371+
19372+ return 1;
19373+}
19374+
19375+int
19376+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
19377+{
19378+ __u32 mode;
19379+
19380+ if (unlikely(!file || !(prot & PROT_EXEC)))
19381+ return 1;
19382+
19383+ if (is_writable_mmap(file))
19384+ return 0;
19385+
19386+ mode =
19387+ gr_search_file(file->f_dentry,
19388+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
19389+ file->f_vfsmnt);
19390+
19391+ if (!gr_tpe_allow(file))
19392+ return 0;
19393+
19394+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
19395+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
19396+ return 0;
19397+ } else if (unlikely(!(mode & GR_EXEC))) {
19398+ return 0;
19399+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
19400+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
19401+ return 1;
19402+ }
19403+
19404+ return 1;
19405+}
19406+
19407+void
19408+gr_acl_handle_psacct(struct task_struct *task, const long code)
19409+{
19410+ unsigned long runtime;
19411+ unsigned long cputime;
19412+ unsigned int wday, cday;
19413+ __u8 whr, chr;
19414+ __u8 wmin, cmin;
19415+ __u8 wsec, csec;
19416+
19417+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
19418+ !(task->acl->mode & GR_PROCACCT)))
19419+ return;
19420+
19421+ runtime = xtime.tv_sec - task->start_time.tv_sec;
19422+ wday = runtime / (3600 * 24);
19423+ runtime -= wday * (3600 * 24);
19424+ whr = runtime / 3600;
19425+ runtime -= whr * 3600;
19426+ wmin = runtime / 60;
19427+ runtime -= wmin * 60;
19428+ wsec = runtime;
19429+
19430+ cputime = (task->utime + task->stime) / HZ;
19431+ cday = cputime / (3600 * 24);
19432+ cputime -= cday * (3600 * 24);
19433+ chr = cputime / 3600;
19434+ cputime -= chr * 3600;
19435+ cmin = cputime / 60;
19436+ cputime -= cmin * 60;
19437+ csec = cputime;
19438+
19439+ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
19440+
19441+ return;
19442+}
19443+
19444+void gr_set_kernel_label(struct task_struct *task)
19445+{
19446+ if (gr_status & GR_READY) {
19447+ task->role = kernel_role;
19448+ task->acl = kernel_role->root_label;
19449+ }
19450+ return;
19451+}
19452+
19453+int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
19454+{
19455+ struct task_struct *task = current;
19456+ struct dentry *dentry = file->f_dentry;
19457+ struct vfsmount *mnt = file->f_vfsmnt;
19458+ struct acl_object_label *obj, *tmp;
19459+ struct acl_subject_label *subj;
19460+ unsigned int bufsize;
19461+ int is_not_root;
19462+ char *path;
19463+
19464+ if (unlikely(!(gr_status & GR_READY)))
19465+ return 1;
19466+
19467+ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19468+ return 1;
19469+
19470+ /* ignore Eric Biederman */
19471+ if (IS_PRIVATE(dentry->d_inode))
19472+ return 1;
19473+
19474+ subj = task->acl;
19475+ do {
19476+ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
19477+ if (obj != NULL)
19478+ return (obj->mode & GR_FIND) ? 1 : 0;
19479+ } while ((subj = subj->parent_subject));
19480+
19481+ obj = chk_obj_label(dentry, mnt, task->acl);
19482+ if (obj->globbed == NULL)
19483+ return (obj->mode & GR_FIND) ? 1 : 0;
19484+
19485+ is_not_root = ((obj->filename[0] == '/') &&
19486+ (obj->filename[1] == '\0')) ? 0 : 1;
19487+ bufsize = PAGE_SIZE - namelen - is_not_root;
19488+
19489+ /* check bufsize > PAGE_SIZE || bufsize == 0 */
19490+ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
19491+ return 1;
19492+
19493+ preempt_disable();
19494+ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
19495+ bufsize);
19496+
19497+ bufsize = strlen(path);
19498+
19499+ /* if base is "/", don't append an additional slash */
19500+ if (is_not_root)
19501+ *(path + bufsize) = '/';
19502+ memcpy(path + bufsize + is_not_root, name, namelen);
19503+ *(path + bufsize + namelen + is_not_root) = '\0';
19504+
19505+ tmp = obj->globbed;
19506+ while (tmp) {
19507+ if (!glob_match(tmp->filename, path)) {
19508+ preempt_enable();
19509+ return (tmp->mode & GR_FIND) ? 1 : 0;
19510+ }
19511+ tmp = tmp->next;
19512+ }
19513+ preempt_enable();
19514+ return (obj->mode & GR_FIND) ? 1 : 0;
19515+}
19516+
19517+EXPORT_SYMBOL(gr_learn_resource);
19518+EXPORT_SYMBOL(gr_set_kernel_label);
19519+#ifdef CONFIG_SECURITY
19520+EXPORT_SYMBOL(gr_check_user_change);
19521+EXPORT_SYMBOL(gr_check_group_change);
19522+#endif
19523+
19524diff -urNp linux-2.6.22.1/grsecurity/gracl_cap.c linux-2.6.22.1/grsecurity/gracl_cap.c
19525--- linux-2.6.22.1/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
19526+++ linux-2.6.22.1/grsecurity/gracl_cap.c 2007-08-02 12:24:21.000000000 -0400
19527@@ -0,0 +1,112 @@
19528+#include <linux/kernel.h>
19529+#include <linux/module.h>
19530+#include <linux/sched.h>
19531+#include <linux/capability.h>
19532+#include <linux/gracl.h>
19533+#include <linux/grsecurity.h>
19534+#include <linux/grinternal.h>
19535+
19536+static const char *captab_log[] = {
19537+ "CAP_CHOWN",
19538+ "CAP_DAC_OVERRIDE",
19539+ "CAP_DAC_READ_SEARCH",
19540+ "CAP_FOWNER",
19541+ "CAP_FSETID",
19542+ "CAP_KILL",
19543+ "CAP_SETGID",
19544+ "CAP_SETUID",
19545+ "CAP_SETPCAP",
19546+ "CAP_LINUX_IMMUTABLE",
19547+ "CAP_NET_BIND_SERVICE",
19548+ "CAP_NET_BROADCAST",
19549+ "CAP_NET_ADMIN",
19550+ "CAP_NET_RAW",
19551+ "CAP_IPC_LOCK",
19552+ "CAP_IPC_OWNER",
19553+ "CAP_SYS_MODULE",
19554+ "CAP_SYS_RAWIO",
19555+ "CAP_SYS_CHROOT",
19556+ "CAP_SYS_PTRACE",
19557+ "CAP_SYS_PACCT",
19558+ "CAP_SYS_ADMIN",
19559+ "CAP_SYS_BOOT",
19560+ "CAP_SYS_NICE",
19561+ "CAP_SYS_RESOURCE",
19562+ "CAP_SYS_TIME",
19563+ "CAP_SYS_TTY_CONFIG",
19564+ "CAP_MKNOD",
19565+ "CAP_LEASE",
19566+ "CAP_AUDIT_WRITE",
19567+ "CAP_AUDIT_CONTROL"
19568+};
19569+
19570+EXPORT_SYMBOL(gr_task_is_capable);
19571+EXPORT_SYMBOL(gr_is_capable_nolog);
19572+
19573+int
19574+gr_task_is_capable(struct task_struct *task, const int cap)
19575+{
19576+ struct acl_subject_label *curracl;
19577+ __u32 cap_drop = 0, cap_mask = 0;
19578+
19579+ if (!gr_acl_is_enabled())
19580+ return 1;
19581+
19582+ curracl = task->acl;
19583+
19584+ cap_drop = curracl->cap_lower;
19585+ cap_mask = curracl->cap_mask;
19586+
19587+ while ((curracl = curracl->parent_subject)) {
19588+ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
19589+ cap_drop |= curracl->cap_lower & (1 << cap);
19590+ cap_mask |= curracl->cap_mask;
19591+ }
19592+
19593+ if (!cap_raised(cap_drop, cap))
19594+ return 1;
19595+
19596+ curracl = task->acl;
19597+
19598+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
19599+ && cap_raised(task->cap_effective, cap)) {
19600+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
19601+ task->role->roletype, task->uid,
19602+ task->gid, task->exec_file ?
19603+ gr_to_filename(task->exec_file->f_dentry,
19604+ task->exec_file->f_vfsmnt) : curracl->filename,
19605+ curracl->filename, 0UL,
19606+ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
19607+ return 1;
19608+ }
19609+
19610+ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
19611+ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
19612+ return 0;
19613+}
19614+
19615+int
19616+gr_is_capable_nolog(const int cap)
19617+{
19618+ struct acl_subject_label *curracl;
19619+ __u32 cap_drop = 0, cap_mask = 0;
19620+
19621+ if (!gr_acl_is_enabled())
19622+ return 1;
19623+
19624+ curracl = current->acl;
19625+
19626+ cap_drop = curracl->cap_lower;
19627+ cap_mask = curracl->cap_mask;
19628+
19629+ while ((curracl = curracl->parent_subject)) {
19630+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
19631+ cap_mask |= curracl->cap_mask;
19632+ }
19633+
19634+ if (!cap_raised(cap_drop, cap))
19635+ return 1;
19636+
19637+ return 0;
19638+}
19639+
19640diff -urNp linux-2.6.22.1/grsecurity/gracl_fs.c linux-2.6.22.1/grsecurity/gracl_fs.c
19641--- linux-2.6.22.1/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
19642+++ linux-2.6.22.1/grsecurity/gracl_fs.c 2007-08-02 11:09:16.000000000 -0400
19643@@ -0,0 +1,423 @@
19644+#include <linux/kernel.h>
19645+#include <linux/sched.h>
19646+#include <linux/types.h>
19647+#include <linux/fs.h>
19648+#include <linux/file.h>
19649+#include <linux/stat.h>
19650+#include <linux/grsecurity.h>
19651+#include <linux/grinternal.h>
19652+#include <linux/gracl.h>
19653+
19654+__u32
19655+gr_acl_handle_hidden_file(const struct dentry * dentry,
19656+ const struct vfsmount * mnt)
19657+{
19658+ __u32 mode;
19659+
19660+ if (unlikely(!dentry->d_inode))
19661+ return GR_FIND;
19662+
19663+ mode =
19664+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
19665+
19666+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
19667+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
19668+ return mode;
19669+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
19670+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
19671+ return 0;
19672+ } else if (unlikely(!(mode & GR_FIND)))
19673+ return 0;
19674+
19675+ return GR_FIND;
19676+}
19677+
19678+__u32
19679+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
19680+ const int fmode)
19681+{
19682+ __u32 reqmode = GR_FIND;
19683+ __u32 mode;
19684+
19685+ if (unlikely(!dentry->d_inode))
19686+ return reqmode;
19687+
19688+ if (unlikely(fmode & O_APPEND))
19689+ reqmode |= GR_APPEND;
19690+ else if (unlikely(fmode & FMODE_WRITE))
19691+ reqmode |= GR_WRITE;
19692+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
19693+ reqmode |= GR_READ;
19694+
19695+ mode =
19696+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
19697+ mnt);
19698+
19699+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
19700+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
19701+ reqmode & GR_READ ? " reading" : "",
19702+ reqmode & GR_WRITE ? " writing" : reqmode &
19703+ GR_APPEND ? " appending" : "");
19704+ return reqmode;
19705+ } else
19706+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
19707+ {
19708+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
19709+ reqmode & GR_READ ? " reading" : "",
19710+ reqmode & GR_WRITE ? " writing" : reqmode &
19711+ GR_APPEND ? " appending" : "");
19712+ return 0;
19713+ } else if (unlikely((mode & reqmode) != reqmode))
19714+ return 0;
19715+
19716+ return reqmode;
19717+}
19718+
19719+__u32
19720+gr_acl_handle_creat(const struct dentry * dentry,
19721+ const struct dentry * p_dentry,
19722+ const struct vfsmount * p_mnt, const int fmode,
19723+ const int imode)
19724+{
19725+ __u32 reqmode = GR_WRITE | GR_CREATE;
19726+ __u32 mode;
19727+
19728+ if (unlikely(fmode & O_APPEND))
19729+ reqmode |= GR_APPEND;
19730+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
19731+ reqmode |= GR_READ;
19732+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
19733+ reqmode |= GR_SETID;
19734+
19735+ mode =
19736+ gr_check_create(dentry, p_dentry, p_mnt,
19737+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
19738+
19739+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
19740+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
19741+ reqmode & GR_READ ? " reading" : "",
19742+ reqmode & GR_WRITE ? " writing" : reqmode &
19743+ GR_APPEND ? " appending" : "");
19744+ return reqmode;
19745+ } else
19746+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
19747+ {
19748+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
19749+ reqmode & GR_READ ? " reading" : "",
19750+ reqmode & GR_WRITE ? " writing" : reqmode &
19751+ GR_APPEND ? " appending" : "");
19752+ return 0;
19753+ } else if (unlikely((mode & reqmode) != reqmode))
19754+ return 0;
19755+
19756+ return reqmode;
19757+}
19758+
19759+__u32
19760+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
19761+ const int fmode)
19762+{
19763+ __u32 mode, reqmode = GR_FIND;
19764+
19765+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
19766+ reqmode |= GR_EXEC;
19767+ if (fmode & S_IWOTH)
19768+ reqmode |= GR_WRITE;
19769+ if (fmode & S_IROTH)
19770+ reqmode |= GR_READ;
19771+
19772+ mode =
19773+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
19774+ mnt);
19775+
19776+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
19777+ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
19778+ reqmode & GR_READ ? " reading" : "",
19779+ reqmode & GR_WRITE ? " writing" : "",
19780+ reqmode & GR_EXEC ? " executing" : "");
19781+ return reqmode;
19782+ } else
19783+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
19784+ {
19785+ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
19786+ reqmode & GR_READ ? " reading" : "",
19787+ reqmode & GR_WRITE ? " writing" : "",
19788+ reqmode & GR_EXEC ? " executing" : "");
19789+ return 0;
19790+ } else if (unlikely((mode & reqmode) != reqmode))
19791+ return 0;
19792+
19793+ return reqmode;
19794+}
19795+
19796+static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
19797+{
19798+ __u32 mode;
19799+
19800+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
19801+
19802+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
19803+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
19804+ return mode;
19805+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
19806+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
19807+ return 0;
19808+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
19809+ return 0;
19810+
19811+ return (reqmode);
19812+}
19813+
19814+__u32
19815+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
19816+{
19817+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
19818+}
19819+
19820+__u32
19821+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
19822+{
19823+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
19824+}
19825+
19826+__u32
19827+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
19828+{
19829+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
19830+}
19831+
19832+__u32
19833+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
19834+{
19835+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
19836+}
19837+
19838+__u32
19839+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
19840+ mode_t mode)
19841+{
19842+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
19843+ return 1;
19844+
19845+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
19846+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
19847+ GR_FCHMOD_ACL_MSG);
19848+ } else {
19849+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
19850+ }
19851+}
19852+
19853+__u32
19854+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
19855+ mode_t mode)
19856+{
19857+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
19858+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
19859+ GR_CHMOD_ACL_MSG);
19860+ } else {
19861+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
19862+ }
19863+}
19864+
19865+__u32
19866+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
19867+{
19868+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
19869+}
19870+
19871+__u32
19872+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
19873+{
19874+ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
19875+}
19876+
19877+__u32
19878+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
19879+{
19880+ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
19881+ GR_UNIXCONNECT_ACL_MSG);
19882+}
19883+
19884+/* hardlinks require at minimum create permission,
19885+ any additional privilege required is based on the
19886+ privilege of the file being linked to
19887+*/
19888+__u32
19889+gr_acl_handle_link(const struct dentry * new_dentry,
19890+ const struct dentry * parent_dentry,
19891+ const struct vfsmount * parent_mnt,
19892+ const struct dentry * old_dentry,
19893+ const struct vfsmount * old_mnt, const char *to)
19894+{
19895+ __u32 mode;
19896+ __u32 needmode = GR_CREATE | GR_LINK;
19897+ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
19898+
19899+ mode =
19900+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
19901+ old_mnt);
19902+
19903+ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
19904+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
19905+ return mode;
19906+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
19907+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
19908+ return 0;
19909+ } else if (unlikely((mode & needmode) != needmode))
19910+ return 0;
19911+
19912+ return 1;
19913+}
19914+
19915+__u32
19916+gr_acl_handle_symlink(const struct dentry * new_dentry,
19917+ const struct dentry * parent_dentry,
19918+ const struct vfsmount * parent_mnt, const char *from)
19919+{
19920+ __u32 needmode = GR_WRITE | GR_CREATE;
19921+ __u32 mode;
19922+
19923+ mode =
19924+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
19925+ GR_CREATE | GR_AUDIT_CREATE |
19926+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
19927+
19928+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
19929+ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
19930+ return mode;
19931+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
19932+ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
19933+ return 0;
19934+ } else if (unlikely((mode & needmode) != needmode))
19935+ return 0;
19936+
19937+ return (GR_WRITE | GR_CREATE);
19938+}
19939+
19940+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)
19941+{
19942+ __u32 mode;
19943+
19944+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
19945+
19946+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
19947+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
19948+ return mode;
19949+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
19950+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
19951+ return 0;
19952+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
19953+ return 0;
19954+
19955+ return (reqmode);
19956+}
19957+
19958+__u32
19959+gr_acl_handle_mknod(const struct dentry * new_dentry,
19960+ const struct dentry * parent_dentry,
19961+ const struct vfsmount * parent_mnt,
19962+ const int mode)
19963+{
19964+ __u32 reqmode = GR_WRITE | GR_CREATE;
19965+ if (unlikely(mode & (S_ISUID | S_ISGID)))
19966+ reqmode |= GR_SETID;
19967+
19968+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
19969+ reqmode, GR_MKNOD_ACL_MSG);
19970+}
19971+
19972+__u32
19973+gr_acl_handle_mkdir(const struct dentry *new_dentry,
19974+ const struct dentry *parent_dentry,
19975+ const struct vfsmount *parent_mnt)
19976+{
19977+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
19978+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
19979+}
19980+
19981+#define RENAME_CHECK_SUCCESS(old, new) \
19982+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
19983+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
19984+
19985+int
19986+gr_acl_handle_rename(struct dentry *new_dentry,
19987+ struct dentry *parent_dentry,
19988+ const struct vfsmount *parent_mnt,
19989+ struct dentry *old_dentry,
19990+ struct inode *old_parent_inode,
19991+ struct vfsmount *old_mnt, const char *newname)
19992+{
19993+ __u32 comp1, comp2;
19994+ int error = 0;
19995+
19996+ if (unlikely(!gr_acl_is_enabled()))
19997+ return 0;
19998+
19999+ if (!new_dentry->d_inode) {
20000+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
20001+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
20002+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
20003+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
20004+ GR_DELETE | GR_AUDIT_DELETE |
20005+ GR_AUDIT_READ | GR_AUDIT_WRITE |
20006+ GR_SUPPRESS, old_mnt);
20007+ } else {
20008+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
20009+ GR_CREATE | GR_DELETE |
20010+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
20011+ GR_AUDIT_READ | GR_AUDIT_WRITE |
20012+ GR_SUPPRESS, parent_mnt);
20013+ comp2 =
20014+ gr_search_file(old_dentry,
20015+ GR_READ | GR_WRITE | GR_AUDIT_READ |
20016+ GR_DELETE | GR_AUDIT_DELETE |
20017+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
20018+ }
20019+
20020+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
20021+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
20022+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
20023+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
20024+ && !(comp2 & GR_SUPPRESS)) {
20025+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
20026+ error = -EACCES;
20027+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
20028+ error = -EACCES;
20029+
20030+ return error;
20031+}
20032+
20033+void
20034+gr_acl_handle_exit(void)
20035+{
20036+ u16 id;
20037+ char *rolename;
20038+ struct file *exec_file;
20039+
20040+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
20041+ id = current->acl_role_id;
20042+ rolename = current->role->rolename;
20043+ gr_set_acls(1);
20044+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
20045+ }
20046+
20047+ write_lock(&grsec_exec_file_lock);
20048+ exec_file = current->exec_file;
20049+ current->exec_file = NULL;
20050+ write_unlock(&grsec_exec_file_lock);
20051+
20052+ if (exec_file)
20053+ fput(exec_file);
20054+}
20055+
20056+int
20057+gr_acl_handle_procpidmem(const struct task_struct *task)
20058+{
20059+ if (unlikely(!gr_acl_is_enabled()))
20060+ return 0;
20061+
20062+ if (task->acl->mode & GR_PROTPROCFD)
20063+ return -EACCES;
20064+
20065+ return 0;
20066+}
20067diff -urNp linux-2.6.22.1/grsecurity/gracl_ip.c linux-2.6.22.1/grsecurity/gracl_ip.c
20068--- linux-2.6.22.1/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
20069+++ linux-2.6.22.1/grsecurity/gracl_ip.c 2007-08-02 11:56:40.000000000 -0400
20070@@ -0,0 +1,313 @@
20071+#include <linux/kernel.h>
20072+#include <asm/uaccess.h>
20073+#include <asm/errno.h>
20074+#include <net/sock.h>
20075+#include <linux/file.h>
20076+#include <linux/fs.h>
20077+#include <linux/net.h>
20078+#include <linux/in.h>
20079+#include <linux/skbuff.h>
20080+#include <linux/ip.h>
20081+#include <linux/udp.h>
20082+#include <linux/smp_lock.h>
20083+#include <linux/types.h>
20084+#include <linux/sched.h>
20085+#include <linux/netdevice.h>
20086+#include <linux/inetdevice.h>
20087+#include <linux/gracl.h>
20088+#include <linux/grsecurity.h>
20089+#include <linux/grinternal.h>
20090+
20091+#define GR_BIND 0x01
20092+#define GR_CONNECT 0x02
20093+#define GR_INVERT 0x04
20094+
20095+static const char * gr_protocols[256] = {
20096+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
20097+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
20098+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
20099+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
20100+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
20101+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
20102+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
20103+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
20104+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
20105+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
20106+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
20107+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
20108+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
20109+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
20110+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
20111+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
20112+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
20113+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
20114+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
20115+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
20116+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
20117+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
20118+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
20119+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
20120+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
20121+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
20122+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
20123+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
20124+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
20125+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
20126+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
20127+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
20128+ };
20129+
20130+static const char * gr_socktypes[11] = {
20131+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
20132+ "unknown:7", "unknown:8", "unknown:9", "packet"
20133+ };
20134+
20135+const char *
20136+gr_proto_to_name(unsigned char proto)
20137+{
20138+ return gr_protocols[proto];
20139+}
20140+
20141+const char *
20142+gr_socktype_to_name(unsigned char type)
20143+{
20144+ return gr_socktypes[type];
20145+}
20146+
20147+int
20148+gr_search_socket(const int domain, const int type, const int protocol)
20149+{
20150+ struct acl_subject_label *curr;
20151+
20152+ if (unlikely(!gr_acl_is_enabled()))
20153+ goto exit;
20154+
20155+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
20156+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
20157+ goto exit; // let the kernel handle it
20158+
20159+ curr = current->acl;
20160+
20161+ if (!curr->ips)
20162+ goto exit;
20163+
20164+ if ((curr->ip_type & (1 << type)) &&
20165+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
20166+ goto exit;
20167+
20168+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
20169+ /* we don't place acls on raw sockets , and sometimes
20170+ dgram/ip sockets are opened for ioctl and not
20171+ bind/connect, so we'll fake a bind learn log */
20172+ if (type == SOCK_RAW || type == SOCK_PACKET) {
20173+ __u32 fakeip = 0;
20174+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
20175+ current->role->roletype, current->uid,
20176+ current->gid, current->exec_file ?
20177+ gr_to_filename(current->exec_file->f_dentry,
20178+ current->exec_file->f_vfsmnt) :
20179+ curr->filename, curr->filename,
20180+ NIPQUAD(fakeip), 0, type,
20181+ protocol, GR_CONNECT,
20182+NIPQUAD(current->signal->curr_ip));
20183+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
20184+ __u32 fakeip = 0;
20185+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
20186+ current->role->roletype, current->uid,
20187+ current->gid, current->exec_file ?
20188+ gr_to_filename(current->exec_file->f_dentry,
20189+ current->exec_file->f_vfsmnt) :
20190+ curr->filename, curr->filename,
20191+ NIPQUAD(fakeip), 0, type,
20192+ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
20193+ }
20194+ /* we'll log when they use connect or bind */
20195+ goto exit;
20196+ }
20197+
20198+ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
20199+ gr_socktype_to_name(type), gr_proto_to_name(protocol));
20200+
20201+ return 0;
20202+ exit:
20203+ return 1;
20204+}
20205+
20206+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)
20207+{
20208+ if ((ip->mode & mode) &&
20209+ (ip_port >= ip->low) &&
20210+ (ip_port <= ip->high) &&
20211+ ((ntohl(ip_addr) & our_netmask) ==
20212+ (ntohl(our_addr) & our_netmask))
20213+ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
20214+ && (ip->type & (1 << type))) {
20215+ if (ip->mode & GR_INVERT)
20216+ return 2; // specifically denied
20217+ else
20218+ return 1; // allowed
20219+ }
20220+
20221+ return 0; // not specifically allowed, may continue parsing
20222+}
20223+
20224+static int
20225+gr_search_connectbind(const int mode, const struct sock *sk,
20226+ const struct sockaddr_in *addr, const int type)
20227+{
20228+ char iface[IFNAMSIZ] = {0};
20229+ struct acl_subject_label *curr;
20230+ struct acl_ip_label *ip;
20231+ struct net_device *dev;
20232+ struct in_device *idev;
20233+ unsigned long i;
20234+ int ret;
20235+ __u32 ip_addr = 0;
20236+ __u32 our_addr;
20237+ __u32 our_netmask;
20238+ char *p;
20239+ __u16 ip_port = 0;
20240+
20241+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
20242+ return 1;
20243+
20244+ curr = current->acl;
20245+
20246+ if (!curr->ips)
20247+ return 1;
20248+
20249+ ip_addr = addr->sin_addr.s_addr;
20250+ ip_port = ntohs(addr->sin_port);
20251+
20252+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
20253+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
20254+ current->role->roletype, current->uid,
20255+ current->gid, current->exec_file ?
20256+ gr_to_filename(current->exec_file->f_dentry,
20257+ current->exec_file->f_vfsmnt) :
20258+ curr->filename, curr->filename,
20259+ NIPQUAD(ip_addr), ip_port, type,
20260+ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
20261+ return 1;
20262+ }
20263+
20264+ for (i = 0; i < curr->ip_num; i++) {
20265+ ip = *(curr->ips + i);
20266+ if (ip->iface != NULL) {
20267+ strncpy(iface, ip->iface, IFNAMSIZ - 1);
20268+ p = strchr(iface, ':');
20269+ if (p != NULL)
20270+ *p = '\0';
20271+ dev = dev_get_by_name(iface);
20272+ if (dev == NULL)
20273+ continue;
20274+ idev = in_dev_get(dev);
20275+ if (idev == NULL) {
20276+ dev_put(dev);
20277+ continue;
20278+ }
20279+ rcu_read_lock();
20280+ for_ifa(idev) {
20281+ if (!strcmp(ip->iface, ifa->ifa_label)) {
20282+ our_addr = ifa->ifa_address;
20283+ our_netmask = 0xffffffff;
20284+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
20285+ if (ret == 1) {
20286+ rcu_read_unlock();
20287+ in_dev_put(idev);
20288+ dev_put(dev);
20289+ return 1;
20290+ } else if (ret == 2) {
20291+ rcu_read_unlock();
20292+ in_dev_put(idev);
20293+ dev_put(dev);
20294+ goto denied;
20295+ }
20296+ }
20297+ } endfor_ifa(idev);
20298+ rcu_read_unlock();
20299+ in_dev_put(idev);
20300+ dev_put(dev);
20301+ } else {
20302+ our_addr = ip->addr;
20303+ our_netmask = ip->netmask;
20304+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
20305+ if (ret == 1)
20306+ return 1;
20307+ else if (ret == 2)
20308+ goto denied;
20309+ }
20310+ }
20311+
20312+denied:
20313+ if (mode == GR_BIND)
20314+ 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));
20315+ else if (mode == GR_CONNECT)
20316+ 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));
20317+
20318+ return 0;
20319+}
20320+
20321+int
20322+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
20323+{
20324+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
20325+}
20326+
20327+int
20328+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
20329+{
20330+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
20331+}
20332+
20333+int gr_search_listen(const struct socket *sock)
20334+{
20335+ struct sock *sk = sock->sk;
20336+ struct sockaddr_in addr;
20337+
20338+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
20339+ addr.sin_port = inet_sk(sk)->sport;
20340+
20341+ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
20342+}
20343+
20344+int gr_search_accept(const struct socket *sock)
20345+{
20346+ struct sock *sk = sock->sk;
20347+ struct sockaddr_in addr;
20348+
20349+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
20350+ addr.sin_port = inet_sk(sk)->sport;
20351+
20352+ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
20353+}
20354+
20355+int
20356+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
20357+{
20358+ if (addr)
20359+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
20360+ else {
20361+ struct sockaddr_in sin;
20362+ const struct inet_sock *inet = inet_sk(sk);
20363+
20364+ sin.sin_addr.s_addr = inet->daddr;
20365+ sin.sin_port = inet->dport;
20366+
20367+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
20368+ }
20369+}
20370+
20371+int
20372+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
20373+{
20374+ struct sockaddr_in sin;
20375+
20376+ if (unlikely(skb->len < sizeof (struct udphdr)))
20377+ return 1; // skip this packet
20378+
20379+ sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
20380+ sin.sin_port = udp_hdr(skb)->source;
20381+
20382+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
20383+}
20384diff -urNp linux-2.6.22.1/grsecurity/gracl_learn.c linux-2.6.22.1/grsecurity/gracl_learn.c
20385--- linux-2.6.22.1/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
20386+++ linux-2.6.22.1/grsecurity/gracl_learn.c 2007-08-02 11:09:16.000000000 -0400
20387@@ -0,0 +1,211 @@
20388+#include <linux/kernel.h>
20389+#include <linux/mm.h>
20390+#include <linux/sched.h>
20391+#include <linux/poll.h>
20392+#include <linux/smp_lock.h>
20393+#include <linux/string.h>
20394+#include <linux/file.h>
20395+#include <linux/types.h>
20396+#include <linux/vmalloc.h>
20397+#include <linux/grinternal.h>
20398+
20399+extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
20400+ size_t count, loff_t *ppos);
20401+extern int gr_acl_is_enabled(void);
20402+
20403+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
20404+static int gr_learn_attached;
20405+
20406+/* use a 512k buffer */
20407+#define LEARN_BUFFER_SIZE (512 * 1024)
20408+
20409+static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
20410+static DECLARE_MUTEX(gr_learn_user_sem);
20411+
20412+/* we need to maintain two buffers, so that the kernel context of grlearn
20413+ uses a semaphore around the userspace copying, and the other kernel contexts
20414+ use a spinlock when copying into the buffer, since they cannot sleep
20415+*/
20416+static char *learn_buffer;
20417+static char *learn_buffer_user;
20418+static int learn_buffer_len;
20419+static int learn_buffer_user_len;
20420+
20421+static ssize_t
20422+read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
20423+{
20424+ DECLARE_WAITQUEUE(wait, current);
20425+ ssize_t retval = 0;
20426+
20427+ add_wait_queue(&learn_wait, &wait);
20428+ set_current_state(TASK_INTERRUPTIBLE);
20429+ do {
20430+ down(&gr_learn_user_sem);
20431+ spin_lock(&gr_learn_lock);
20432+ if (learn_buffer_len)
20433+ break;
20434+ spin_unlock(&gr_learn_lock);
20435+ up(&gr_learn_user_sem);
20436+ if (file->f_flags & O_NONBLOCK) {
20437+ retval = -EAGAIN;
20438+ goto out;
20439+ }
20440+ if (signal_pending(current)) {
20441+ retval = -ERESTARTSYS;
20442+ goto out;
20443+ }
20444+
20445+ schedule();
20446+ } while (1);
20447+
20448+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
20449+ learn_buffer_user_len = learn_buffer_len;
20450+ retval = learn_buffer_len;
20451+ learn_buffer_len = 0;
20452+
20453+ spin_unlock(&gr_learn_lock);
20454+
20455+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
20456+ retval = -EFAULT;
20457+
20458+ up(&gr_learn_user_sem);
20459+out:
20460+ set_current_state(TASK_RUNNING);
20461+ remove_wait_queue(&learn_wait, &wait);
20462+ return retval;
20463+}
20464+
20465+static unsigned int
20466+poll_learn(struct file * file, poll_table * wait)
20467+{
20468+ poll_wait(file, &learn_wait, wait);
20469+
20470+ if (learn_buffer_len)
20471+ return (POLLIN | POLLRDNORM);
20472+
20473+ return 0;
20474+}
20475+
20476+void
20477+gr_clear_learn_entries(void)
20478+{
20479+ char *tmp;
20480+
20481+ down(&gr_learn_user_sem);
20482+ if (learn_buffer != NULL) {
20483+ spin_lock(&gr_learn_lock);
20484+ tmp = learn_buffer;
20485+ learn_buffer = NULL;
20486+ spin_unlock(&gr_learn_lock);
20487+ vfree(learn_buffer);
20488+ }
20489+ if (learn_buffer_user != NULL) {
20490+ vfree(learn_buffer_user);
20491+ learn_buffer_user = NULL;
20492+ }
20493+ learn_buffer_len = 0;
20494+ up(&gr_learn_user_sem);
20495+
20496+ return;
20497+}
20498+
20499+void
20500+gr_add_learn_entry(const char *fmt, ...)
20501+{
20502+ va_list args;
20503+ unsigned int len;
20504+
20505+ if (!gr_learn_attached)
20506+ return;
20507+
20508+ spin_lock(&gr_learn_lock);
20509+
20510+ /* leave a gap at the end so we know when it's "full" but don't have to
20511+ compute the exact length of the string we're trying to append
20512+ */
20513+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
20514+ spin_unlock(&gr_learn_lock);
20515+ wake_up_interruptible(&learn_wait);
20516+ return;
20517+ }
20518+ if (learn_buffer == NULL) {
20519+ spin_unlock(&gr_learn_lock);
20520+ return;
20521+ }
20522+
20523+ va_start(args, fmt);
20524+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
20525+ va_end(args);
20526+
20527+ learn_buffer_len += len + 1;
20528+
20529+ spin_unlock(&gr_learn_lock);
20530+ wake_up_interruptible(&learn_wait);
20531+
20532+ return;
20533+}
20534+
20535+static int
20536+open_learn(struct inode *inode, struct file *file)
20537+{
20538+ if (file->f_mode & FMODE_READ && gr_learn_attached)
20539+ return -EBUSY;
20540+ if (file->f_mode & FMODE_READ) {
20541+ int retval = 0;
20542+ down(&gr_learn_user_sem);
20543+ if (learn_buffer == NULL)
20544+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
20545+ if (learn_buffer_user == NULL)
20546+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
20547+ if (learn_buffer == NULL) {
20548+ retval = -ENOMEM;
20549+ goto out_error;
20550+ }
20551+ if (learn_buffer_user == NULL) {
20552+ retval = -ENOMEM;
20553+ goto out_error;
20554+ }
20555+ learn_buffer_len = 0;
20556+ learn_buffer_user_len = 0;
20557+ gr_learn_attached = 1;
20558+out_error:
20559+ up(&gr_learn_user_sem);
20560+ return retval;
20561+ }
20562+ return 0;
20563+}
20564+
20565+static int
20566+close_learn(struct inode *inode, struct file *file)
20567+{
20568+ char *tmp;
20569+
20570+ if (file->f_mode & FMODE_READ) {
20571+ down(&gr_learn_user_sem);
20572+ if (learn_buffer != NULL) {
20573+ spin_lock(&gr_learn_lock);
20574+ tmp = learn_buffer;
20575+ learn_buffer = NULL;
20576+ spin_unlock(&gr_learn_lock);
20577+ vfree(tmp);
20578+ }
20579+ if (learn_buffer_user != NULL) {
20580+ vfree(learn_buffer_user);
20581+ learn_buffer_user = NULL;
20582+ }
20583+ learn_buffer_len = 0;
20584+ learn_buffer_user_len = 0;
20585+ gr_learn_attached = 0;
20586+ up(&gr_learn_user_sem);
20587+ }
20588+
20589+ return 0;
20590+}
20591+
20592+struct file_operations grsec_fops = {
20593+ .read = read_learn,
20594+ .write = write_grsec_handler,
20595+ .open = open_learn,
20596+ .release = close_learn,
20597+ .poll = poll_learn,
20598+};
20599diff -urNp linux-2.6.22.1/grsecurity/gracl_res.c linux-2.6.22.1/grsecurity/gracl_res.c
20600--- linux-2.6.22.1/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
20601+++ linux-2.6.22.1/grsecurity/gracl_res.c 2007-08-02 11:09:16.000000000 -0400
20602@@ -0,0 +1,45 @@
20603+#include <linux/kernel.h>
20604+#include <linux/sched.h>
20605+#include <linux/gracl.h>
20606+#include <linux/grinternal.h>
20607+
20608+static const char *restab_log[] = {
20609+ [RLIMIT_CPU] = "RLIMIT_CPU",
20610+ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
20611+ [RLIMIT_DATA] = "RLIMIT_DATA",
20612+ [RLIMIT_STACK] = "RLIMIT_STACK",
20613+ [RLIMIT_CORE] = "RLIMIT_CORE",
20614+ [RLIMIT_RSS] = "RLIMIT_RSS",
20615+ [RLIMIT_NPROC] = "RLIMIT_NPROC",
20616+ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
20617+ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
20618+ [RLIMIT_AS] = "RLIMIT_AS",
20619+ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
20620+ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
20621+};
20622+
20623+void
20624+gr_log_resource(const struct task_struct *task,
20625+ const int res, const unsigned long wanted, const int gt)
20626+{
20627+ if (res == RLIMIT_NPROC &&
20628+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
20629+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
20630+ return;
20631+ else if (res == RLIMIT_MEMLOCK &&
20632+ cap_raised(task->cap_effective, CAP_IPC_LOCK))
20633+ return;
20634+
20635+ if (!gr_acl_is_enabled() && !grsec_resource_logging)
20636+ return;
20637+
20638+ preempt_disable();
20639+
20640+ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
20641+ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
20642+ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
20643+ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
20644+ preempt_enable_no_resched();
20645+
20646+ return;
20647+}
20648diff -urNp linux-2.6.22.1/grsecurity/gracl_segv.c linux-2.6.22.1/grsecurity/gracl_segv.c
20649--- linux-2.6.22.1/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
20650+++ linux-2.6.22.1/grsecurity/gracl_segv.c 2007-08-02 12:02:19.000000000 -0400
20651@@ -0,0 +1,301 @@
20652+#include <linux/kernel.h>
20653+#include <linux/mm.h>
20654+#include <asm/uaccess.h>
20655+#include <asm/errno.h>
20656+#include <asm/mman.h>
20657+#include <net/sock.h>
20658+#include <linux/file.h>
20659+#include <linux/fs.h>
20660+#include <linux/net.h>
20661+#include <linux/in.h>
20662+#include <linux/smp_lock.h>
20663+#include <linux/slab.h>
20664+#include <linux/types.h>
20665+#include <linux/sched.h>
20666+#include <linux/timer.h>
20667+#include <linux/gracl.h>
20668+#include <linux/grsecurity.h>
20669+#include <linux/grinternal.h>
20670+
20671+static struct crash_uid *uid_set;
20672+static unsigned short uid_used;
20673+static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
20674+extern rwlock_t gr_inode_lock;
20675+extern struct acl_subject_label *
20676+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
20677+ struct acl_role_label *role);
20678+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
20679+
20680+int
20681+gr_init_uidset(void)
20682+{
20683+ uid_set =
20684+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
20685+ uid_used = 0;
20686+
20687+ return uid_set ? 1 : 0;
20688+}
20689+
20690+void
20691+gr_free_uidset(void)
20692+{
20693+ if (uid_set)
20694+ kfree(uid_set);
20695+
20696+ return;
20697+}
20698+
20699+int
20700+gr_find_uid(const uid_t uid)
20701+{
20702+ struct crash_uid *tmp = uid_set;
20703+ uid_t buid;
20704+ int low = 0, high = uid_used - 1, mid;
20705+
20706+ while (high >= low) {
20707+ mid = (low + high) >> 1;
20708+ buid = tmp[mid].uid;
20709+ if (buid == uid)
20710+ return mid;
20711+ if (buid > uid)
20712+ high = mid - 1;
20713+ if (buid < uid)
20714+ low = mid + 1;
20715+ }
20716+
20717+ return -1;
20718+}
20719+
20720+static __inline__ void
20721+gr_insertsort(void)
20722+{
20723+ unsigned short i, j;
20724+ struct crash_uid index;
20725+
20726+ for (i = 1; i < uid_used; i++) {
20727+ index = uid_set[i];
20728+ j = i;
20729+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
20730+ uid_set[j] = uid_set[j - 1];
20731+ j--;
20732+ }
20733+ uid_set[j] = index;
20734+ }
20735+
20736+ return;
20737+}
20738+
20739+static __inline__ void
20740+gr_insert_uid(const uid_t uid, const unsigned long expires)
20741+{
20742+ int loc;
20743+
20744+ if (uid_used == GR_UIDTABLE_MAX)
20745+ return;
20746+
20747+ loc = gr_find_uid(uid);
20748+
20749+ if (loc >= 0) {
20750+ uid_set[loc].expires = expires;
20751+ return;
20752+ }
20753+
20754+ uid_set[uid_used].uid = uid;
20755+ uid_set[uid_used].expires = expires;
20756+ uid_used++;
20757+
20758+ gr_insertsort();
20759+
20760+ return;
20761+}
20762+
20763+void
20764+gr_remove_uid(const unsigned short loc)
20765+{
20766+ unsigned short i;
20767+
20768+ for (i = loc + 1; i < uid_used; i++)
20769+ uid_set[i - 1] = uid_set[i];
20770+
20771+ uid_used--;
20772+
20773+ return;
20774+}
20775+
20776+int
20777+gr_check_crash_uid(const uid_t uid)
20778+{
20779+ int loc;
20780+ int ret = 0;
20781+
20782+ if (unlikely(!gr_acl_is_enabled()))
20783+ return 0;
20784+
20785+ spin_lock(&gr_uid_lock);
20786+ loc = gr_find_uid(uid);
20787+
20788+ if (loc < 0)
20789+ goto out_unlock;
20790+
20791+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
20792+ gr_remove_uid(loc);
20793+ else
20794+ ret = 1;
20795+
20796+out_unlock:
20797+ spin_unlock(&gr_uid_lock);
20798+ return ret;
20799+}
20800+
20801+static __inline__ int
20802+proc_is_setxid(const struct task_struct *task)
20803+{
20804+ if (task->uid != task->euid || task->uid != task->suid ||
20805+ task->uid != task->fsuid)
20806+ return 1;
20807+ if (task->gid != task->egid || task->gid != task->sgid ||
20808+ task->gid != task->fsgid)
20809+ return 1;
20810+
20811+ return 0;
20812+}
20813+static __inline__ int
20814+gr_fake_force_sig(int sig, struct task_struct *t)
20815+{
20816+ unsigned long int flags;
20817+ int ret, blocked, ignored;
20818+ struct k_sigaction *action;
20819+
20820+ spin_lock_irqsave(&t->sighand->siglock, flags);
20821+ action = &t->sighand->action[sig-1];
20822+ ignored = action->sa.sa_handler == SIG_IGN;
20823+ blocked = sigismember(&t->blocked, sig);
20824+ if (blocked || ignored) {
20825+ action->sa.sa_handler = SIG_DFL;
20826+ if (blocked) {
20827+ sigdelset(&t->blocked, sig);
20828+ recalc_sigpending_and_wake(t);
20829+ }
20830+ }
20831+ ret = specific_send_sig_info(sig, (void*)1L, t);
20832+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
20833+
20834+ return ret;
20835+}
20836+
20837+void
20838+gr_handle_crash(struct task_struct *task, const int sig)
20839+{
20840+ struct acl_subject_label *curr;
20841+ struct acl_subject_label *curr2;
20842+ struct task_struct *tsk, *tsk2;
20843+
20844+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
20845+ return;
20846+
20847+ if (unlikely(!gr_acl_is_enabled()))
20848+ return;
20849+
20850+ curr = task->acl;
20851+
20852+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
20853+ return;
20854+
20855+ if (time_before_eq(curr->expires, get_seconds())) {
20856+ curr->expires = 0;
20857+ curr->crashes = 0;
20858+ }
20859+
20860+ curr->crashes++;
20861+
20862+ if (!curr->expires)
20863+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
20864+
20865+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
20866+ time_after(curr->expires, get_seconds())) {
20867+ if (task->uid && proc_is_setxid(task)) {
20868+ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
20869+ spin_lock(&gr_uid_lock);
20870+ gr_insert_uid(task->uid, curr->expires);
20871+ spin_unlock(&gr_uid_lock);
20872+ curr->expires = 0;
20873+ curr->crashes = 0;
20874+ read_lock(&tasklist_lock);
20875+ do_each_thread(tsk2, tsk) {
20876+ if (tsk != task && tsk->uid == task->uid)
20877+ gr_fake_force_sig(SIGKILL, tsk);
20878+ } while_each_thread(tsk2, tsk);
20879+ read_unlock(&tasklist_lock);
20880+ } else {
20881+ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
20882+ read_lock(&tasklist_lock);
20883+ do_each_thread(tsk2, tsk) {
20884+ if (likely(tsk != task)) {
20885+ curr2 = tsk->acl;
20886+
20887+ if (curr2->device == curr->device &&
20888+ curr2->inode == curr->inode)
20889+ gr_fake_force_sig(SIGKILL, tsk);
20890+ }
20891+ } while_each_thread(tsk2, tsk);
20892+ read_unlock(&tasklist_lock);
20893+ }
20894+ }
20895+
20896+ return;
20897+}
20898+
20899+int
20900+gr_check_crash_exec(const struct file *filp)
20901+{
20902+ struct acl_subject_label *curr;
20903+
20904+ if (unlikely(!gr_acl_is_enabled()))
20905+ return 0;
20906+
20907+ read_lock(&gr_inode_lock);
20908+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
20909+ filp->f_dentry->d_inode->i_sb->s_dev,
20910+ current->role);
20911+ read_unlock(&gr_inode_lock);
20912+
20913+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
20914+ (!curr->crashes && !curr->expires))
20915+ return 0;
20916+
20917+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
20918+ time_after(curr->expires, get_seconds()))
20919+ return 1;
20920+ else if (time_before_eq(curr->expires, get_seconds())) {
20921+ curr->crashes = 0;
20922+ curr->expires = 0;
20923+ }
20924+
20925+ return 0;
20926+}
20927+
20928+void
20929+gr_handle_alertkill(struct task_struct *task)
20930+{
20931+ struct acl_subject_label *curracl;
20932+ __u32 curr_ip;
20933+ struct task_struct *p, *p2;
20934+
20935+ if (unlikely(!gr_acl_is_enabled()))
20936+ return;
20937+
20938+ curracl = task->acl;
20939+ curr_ip = task->signal->curr_ip;
20940+
20941+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
20942+ read_lock(&tasklist_lock);
20943+ do_each_thread(p2, p) {
20944+ if (p->signal->curr_ip == curr_ip)
20945+ gr_fake_force_sig(SIGKILL, p);
20946+ } while_each_thread(p2, p);
20947+ read_unlock(&tasklist_lock);
20948+ } else if (curracl->mode & GR_KILLPROC)
20949+ gr_fake_force_sig(SIGKILL, task);
20950+
20951+ return;
20952+}
20953diff -urNp linux-2.6.22.1/grsecurity/gracl_shm.c linux-2.6.22.1/grsecurity/gracl_shm.c
20954--- linux-2.6.22.1/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
20955+++ linux-2.6.22.1/grsecurity/gracl_shm.c 2007-08-02 11:09:16.000000000 -0400
20956@@ -0,0 +1,33 @@
20957+#include <linux/kernel.h>
20958+#include <linux/mm.h>
20959+#include <linux/sched.h>
20960+#include <linux/file.h>
20961+#include <linux/ipc.h>
20962+#include <linux/gracl.h>
20963+#include <linux/grsecurity.h>
20964+#include <linux/grinternal.h>
20965+
20966+int
20967+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20968+ const time_t shm_createtime, const uid_t cuid, const int shmid)
20969+{
20970+ struct task_struct *task;
20971+
20972+ if (!gr_acl_is_enabled())
20973+ return 1;
20974+
20975+ task = find_task_by_pid(shm_cprid);
20976+
20977+ if (unlikely(!task))
20978+ task = find_task_by_pid(shm_lapid);
20979+
20980+ if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
20981+ (task->pid == shm_lapid)) &&
20982+ (task->acl->mode & GR_PROTSHM) &&
20983+ (task->acl != current->acl))) {
20984+ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
20985+ return 0;
20986+ }
20987+
20988+ return 1;
20989+}
20990diff -urNp linux-2.6.22.1/grsecurity/grsec_chdir.c linux-2.6.22.1/grsecurity/grsec_chdir.c
20991--- linux-2.6.22.1/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
20992+++ linux-2.6.22.1/grsecurity/grsec_chdir.c 2007-08-02 11:09:16.000000000 -0400
20993@@ -0,0 +1,19 @@
20994+#include <linux/kernel.h>
20995+#include <linux/sched.h>
20996+#include <linux/fs.h>
20997+#include <linux/file.h>
20998+#include <linux/grsecurity.h>
20999+#include <linux/grinternal.h>
21000+
21001+void
21002+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
21003+{
21004+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
21005+ if ((grsec_enable_chdir && grsec_enable_group &&
21006+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
21007+ !grsec_enable_group)) {
21008+ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
21009+ }
21010+#endif
21011+ return;
21012+}
21013diff -urNp linux-2.6.22.1/grsecurity/grsec_chroot.c linux-2.6.22.1/grsecurity/grsec_chroot.c
21014--- linux-2.6.22.1/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
21015+++ linux-2.6.22.1/grsecurity/grsec_chroot.c 2007-08-02 11:09:16.000000000 -0400
21016@@ -0,0 +1,335 @@
21017+#include <linux/kernel.h>
21018+#include <linux/module.h>
21019+#include <linux/sched.h>
21020+#include <linux/file.h>
21021+#include <linux/fs.h>
21022+#include <linux/mount.h>
21023+#include <linux/types.h>
21024+#include <linux/pid_namespace.h>
21025+#include <linux/grsecurity.h>
21026+#include <linux/grinternal.h>
21027+
21028+int
21029+gr_handle_chroot_unix(const pid_t pid)
21030+{
21031+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
21032+ struct pid *spid = NULL;
21033+
21034+ if (unlikely(!grsec_enable_chroot_unix))
21035+ return 1;
21036+
21037+ if (likely(!proc_is_chrooted(current)))
21038+ return 1;
21039+
21040+ read_lock(&tasklist_lock);
21041+
21042+ spid = find_pid(pid);
21043+ if (spid) {
21044+ struct task_struct *p;
21045+ p = pid_task(spid, PIDTYPE_PID);
21046+ task_lock(p);
21047+ if (unlikely(!have_same_root(current, p))) {
21048+ task_unlock(p);
21049+ read_unlock(&tasklist_lock);
21050+ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
21051+ return 0;
21052+ }
21053+ task_unlock(p);
21054+ }
21055+ read_unlock(&tasklist_lock);
21056+#endif
21057+ return 1;
21058+}
21059+
21060+int
21061+gr_handle_chroot_nice(void)
21062+{
21063+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
21064+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
21065+ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
21066+ return -EPERM;
21067+ }
21068+#endif
21069+ return 0;
21070+}
21071+
21072+int
21073+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
21074+{
21075+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
21076+ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
21077+ && proc_is_chrooted(current)) {
21078+ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
21079+ return -EACCES;
21080+ }
21081+#endif
21082+ return 0;
21083+}
21084+
21085+int
21086+gr_handle_chroot_rawio(const struct inode *inode)
21087+{
21088+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
21089+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
21090+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
21091+ return 1;
21092+#endif
21093+ return 0;
21094+}
21095+
21096+int
21097+gr_pid_is_chrooted(struct task_struct *p)
21098+{
21099+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
21100+ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
21101+ return 0;
21102+
21103+ task_lock(p);
21104+ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
21105+ !have_same_root(current, p)) {
21106+ task_unlock(p);
21107+ return 1;
21108+ }
21109+ task_unlock(p);
21110+#endif
21111+ return 0;
21112+}
21113+
21114+EXPORT_SYMBOL(gr_pid_is_chrooted);
21115+
21116+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
21117+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
21118+{
21119+ struct dentry *dentry = (struct dentry *)u_dentry;
21120+ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
21121+ struct dentry *realroot;
21122+ struct vfsmount *realrootmnt;
21123+ struct dentry *currentroot;
21124+ struct vfsmount *currentmnt;
21125+ struct task_struct *reaper = child_reaper(current);
21126+ int ret = 1;
21127+
21128+ read_lock(&reaper->fs->lock);
21129+ realrootmnt = mntget(reaper->fs->rootmnt);
21130+ realroot = dget(reaper->fs->root);
21131+ read_unlock(&reaper->fs->lock);
21132+
21133+ read_lock(&current->fs->lock);
21134+ currentmnt = mntget(current->fs->rootmnt);
21135+ currentroot = dget(current->fs->root);
21136+ read_unlock(&current->fs->lock);
21137+
21138+ spin_lock(&dcache_lock);
21139+ for (;;) {
21140+ if (unlikely((dentry == realroot && mnt == realrootmnt)
21141+ || (dentry == currentroot && mnt == currentmnt)))
21142+ break;
21143+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
21144+ if (mnt->mnt_parent == mnt)
21145+ break;
21146+ dentry = mnt->mnt_mountpoint;
21147+ mnt = mnt->mnt_parent;
21148+ continue;
21149+ }
21150+ dentry = dentry->d_parent;
21151+ }
21152+ spin_unlock(&dcache_lock);
21153+
21154+ dput(currentroot);
21155+ mntput(currentmnt);
21156+
21157+ /* access is outside of chroot */
21158+ if (dentry == realroot && mnt == realrootmnt)
21159+ ret = 0;
21160+
21161+ dput(realroot);
21162+ mntput(realrootmnt);
21163+ return ret;
21164+}
21165+#endif
21166+
21167+int
21168+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
21169+{
21170+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
21171+ if (!grsec_enable_chroot_fchdir)
21172+ return 1;
21173+
21174+ if (!proc_is_chrooted(current))
21175+ return 1;
21176+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
21177+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
21178+ return 0;
21179+ }
21180+#endif
21181+ return 1;
21182+}
21183+
21184+int
21185+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
21186+ const time_t shm_createtime)
21187+{
21188+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
21189+ struct pid *pid = NULL;
21190+ time_t starttime;
21191+
21192+ if (unlikely(!grsec_enable_chroot_shmat))
21193+ return 1;
21194+
21195+ if (likely(!proc_is_chrooted(current)))
21196+ return 1;
21197+
21198+ read_lock(&tasklist_lock);
21199+
21200+ pid = find_pid(shm_cprid);
21201+ if (pid) {
21202+ struct task_struct *p;
21203+ p = pid_task(pid, PIDTYPE_PID);
21204+ task_lock(p);
21205+ starttime = p->start_time.tv_sec;
21206+ if (unlikely(!have_same_root(current, p) &&
21207+ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
21208+ task_unlock(p);
21209+ read_unlock(&tasklist_lock);
21210+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
21211+ return 0;
21212+ }
21213+ task_unlock(p);
21214+ } else {
21215+ pid = find_pid(shm_lapid);
21216+ if (pid) {
21217+ struct task_struct *p;
21218+ p = pid_task(pid, PIDTYPE_PID);
21219+ task_lock(p);
21220+ if (unlikely(!have_same_root(current, p))) {
21221+ task_unlock(p);
21222+ read_unlock(&tasklist_lock);
21223+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
21224+ return 0;
21225+ }
21226+ task_unlock(p);
21227+ }
21228+ }
21229+
21230+ read_unlock(&tasklist_lock);
21231+#endif
21232+ return 1;
21233+}
21234+
21235+void
21236+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
21237+{
21238+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
21239+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
21240+ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
21241+#endif
21242+ return;
21243+}
21244+
21245+int
21246+gr_handle_chroot_mknod(const struct dentry *dentry,
21247+ const struct vfsmount *mnt, const int mode)
21248+{
21249+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
21250+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
21251+ proc_is_chrooted(current)) {
21252+ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
21253+ return -EPERM;
21254+ }
21255+#endif
21256+ return 0;
21257+}
21258+
21259+int
21260+gr_handle_chroot_mount(const struct dentry *dentry,
21261+ const struct vfsmount *mnt, const char *dev_name)
21262+{
21263+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
21264+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
21265+ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
21266+ return -EPERM;
21267+ }
21268+#endif
21269+ return 0;
21270+}
21271+
21272+int
21273+gr_handle_chroot_pivot(void)
21274+{
21275+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
21276+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
21277+ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
21278+ return -EPERM;
21279+ }
21280+#endif
21281+ return 0;
21282+}
21283+
21284+int
21285+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
21286+{
21287+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
21288+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
21289+ !gr_is_outside_chroot(dentry, mnt)) {
21290+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
21291+ return -EPERM;
21292+ }
21293+#endif
21294+ return 0;
21295+}
21296+
21297+void
21298+gr_handle_chroot_caps(struct task_struct *task)
21299+{
21300+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
21301+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
21302+ task->cap_permitted =
21303+ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
21304+ task->cap_inheritable =
21305+ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
21306+ task->cap_effective =
21307+ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
21308+ }
21309+#endif
21310+ return;
21311+}
21312+
21313+int
21314+gr_handle_chroot_sysctl(const int op)
21315+{
21316+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
21317+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
21318+ && (op & 002))
21319+ return -EACCES;
21320+#endif
21321+ return 0;
21322+}
21323+
21324+void
21325+gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
21326+{
21327+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
21328+ if (grsec_enable_chroot_chdir)
21329+ set_fs_pwd(current->fs, mnt, dentry);
21330+#endif
21331+ return;
21332+}
21333+
21334+int
21335+gr_handle_chroot_chmod(const struct dentry *dentry,
21336+ const struct vfsmount *mnt, const int mode)
21337+{
21338+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
21339+ if (grsec_enable_chroot_chmod &&
21340+ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
21341+ proc_is_chrooted(current)) {
21342+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
21343+ return -EPERM;
21344+ }
21345+#endif
21346+ return 0;
21347+}
21348+
21349+#ifdef CONFIG_SECURITY
21350+EXPORT_SYMBOL(gr_handle_chroot_caps);
21351+#endif
21352diff -urNp linux-2.6.22.1/grsecurity/grsec_disabled.c linux-2.6.22.1/grsecurity/grsec_disabled.c
21353--- linux-2.6.22.1/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
21354+++ linux-2.6.22.1/grsecurity/grsec_disabled.c 2007-08-02 11:09:16.000000000 -0400
21355@@ -0,0 +1,418 @@
21356+#include <linux/kernel.h>
21357+#include <linux/module.h>
21358+#include <linux/sched.h>
21359+#include <linux/file.h>
21360+#include <linux/fs.h>
21361+#include <linux/kdev_t.h>
21362+#include <linux/net.h>
21363+#include <linux/in.h>
21364+#include <linux/ip.h>
21365+#include <linux/skbuff.h>
21366+#include <linux/sysctl.h>
21367+
21368+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
21369+void
21370+pax_set_initial_flags(struct linux_binprm *bprm)
21371+{
21372+ return;
21373+}
21374+#endif
21375+
21376+#ifdef CONFIG_SYSCTL
21377+__u32
21378+gr_handle_sysctl(const struct ctl_table * table, const int op)
21379+{
21380+ return 0;
21381+}
21382+#endif
21383+
21384+int
21385+gr_acl_is_enabled(void)
21386+{
21387+ return 0;
21388+}
21389+
21390+int
21391+gr_handle_rawio(const struct inode *inode)
21392+{
21393+ return 0;
21394+}
21395+
21396+void
21397+gr_acl_handle_psacct(struct task_struct *task, const long code)
21398+{
21399+ return;
21400+}
21401+
21402+int
21403+gr_handle_ptrace(struct task_struct *task, const long request)
21404+{
21405+ return 0;
21406+}
21407+
21408+int
21409+gr_handle_proc_ptrace(struct task_struct *task)
21410+{
21411+ return 0;
21412+}
21413+
21414+void
21415+gr_learn_resource(const struct task_struct *task,
21416+ const int res, const unsigned long wanted, const int gt)
21417+{
21418+ return;
21419+}
21420+
21421+int
21422+gr_set_acls(const int type)
21423+{
21424+ return 0;
21425+}
21426+
21427+int
21428+gr_check_hidden_task(const struct task_struct *tsk)
21429+{
21430+ return 0;
21431+}
21432+
21433+int
21434+gr_check_protected_task(const struct task_struct *task)
21435+{
21436+ return 0;
21437+}
21438+
21439+void
21440+gr_copy_label(struct task_struct *tsk)
21441+{
21442+ return;
21443+}
21444+
21445+void
21446+gr_set_pax_flags(struct task_struct *task)
21447+{
21448+ return;
21449+}
21450+
21451+int
21452+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
21453+{
21454+ return 0;
21455+}
21456+
21457+void
21458+gr_handle_delete(const ino_t ino, const dev_t dev)
21459+{
21460+ return;
21461+}
21462+
21463+void
21464+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
21465+{
21466+ return;
21467+}
21468+
21469+void
21470+gr_handle_crash(struct task_struct *task, const int sig)
21471+{
21472+ return;
21473+}
21474+
21475+int
21476+gr_check_crash_exec(const struct file *filp)
21477+{
21478+ return 0;
21479+}
21480+
21481+int
21482+gr_check_crash_uid(const uid_t uid)
21483+{
21484+ return 0;
21485+}
21486+
21487+void
21488+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
21489+ struct dentry *old_dentry,
21490+ struct dentry *new_dentry,
21491+ struct vfsmount *mnt, const __u8 replace)
21492+{
21493+ return;
21494+}
21495+
21496+int
21497+gr_search_socket(const int family, const int type, const int protocol)
21498+{
21499+ return 1;
21500+}
21501+
21502+int
21503+gr_search_connectbind(const int mode, const struct socket *sock,
21504+ const struct sockaddr_in *addr)
21505+{
21506+ return 1;
21507+}
21508+
21509+int
21510+gr_task_is_capable(struct task_struct *task, const int cap)
21511+{
21512+ return 1;
21513+}
21514+
21515+int
21516+gr_is_capable_nolog(const int cap)
21517+{
21518+ return 1;
21519+}
21520+
21521+void
21522+gr_handle_alertkill(struct task_struct *task)
21523+{
21524+ return;
21525+}
21526+
21527+__u32
21528+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
21529+{
21530+ return 1;
21531+}
21532+
21533+__u32
21534+gr_acl_handle_hidden_file(const struct dentry * dentry,
21535+ const struct vfsmount * mnt)
21536+{
21537+ return 1;
21538+}
21539+
21540+__u32
21541+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
21542+ const int fmode)
21543+{
21544+ return 1;
21545+}
21546+
21547+__u32
21548+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
21549+{
21550+ return 1;
21551+}
21552+
21553+__u32
21554+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
21555+{
21556+ return 1;
21557+}
21558+
21559+int
21560+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
21561+ unsigned int *vm_flags)
21562+{
21563+ return 1;
21564+}
21565+
21566+__u32
21567+gr_acl_handle_truncate(const struct dentry * dentry,
21568+ const struct vfsmount * mnt)
21569+{
21570+ return 1;
21571+}
21572+
21573+__u32
21574+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
21575+{
21576+ return 1;
21577+}
21578+
21579+__u32
21580+gr_acl_handle_access(const struct dentry * dentry,
21581+ const struct vfsmount * mnt, const int fmode)
21582+{
21583+ return 1;
21584+}
21585+
21586+__u32
21587+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
21588+ mode_t mode)
21589+{
21590+ return 1;
21591+}
21592+
21593+__u32
21594+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
21595+ mode_t mode)
21596+{
21597+ return 1;
21598+}
21599+
21600+__u32
21601+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
21602+{
21603+ return 1;
21604+}
21605+
21606+void
21607+grsecurity_init(void)
21608+{
21609+ return;
21610+}
21611+
21612+__u32
21613+gr_acl_handle_mknod(const struct dentry * new_dentry,
21614+ const struct dentry * parent_dentry,
21615+ const struct vfsmount * parent_mnt,
21616+ const int mode)
21617+{
21618+ return 1;
21619+}
21620+
21621+__u32
21622+gr_acl_handle_mkdir(const struct dentry * new_dentry,
21623+ const struct dentry * parent_dentry,
21624+ const struct vfsmount * parent_mnt)
21625+{
21626+ return 1;
21627+}
21628+
21629+__u32
21630+gr_acl_handle_symlink(const struct dentry * new_dentry,
21631+ const struct dentry * parent_dentry,
21632+ const struct vfsmount * parent_mnt, const char *from)
21633+{
21634+ return 1;
21635+}
21636+
21637+__u32
21638+gr_acl_handle_link(const struct dentry * new_dentry,
21639+ const struct dentry * parent_dentry,
21640+ const struct vfsmount * parent_mnt,
21641+ const struct dentry * old_dentry,
21642+ const struct vfsmount * old_mnt, const char *to)
21643+{
21644+ return 1;
21645+}
21646+
21647+int
21648+gr_acl_handle_rename(const struct dentry *new_dentry,
21649+ const struct dentry *parent_dentry,
21650+ const struct vfsmount *parent_mnt,
21651+ const struct dentry *old_dentry,
21652+ const struct inode *old_parent_inode,
21653+ const struct vfsmount *old_mnt, const char *newname)
21654+{
21655+ return 0;
21656+}
21657+
21658+int
21659+gr_acl_handle_filldir(const struct file *file, const char *name,
21660+ const int namelen, const ino_t ino)
21661+{
21662+ return 1;
21663+}
21664+
21665+int
21666+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
21667+ const time_t shm_createtime, const uid_t cuid, const int shmid)
21668+{
21669+ return 1;
21670+}
21671+
21672+int
21673+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
21674+{
21675+ return 1;
21676+}
21677+
21678+int
21679+gr_search_accept(const struct socket *sock)
21680+{
21681+ return 1;
21682+}
21683+
21684+int
21685+gr_search_listen(const struct socket *sock)
21686+{
21687+ return 1;
21688+}
21689+
21690+int
21691+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
21692+{
21693+ return 1;
21694+}
21695+
21696+__u32
21697+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
21698+{
21699+ return 1;
21700+}
21701+
21702+__u32
21703+gr_acl_handle_creat(const struct dentry * dentry,
21704+ const struct dentry * p_dentry,
21705+ const struct vfsmount * p_mnt, const int fmode,
21706+ const int imode)
21707+{
21708+ return 1;
21709+}
21710+
21711+void
21712+gr_acl_handle_exit(void)
21713+{
21714+ return;
21715+}
21716+
21717+int
21718+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
21719+{
21720+ return 1;
21721+}
21722+
21723+void
21724+gr_set_role_label(const uid_t uid, const gid_t gid)
21725+{
21726+ return;
21727+}
21728+
21729+int
21730+gr_acl_handle_procpidmem(const struct task_struct *task)
21731+{
21732+ return 0;
21733+}
21734+
21735+int
21736+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
21737+{
21738+ return 1;
21739+}
21740+
21741+int
21742+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
21743+{
21744+ return 1;
21745+}
21746+
21747+void
21748+gr_set_kernel_label(struct task_struct *task)
21749+{
21750+ return;
21751+}
21752+
21753+int
21754+gr_check_user_change(int real, int effective, int fs)
21755+{
21756+ return 0;
21757+}
21758+
21759+int
21760+gr_check_group_change(int real, int effective, int fs)
21761+{
21762+ return 0;
21763+}
21764+
21765+
21766+EXPORT_SYMBOL(gr_task_is_capable);
21767+EXPORT_SYMBOL(gr_is_capable_nolog);
21768+EXPORT_SYMBOL(gr_learn_resource);
21769+EXPORT_SYMBOL(gr_set_kernel_label);
21770+#ifdef CONFIG_SECURITY
21771+EXPORT_SYMBOL(gr_check_user_change);
21772+EXPORT_SYMBOL(gr_check_group_change);
21773+#endif
21774diff -urNp linux-2.6.22.1/grsecurity/grsec_exec.c linux-2.6.22.1/grsecurity/grsec_exec.c
21775--- linux-2.6.22.1/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
21776+++ linux-2.6.22.1/grsecurity/grsec_exec.c 2007-08-02 11:09:16.000000000 -0400
21777@@ -0,0 +1,88 @@
21778+#include <linux/kernel.h>
21779+#include <linux/sched.h>
21780+#include <linux/file.h>
21781+#include <linux/binfmts.h>
21782+#include <linux/smp_lock.h>
21783+#include <linux/fs.h>
21784+#include <linux/types.h>
21785+#include <linux/grdefs.h>
21786+#include <linux/grinternal.h>
21787+#include <linux/capability.h>
21788+
21789+#include <asm/uaccess.h>
21790+
21791+#ifdef CONFIG_GRKERNSEC_EXECLOG
21792+static char gr_exec_arg_buf[132];
21793+static DECLARE_MUTEX(gr_exec_arg_sem);
21794+#endif
21795+
21796+int
21797+gr_handle_nproc(void)
21798+{
21799+#ifdef CONFIG_GRKERNSEC_EXECVE
21800+ if (grsec_enable_execve && current->user &&
21801+ (atomic_read(&current->user->processes) >
21802+ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
21803+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
21804+ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
21805+ return -EAGAIN;
21806+ }
21807+#endif
21808+ return 0;
21809+}
21810+
21811+void
21812+gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
21813+{
21814+#ifdef CONFIG_GRKERNSEC_EXECLOG
21815+ char *grarg = gr_exec_arg_buf;
21816+ unsigned int i, x, execlen = 0;
21817+ char c;
21818+
21819+ if (!((grsec_enable_execlog && grsec_enable_group &&
21820+ in_group_p(grsec_audit_gid))
21821+ || (grsec_enable_execlog && !grsec_enable_group)))
21822+ return;
21823+
21824+ down(&gr_exec_arg_sem);
21825+ memset(grarg, 0, sizeof(gr_exec_arg_buf));
21826+
21827+ if (unlikely(argv == NULL))
21828+ goto log;
21829+
21830+ for (i = 0; i < bprm->argc && execlen < 128; i++) {
21831+ const char __user *p;
21832+ unsigned int len;
21833+
21834+ if (copy_from_user(&p, argv + i, sizeof(p)))
21835+ goto log;
21836+ if (!p)
21837+ goto log;
21838+ len = strnlen_user(p, 128 - execlen);
21839+ if (len > 128 - execlen)
21840+ len = 128 - execlen;
21841+ else if (len > 0)
21842+ len--;
21843+ if (copy_from_user(grarg + execlen, p, len))
21844+ goto log;
21845+
21846+ /* rewrite unprintable characters */
21847+ for (x = 0; x < len; x++) {
21848+ c = *(grarg + execlen + x);
21849+ if (c < 32 || c > 126)
21850+ *(grarg + execlen + x) = ' ';
21851+ }
21852+
21853+ execlen += len;
21854+ *(grarg + execlen) = ' ';
21855+ *(grarg + execlen + 1) = '\0';
21856+ execlen++;
21857+ }
21858+
21859+ log:
21860+ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
21861+ bprm->file->f_vfsmnt, grarg);
21862+ up(&gr_exec_arg_sem);
21863+#endif
21864+ return;
21865+}
21866diff -urNp linux-2.6.22.1/grsecurity/grsec_fifo.c linux-2.6.22.1/grsecurity/grsec_fifo.c
21867--- linux-2.6.22.1/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
21868+++ linux-2.6.22.1/grsecurity/grsec_fifo.c 2007-08-02 11:09:16.000000000 -0400
21869@@ -0,0 +1,22 @@
21870+#include <linux/kernel.h>
21871+#include <linux/sched.h>
21872+#include <linux/fs.h>
21873+#include <linux/file.h>
21874+#include <linux/grinternal.h>
21875+
21876+int
21877+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
21878+ const struct dentry *dir, const int flag, const int acc_mode)
21879+{
21880+#ifdef CONFIG_GRKERNSEC_FIFO
21881+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
21882+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
21883+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
21884+ (current->fsuid != dentry->d_inode->i_uid)) {
21885+ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
21886+ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
21887+ return -EACCES;
21888+ }
21889+#endif
21890+ return 0;
21891+}
21892diff -urNp linux-2.6.22.1/grsecurity/grsec_fork.c linux-2.6.22.1/grsecurity/grsec_fork.c
21893--- linux-2.6.22.1/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
21894+++ linux-2.6.22.1/grsecurity/grsec_fork.c 2007-08-02 11:09:16.000000000 -0400
21895@@ -0,0 +1,15 @@
21896+#include <linux/kernel.h>
21897+#include <linux/sched.h>
21898+#include <linux/grsecurity.h>
21899+#include <linux/grinternal.h>
21900+#include <linux/errno.h>
21901+
21902+void
21903+gr_log_forkfail(const int retval)
21904+{
21905+#ifdef CONFIG_GRKERNSEC_FORKFAIL
21906+ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
21907+ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
21908+#endif
21909+ return;
21910+}
21911diff -urNp linux-2.6.22.1/grsecurity/grsec_init.c linux-2.6.22.1/grsecurity/grsec_init.c
21912--- linux-2.6.22.1/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
21913+++ linux-2.6.22.1/grsecurity/grsec_init.c 2007-08-02 11:09:16.000000000 -0400
b5630f59 21914@@ -0,0 +1,230 @@
3ba9fddb 21915+#include <linux/kernel.h>
21916+#include <linux/sched.h>
21917+#include <linux/mm.h>
21918+#include <linux/smp_lock.h>
21919+#include <linux/gracl.h>
21920+#include <linux/slab.h>
21921+#include <linux/vmalloc.h>
21922+#include <linux/percpu.h>
21923+
21924+int grsec_enable_shm;
21925+int grsec_enable_link;
21926+int grsec_enable_dmesg;
21927+int grsec_enable_fifo;
21928+int grsec_enable_execve;
21929+int grsec_enable_execlog;
21930+int grsec_enable_signal;
21931+int grsec_enable_forkfail;
21932+int grsec_enable_time;
21933+int grsec_enable_audit_textrel;
21934+int grsec_enable_group;
21935+int grsec_audit_gid;
21936+int grsec_enable_chdir;
21937+int grsec_enable_audit_ipc;
21938+int grsec_enable_mount;
21939+int grsec_enable_chroot_findtask;
21940+int grsec_enable_chroot_mount;
21941+int grsec_enable_chroot_shmat;
21942+int grsec_enable_chroot_fchdir;
21943+int grsec_enable_chroot_double;
21944+int grsec_enable_chroot_pivot;
21945+int grsec_enable_chroot_chdir;
21946+int grsec_enable_chroot_chmod;
21947+int grsec_enable_chroot_mknod;
21948+int grsec_enable_chroot_nice;
21949+int grsec_enable_chroot_execlog;
21950+int grsec_enable_chroot_caps;
21951+int grsec_enable_chroot_sysctl;
21952+int grsec_enable_chroot_unix;
21953+int grsec_enable_tpe;
21954+int grsec_tpe_gid;
21955+int grsec_enable_tpe_all;
21956+int grsec_enable_socket_all;
21957+int grsec_socket_all_gid;
21958+int grsec_enable_socket_client;
21959+int grsec_socket_client_gid;
21960+int grsec_enable_socket_server;
21961+int grsec_socket_server_gid;
21962+int grsec_resource_logging;
21963+int grsec_lock;
21964+
21965+spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
21966+unsigned long grsec_alert_wtime = 0;
21967+unsigned long grsec_alert_fyet = 0;
21968+
21969+spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
21970+
21971+rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
21972+
21973+char *gr_shared_page[4];
21974+
21975+char *gr_alert_log_fmt;
21976+char *gr_audit_log_fmt;
21977+char *gr_alert_log_buf;
21978+char *gr_audit_log_buf;
21979+
21980+extern struct gr_arg *gr_usermode;
21981+extern unsigned char *gr_system_salt;
21982+extern unsigned char *gr_system_sum;
21983+
21984+void
21985+grsecurity_init(void)
21986+{
21987+ int j;
21988+ /* create the per-cpu shared pages */
21989+
3ba9fddb 21990+ for (j = 0; j < 4; j++) {
21991+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
21992+ if (gr_shared_page[j] == NULL) {
21993+ panic("Unable to allocate grsecurity shared page");
21994+ return;
21995+ }
21996+ }
3ba9fddb 21997+
21998+ /* allocate log buffers */
21999+ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
22000+ if (!gr_alert_log_fmt) {
22001+ panic("Unable to allocate grsecurity alert log format buffer");
22002+ return;
22003+ }
22004+ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
22005+ if (!gr_audit_log_fmt) {
22006+ panic("Unable to allocate grsecurity audit log format buffer");
22007+ return;
22008+ }
22009+ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
22010+ if (!gr_alert_log_buf) {
22011+ panic("Unable to allocate grsecurity alert log buffer");
22012+ return;
22013+ }
22014+ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
22015+ if (!gr_audit_log_buf) {
22016+ panic("Unable to allocate grsecurity audit log buffer");
22017+ return;
22018+ }
22019+
22020+ /* allocate memory for authentication structure */
22021+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
22022+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
22023+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
22024+
22025+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
22026+ panic("Unable to allocate grsecurity authentication structure");
22027+ return;
22028+ }
22029+
22030+#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
22031+#ifndef CONFIG_GRKERNSEC_SYSCTL
22032+ grsec_lock = 1;
22033+#endif
22034+#ifdef CONFIG_GRKERNSEC_SHM
22035+ grsec_enable_shm = 1;
22036+#endif
22037+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
22038+ grsec_enable_audit_textrel = 1;
22039+#endif
22040+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
22041+ grsec_enable_group = 1;
22042+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
22043+#endif
22044+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22045+ grsec_enable_chdir = 1;
22046+#endif
22047+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22048+ grsec_enable_audit_ipc = 1;
22049+#endif
22050+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
22051+ grsec_enable_mount = 1;
22052+#endif
22053+#ifdef CONFIG_GRKERNSEC_LINK
22054+ grsec_enable_link = 1;
22055+#endif
22056+#ifdef CONFIG_GRKERNSEC_DMESG
22057+ grsec_enable_dmesg = 1;
22058+#endif
22059+#ifdef CONFIG_GRKERNSEC_FIFO
22060+ grsec_enable_fifo = 1;
22061+#endif
22062+#ifdef CONFIG_GRKERNSEC_EXECVE
22063+ grsec_enable_execve = 1;
22064+#endif
22065+#ifdef CONFIG_GRKERNSEC_EXECLOG
22066+ grsec_enable_execlog = 1;
22067+#endif
22068+#ifdef CONFIG_GRKERNSEC_SIGNAL
22069+ grsec_enable_signal = 1;
22070+#endif
22071+#ifdef CONFIG_GRKERNSEC_FORKFAIL
22072+ grsec_enable_forkfail = 1;
22073+#endif
22074+#ifdef CONFIG_GRKERNSEC_TIME
22075+ grsec_enable_time = 1;
22076+#endif
22077+#ifdef CONFIG_GRKERNSEC_RESLOG
22078+ grsec_resource_logging = 1;
22079+#endif
22080+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22081+ grsec_enable_chroot_findtask = 1;
22082+#endif
22083+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22084+ grsec_enable_chroot_unix = 1;
22085+#endif
22086+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
22087+ grsec_enable_chroot_mount = 1;
22088+#endif
22089+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
22090+ grsec_enable_chroot_fchdir = 1;
22091+#endif
22092+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
22093+ grsec_enable_chroot_shmat = 1;
22094+#endif
22095+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
22096+ grsec_enable_chroot_double = 1;
22097+#endif
22098+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
22099+ grsec_enable_chroot_pivot = 1;
22100+#endif
22101+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
22102+ grsec_enable_chroot_chdir = 1;
22103+#endif
22104+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
22105+ grsec_enable_chroot_chmod = 1;
22106+#endif
22107+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
22108+ grsec_enable_chroot_mknod = 1;
22109+#endif
22110+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22111+ grsec_enable_chroot_nice = 1;
22112+#endif
22113+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
22114+ grsec_enable_chroot_execlog = 1;
22115+#endif
22116+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22117+ grsec_enable_chroot_caps = 1;
22118+#endif
22119+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
22120+ grsec_enable_chroot_sysctl = 1;
22121+#endif
22122+#ifdef CONFIG_GRKERNSEC_TPE
22123+ grsec_enable_tpe = 1;
22124+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
22125+#ifdef CONFIG_GRKERNSEC_TPE_ALL
22126+ grsec_enable_tpe_all = 1;
22127+#endif
22128+#endif
22129+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
22130+ grsec_enable_socket_all = 1;
22131+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
22132+#endif
22133+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
22134+ grsec_enable_socket_client = 1;
22135+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
22136+#endif
22137+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
22138+ grsec_enable_socket_server = 1;
22139+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
22140+#endif
22141+#endif
22142+
22143+ return;
22144+}
22145diff -urNp linux-2.6.22.1/grsecurity/grsec_ipc.c linux-2.6.22.1/grsecurity/grsec_ipc.c
22146--- linux-2.6.22.1/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
22147+++ linux-2.6.22.1/grsecurity/grsec_ipc.c 2007-08-02 11:09:16.000000000 -0400
22148@@ -0,0 +1,81 @@
22149+#include <linux/kernel.h>
22150+#include <linux/sched.h>
22151+#include <linux/types.h>
22152+#include <linux/ipc.h>
22153+#include <linux/grsecurity.h>
22154+#include <linux/grinternal.h>
22155+
22156+void
22157+gr_log_msgget(const int ret, const int msgflg)
22158+{
22159+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22160+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
22161+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
22162+ !grsec_enable_group)) && (ret >= 0)
22163+ && (msgflg & IPC_CREAT))
22164+ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
22165+#endif
22166+ return;
22167+}
22168+
22169+void
22170+gr_log_msgrm(const uid_t uid, const uid_t cuid)
22171+{
22172+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22173+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
22174+ grsec_enable_audit_ipc) ||
22175+ (grsec_enable_audit_ipc && !grsec_enable_group))
22176+ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
22177+#endif
22178+ return;
22179+}
22180+
22181+void
22182+gr_log_semget(const int err, const int semflg)
22183+{
22184+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22185+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
22186+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
22187+ !grsec_enable_group)) && (err >= 0)
22188+ && (semflg & IPC_CREAT))
22189+ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
22190+#endif
22191+ return;
22192+}
22193+
22194+void
22195+gr_log_semrm(const uid_t uid, const uid_t cuid)
22196+{
22197+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22198+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
22199+ grsec_enable_audit_ipc) ||
22200+ (grsec_enable_audit_ipc && !grsec_enable_group))
22201+ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
22202+#endif
22203+ return;
22204+}
22205+
22206+void
22207+gr_log_shmget(const int err, const int shmflg, const size_t size)
22208+{
22209+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22210+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
22211+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
22212+ !grsec_enable_group)) && (err >= 0)
22213+ && (shmflg & IPC_CREAT))
22214+ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
22215+#endif
22216+ return;
22217+}
22218+
22219+void
22220+gr_log_shmrm(const uid_t uid, const uid_t cuid)
22221+{
22222+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22223+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
22224+ grsec_enable_audit_ipc) ||
22225+ (grsec_enable_audit_ipc && !grsec_enable_group))
22226+ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
22227+#endif
22228+ return;
22229+}
22230diff -urNp linux-2.6.22.1/grsecurity/grsec_link.c linux-2.6.22.1/grsecurity/grsec_link.c
22231--- linux-2.6.22.1/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
22232+++ linux-2.6.22.1/grsecurity/grsec_link.c 2007-08-02 11:09:16.000000000 -0400
22233@@ -0,0 +1,39 @@
22234+#include <linux/kernel.h>
22235+#include <linux/sched.h>
22236+#include <linux/fs.h>
22237+#include <linux/file.h>
22238+#include <linux/grinternal.h>
22239+
22240+int
22241+gr_handle_follow_link(const struct inode *parent,
22242+ const struct inode *inode,
22243+ const struct dentry *dentry, const struct vfsmount *mnt)
22244+{
22245+#ifdef CONFIG_GRKERNSEC_LINK
22246+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
22247+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
22248+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
22249+ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
22250+ return -EACCES;
22251+ }
22252+#endif
22253+ return 0;
22254+}
22255+
22256+int
22257+gr_handle_hardlink(const struct dentry *dentry,
22258+ const struct vfsmount *mnt,
22259+ struct inode *inode, const int mode, const char *to)
22260+{
22261+#ifdef CONFIG_GRKERNSEC_LINK
22262+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
22263+ (!S_ISREG(mode) || (mode & S_ISUID) ||
22264+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
22265+ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
22266+ !capable(CAP_FOWNER) && current->uid) {
22267+ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
22268+ return -EPERM;
22269+ }
22270+#endif
22271+ return 0;
22272+}
22273diff -urNp linux-2.6.22.1/grsecurity/grsec_log.c linux-2.6.22.1/grsecurity/grsec_log.c
22274--- linux-2.6.22.1/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
22275+++ linux-2.6.22.1/grsecurity/grsec_log.c 2007-08-02 11:09:16.000000000 -0400
22276@@ -0,0 +1,269 @@
22277+#include <linux/kernel.h>
22278+#include <linux/sched.h>
22279+#include <linux/file.h>
22280+#include <linux/tty.h>
22281+#include <linux/fs.h>
22282+#include <linux/grinternal.h>
22283+
22284+#define BEGIN_LOCKS(x) \
22285+ read_lock(&tasklist_lock); \
22286+ read_lock(&grsec_exec_file_lock); \
22287+ if (x != GR_DO_AUDIT) \
22288+ spin_lock(&grsec_alert_lock); \
22289+ else \
22290+ spin_lock(&grsec_audit_lock)
22291+
22292+#define END_LOCKS(x) \
22293+ if (x != GR_DO_AUDIT) \
22294+ spin_unlock(&grsec_alert_lock); \
22295+ else \
22296+ spin_unlock(&grsec_audit_lock); \
22297+ read_unlock(&grsec_exec_file_lock); \
22298+ read_unlock(&tasklist_lock); \
22299+ if (x == GR_DONT_AUDIT) \
22300+ gr_handle_alertkill(current)
22301+
22302+enum {
22303+ FLOODING,
22304+ NO_FLOODING
22305+};
22306+
22307+extern char *gr_alert_log_fmt;
22308+extern char *gr_audit_log_fmt;
22309+extern char *gr_alert_log_buf;
22310+extern char *gr_audit_log_buf;
22311+
22312+static int gr_log_start(int audit)
22313+{
22314+ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
22315+ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
22316+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
22317+
22318+ if (audit == GR_DO_AUDIT)
22319+ goto set_fmt;
22320+
22321+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
22322+ grsec_alert_wtime = jiffies;
22323+ grsec_alert_fyet = 0;
22324+ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
22325+ grsec_alert_fyet++;
22326+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
22327+ grsec_alert_wtime = jiffies;
22328+ grsec_alert_fyet++;
22329+ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
22330+ return FLOODING;
22331+ } else return FLOODING;
22332+
22333+set_fmt:
22334+ memset(buf, 0, PAGE_SIZE);
22335+ if (current->signal->curr_ip && gr_acl_is_enabled()) {
22336+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
22337+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
22338+ } else if (current->signal->curr_ip) {
22339+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
22340+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
22341+ } else if (gr_acl_is_enabled()) {
22342+ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
22343+ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
22344+ } else {
22345+ sprintf(fmt, "%s%s", loglevel, "grsec: ");
22346+ strcpy(buf, fmt);
22347+ }
22348+
22349+ return NO_FLOODING;
22350+}
22351+
22352+static void gr_log_middle(int audit, const char *msg, va_list ap)
22353+{
22354+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
22355+ unsigned int len = strlen(buf);
22356+
22357+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
22358+
22359+ return;
22360+}
22361+
22362+static void gr_log_middle_varargs(int audit, const char *msg, ...)
22363+{
22364+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
22365+ unsigned int len = strlen(buf);
22366+ va_list ap;
22367+
22368+ va_start(ap, msg);
22369+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
22370+ va_end(ap);
22371+
22372+ return;
22373+}
22374+
22375+static void gr_log_end(int audit)
22376+{
22377+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
22378+ unsigned int len = strlen(buf);
22379+
22380+ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
22381+ printk("%s\n", buf);
22382+
22383+ return;
22384+}
22385+
22386+void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
22387+{
22388+ int logtype;
22389+ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
22390+ char *str1, *str2, *str3;
22391+ int num1, num2;
22392+ unsigned long ulong1, ulong2;
22393+ struct dentry *dentry;
22394+ struct vfsmount *mnt;
22395+ struct file *file;
22396+ struct task_struct *task;
22397+ va_list ap;
22398+
22399+ BEGIN_LOCKS(audit);
22400+ logtype = gr_log_start(audit);
22401+ if (logtype == FLOODING) {
22402+ END_LOCKS(audit);
22403+ return;
22404+ }
22405+ va_start(ap, argtypes);
22406+ switch (argtypes) {
22407+ case GR_TTYSNIFF:
22408+ task = va_arg(ap, struct task_struct *);
22409+ 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);
22410+ break;
22411+ case GR_SYSCTL_HIDDEN:
22412+ str1 = va_arg(ap, char *);
22413+ gr_log_middle_varargs(audit, msg, result, str1);
22414+ break;
22415+ case GR_RBAC:
22416+ dentry = va_arg(ap, struct dentry *);
22417+ mnt = va_arg(ap, struct vfsmount *);
22418+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
22419+ break;
22420+ case GR_RBAC_STR:
22421+ dentry = va_arg(ap, struct dentry *);
22422+ mnt = va_arg(ap, struct vfsmount *);
22423+ str1 = va_arg(ap, char *);
22424+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
22425+ break;
22426+ case GR_STR_RBAC:
22427+ str1 = va_arg(ap, char *);
22428+ dentry = va_arg(ap, struct dentry *);
22429+ mnt = va_arg(ap, struct vfsmount *);
22430+ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
22431+ break;
22432+ case GR_RBAC_MODE2:
22433+ dentry = va_arg(ap, struct dentry *);
22434+ mnt = va_arg(ap, struct vfsmount *);
22435+ str1 = va_arg(ap, char *);
22436+ str2 = va_arg(ap, char *);
22437+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
22438+ break;
22439+ case GR_RBAC_MODE3:
22440+ dentry = va_arg(ap, struct dentry *);
22441+ mnt = va_arg(ap, struct vfsmount *);
22442+ str1 = va_arg(ap, char *);
22443+ str2 = va_arg(ap, char *);
22444+ str3 = va_arg(ap, char *);
22445+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
22446+ break;
22447+ case GR_FILENAME:
22448+ dentry = va_arg(ap, struct dentry *);
22449+ mnt = va_arg(ap, struct vfsmount *);
22450+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
22451+ break;
22452+ case GR_STR_FILENAME:
22453+ str1 = va_arg(ap, char *);
22454+ dentry = va_arg(ap, struct dentry *);
22455+ mnt = va_arg(ap, struct vfsmount *);
22456+ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
22457+ break;
22458+ case GR_FILENAME_STR:
22459+ dentry = va_arg(ap, struct dentry *);
22460+ mnt = va_arg(ap, struct vfsmount *);
22461+ str1 = va_arg(ap, char *);
22462+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
22463+ break;
22464+ case GR_FILENAME_TWO_INT:
22465+ dentry = va_arg(ap, struct dentry *);
22466+ mnt = va_arg(ap, struct vfsmount *);
22467+ num1 = va_arg(ap, int);
22468+ num2 = va_arg(ap, int);
22469+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
22470+ break;
22471+ case GR_FILENAME_TWO_INT_STR:
22472+ dentry = va_arg(ap, struct dentry *);
22473+ mnt = va_arg(ap, struct vfsmount *);
22474+ num1 = va_arg(ap, int);
22475+ num2 = va_arg(ap, int);
22476+ str1 = va_arg(ap, char *);
22477+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
22478+ break;
22479+ case GR_TEXTREL:
22480+ file = va_arg(ap, struct file *);
22481+ ulong1 = va_arg(ap, unsigned long);
22482+ ulong2 = va_arg(ap, unsigned long);
22483+ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
22484+ break;
22485+ case GR_PTRACE:
22486+ task = va_arg(ap, struct task_struct *);
22487+ 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);
22488+ break;
22489+ case GR_RESOURCE:
22490+ task = va_arg(ap, struct task_struct *);
22491+ ulong1 = va_arg(ap, unsigned long);
22492+ str1 = va_arg(ap, char *);
22493+ ulong2 = va_arg(ap, unsigned long);
22494+ 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);
22495+ break;
22496+ case GR_CAP:
22497+ task = va_arg(ap, struct task_struct *);
22498+ str1 = va_arg(ap, char *);
22499+ 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);
22500+ break;
22501+ case GR_SIG:
22502+ task = va_arg(ap, struct task_struct *);
22503+ num1 = va_arg(ap, int);
22504+ 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);
22505+ break;
22506+ case GR_CRASH1:
22507+ task = va_arg(ap, struct task_struct *);
22508+ ulong1 = va_arg(ap, unsigned long);
22509+ 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);
22510+ break;
22511+ case GR_CRASH2:
22512+ task = va_arg(ap, struct task_struct *);
22513+ ulong1 = va_arg(ap, unsigned long);
22514+ 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);
22515+ break;
22516+ case GR_PSACCT:
22517+ {
22518+ unsigned int wday, cday;
22519+ __u8 whr, chr;
22520+ __u8 wmin, cmin;
22521+ __u8 wsec, csec;
22522+ char cur_tty[64] = { 0 };
22523+ char parent_tty[64] = { 0 };
22524+
22525+ task = va_arg(ap, struct task_struct *);
22526+ wday = va_arg(ap, unsigned int);
22527+ cday = va_arg(ap, unsigned int);
22528+ whr = va_arg(ap, int);
22529+ chr = va_arg(ap, int);
22530+ wmin = va_arg(ap, int);
22531+ cmin = va_arg(ap, int);
22532+ wsec = va_arg(ap, int);
22533+ csec = va_arg(ap, int);
22534+ ulong1 = va_arg(ap, unsigned long);
22535+
22536+ 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);
22537+ }
22538+ break;
22539+ default:
22540+ gr_log_middle(audit, msg, ap);
22541+ }
22542+ va_end(ap);
22543+ gr_log_end(audit);
22544+ END_LOCKS(audit);
22545+}
22546diff -urNp linux-2.6.22.1/grsecurity/grsec_mem.c linux-2.6.22.1/grsecurity/grsec_mem.c
22547--- linux-2.6.22.1/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
22548+++ linux-2.6.22.1/grsecurity/grsec_mem.c 2007-08-02 11:09:16.000000000 -0400
22549@@ -0,0 +1,71 @@
22550+#include <linux/kernel.h>
22551+#include <linux/sched.h>
22552+#include <linux/mm.h>
22553+#include <linux/mman.h>
22554+#include <linux/grinternal.h>
22555+
22556+void
22557+gr_handle_ioperm(void)
22558+{
22559+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
22560+ return;
22561+}
22562+
22563+void
22564+gr_handle_iopl(void)
22565+{
22566+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
22567+ return;
22568+}
22569+
22570+void
22571+gr_handle_mem_write(void)
22572+{
22573+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
22574+ return;
22575+}
22576+
22577+void
22578+gr_handle_kmem_write(void)
22579+{
22580+ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
22581+ return;
22582+}
22583+
22584+void
22585+gr_handle_open_port(void)
22586+{
22587+ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
22588+ return;
22589+}
22590+
22591+int
22592+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
22593+{
22594+ unsigned long start, end;
22595+
22596+ start = offset;
22597+ end = start + vma->vm_end - vma->vm_start;
22598+
22599+ if (start > end) {
22600+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
22601+ return -EPERM;
22602+ }
22603+
22604+ /* allowed ranges : ISA I/O BIOS */
22605+ if ((start >= __pa(high_memory))
22606+#ifdef CONFIG_X86
22607+ || (start >= 0x000a0000 && end <= 0x00100000)
22608+ || (start >= 0x00000000 && end <= 0x00001000)
22609+#endif
22610+ )
22611+ return 0;
22612+
22613+ if (vma->vm_flags & VM_WRITE) {
22614+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
22615+ return -EPERM;
22616+ } else
22617+ vma->vm_flags &= ~VM_MAYWRITE;
22618+
22619+ return 0;
22620+}
22621diff -urNp linux-2.6.22.1/grsecurity/grsec_mount.c linux-2.6.22.1/grsecurity/grsec_mount.c
22622--- linux-2.6.22.1/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
22623+++ linux-2.6.22.1/grsecurity/grsec_mount.c 2007-08-02 11:09:16.000000000 -0400
22624@@ -0,0 +1,34 @@
22625+#include <linux/kernel.h>
22626+#include <linux/sched.h>
22627+#include <linux/grsecurity.h>
22628+#include <linux/grinternal.h>
22629+
22630+void
22631+gr_log_remount(const char *devname, const int retval)
22632+{
22633+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
22634+ if (grsec_enable_mount && (retval >= 0))
22635+ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
22636+#endif
22637+ return;
22638+}
22639+
22640+void
22641+gr_log_unmount(const char *devname, const int retval)
22642+{
22643+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
22644+ if (grsec_enable_mount && (retval >= 0))
22645+ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
22646+#endif
22647+ return;
22648+}
22649+
22650+void
22651+gr_log_mount(const char *from, const char *to, const int retval)
22652+{
22653+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
22654+ if (grsec_enable_mount && (retval >= 0))
22655+ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
22656+#endif
22657+ return;
22658+}
22659diff -urNp linux-2.6.22.1/grsecurity/grsec_sig.c linux-2.6.22.1/grsecurity/grsec_sig.c
22660--- linux-2.6.22.1/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
22661+++ linux-2.6.22.1/grsecurity/grsec_sig.c 2007-08-02 11:09:16.000000000 -0400
22662@@ -0,0 +1,59 @@
22663+#include <linux/kernel.h>
22664+#include <linux/sched.h>
22665+#include <linux/grsecurity.h>
22666+#include <linux/grinternal.h>
22667+
22668+void
22669+gr_log_signal(const int sig, const struct task_struct *t)
22670+{
22671+#ifdef CONFIG_GRKERNSEC_SIGNAL
22672+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
22673+ (sig == SIGABRT) || (sig == SIGBUS))) {
22674+ if (t->pid == current->pid) {
22675+ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
22676+ } else {
22677+ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
22678+ }
22679+ }
22680+#endif
22681+ return;
22682+}
22683+
22684+int
22685+gr_handle_signal(const struct task_struct *p, const int sig)
22686+{
22687+#ifdef CONFIG_GRKERNSEC
22688+ if (current->pid > 1 && gr_check_protected_task(p)) {
22689+ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
22690+ return -EPERM;
22691+ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
22692+ return -EPERM;
22693+ }
22694+#endif
22695+ return 0;
22696+}
22697+
22698+void gr_handle_brute_attach(struct task_struct *p)
22699+{
22700+#ifdef CONFIG_GRKERNSEC_BRUTE
22701+ read_lock(&tasklist_lock);
22702+ read_lock(&grsec_exec_file_lock);
22703+ if (p->parent && p->parent->exec_file == p->exec_file)
22704+ p->parent->brute = 1;
22705+ read_unlock(&grsec_exec_file_lock);
22706+ read_unlock(&tasklist_lock);
22707+#endif
22708+ return;
22709+}
22710+
22711+void gr_handle_brute_check(void)
22712+{
22713+#ifdef CONFIG_GRKERNSEC_BRUTE
22714+ if (current->brute) {
22715+ set_current_state(TASK_UNINTERRUPTIBLE);
22716+ schedule_timeout(30 * HZ);
22717+ }
22718+#endif
22719+ return;
22720+}
22721+
22722diff -urNp linux-2.6.22.1/grsecurity/grsec_sock.c linux-2.6.22.1/grsecurity/grsec_sock.c
22723--- linux-2.6.22.1/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
22724+++ linux-2.6.22.1/grsecurity/grsec_sock.c 2007-08-02 11:09:16.000000000 -0400
22725@@ -0,0 +1,263 @@
22726+#include <linux/kernel.h>
22727+#include <linux/module.h>
22728+#include <linux/sched.h>
22729+#include <linux/file.h>
22730+#include <linux/net.h>
22731+#include <linux/in.h>
22732+#include <linux/ip.h>
22733+#include <net/sock.h>
22734+#include <net/inet_sock.h>
22735+#include <linux/grsecurity.h>
22736+#include <linux/grinternal.h>
22737+#include <linux/gracl.h>
22738+
22739+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
22740+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
22741+EXPORT_SYMBOL(udp_v4_lookup);
22742+#endif
22743+
22744+EXPORT_SYMBOL(gr_cap_rtnetlink);
22745+
22746+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
22747+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
22748+
22749+EXPORT_SYMBOL(gr_search_udp_recvmsg);
22750+EXPORT_SYMBOL(gr_search_udp_sendmsg);
22751+
22752+#ifdef CONFIG_UNIX_MODULE
22753+EXPORT_SYMBOL(gr_acl_handle_unix);
22754+EXPORT_SYMBOL(gr_acl_handle_mknod);
22755+EXPORT_SYMBOL(gr_handle_chroot_unix);
22756+EXPORT_SYMBOL(gr_handle_create);
22757+#endif
22758+
22759+#ifdef CONFIG_GRKERNSEC
22760+#define gr_conn_table_size 32749
22761+struct conn_table_entry {
22762+ struct conn_table_entry *next;
22763+ struct signal_struct *sig;
22764+};
22765+
22766+struct conn_table_entry *gr_conn_table[gr_conn_table_size];
22767+spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
22768+
22769+extern const char * gr_socktype_to_name(unsigned char type);
22770+extern const char * gr_proto_to_name(unsigned char proto);
22771+
22772+static __inline__ int
22773+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
22774+{
22775+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
22776+}
22777+
22778+static __inline__ int
22779+conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
22780+ __u16 sport, __u16 dport)
22781+{
22782+ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
22783+ sig->gr_sport == sport && sig->gr_dport == dport))
22784+ return 1;
22785+ else
22786+ return 0;
22787+}
22788+
22789+static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
22790+{
22791+ struct conn_table_entry **match;
22792+ unsigned int index;
22793+
22794+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
22795+ sig->gr_sport, sig->gr_dport,
22796+ gr_conn_table_size);
22797+
22798+ newent->sig = sig;
22799+
22800+ match = &gr_conn_table[index];
22801+ newent->next = *match;
22802+ *match = newent;
22803+
22804+ return;
22805+}
22806+
22807+static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
22808+{
22809+ struct conn_table_entry *match, *last = NULL;
22810+ unsigned int index;
22811+
22812+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
22813+ sig->gr_sport, sig->gr_dport,
22814+ gr_conn_table_size);
22815+
22816+ match = gr_conn_table[index];
22817+ while (match && !conn_match(match->sig,
22818+ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
22819+ sig->gr_dport)) {
22820+ last = match;
22821+ match = match->next;
22822+ }
22823+
22824+ if (match) {
22825+ if (last)
22826+ last->next = match->next;
22827+ else
22828+ gr_conn_table[index] = NULL;
22829+ kfree(match);
22830+ }
22831+
22832+ return;
22833+}
22834+
22835+static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
22836+ __u16 sport, __u16 dport)
22837+{
22838+ struct conn_table_entry *match;
22839+ unsigned int index;
22840+
22841+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
22842+
22843+ match = gr_conn_table[index];
22844+ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
22845+ match = match->next;
22846+
22847+ if (match)
22848+ return match->sig;
22849+ else
22850+ return NULL;
22851+}
22852+
22853+#endif
22854+
22855+void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
22856+{
22857+#ifdef CONFIG_GRKERNSEC
22858+ struct signal_struct *sig = task->signal;
22859+ struct conn_table_entry *newent;
22860+
22861+ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
22862+ if (newent == NULL)
22863+ return;
22864+ /* no bh lock needed since we are called with bh disabled */
22865+ spin_lock(&gr_conn_table_lock);
22866+ gr_del_task_from_ip_table_nolock(sig);
22867+ sig->gr_saddr = inet->rcv_saddr;
22868+ sig->gr_daddr = inet->daddr;
22869+ sig->gr_sport = inet->sport;
22870+ sig->gr_dport = inet->dport;
22871+ gr_add_to_task_ip_table_nolock(sig, newent);
22872+ spin_unlock(&gr_conn_table_lock);
22873+#endif
22874+ return;
22875+}
22876+
22877+void gr_del_task_from_ip_table(struct task_struct *task)
22878+{
22879+#ifdef CONFIG_GRKERNSEC
22880+ spin_lock(&gr_conn_table_lock);
22881+ gr_del_task_from_ip_table_nolock(task->signal);
22882+ spin_unlock(&gr_conn_table_lock);
22883+#endif
22884+ return;
22885+}
22886+
22887+void
22888+gr_attach_curr_ip(const struct sock *sk)
22889+{
22890+#ifdef CONFIG_GRKERNSEC
22891+ struct signal_struct *p, *set;
22892+ const struct inet_sock *inet = inet_sk(sk);
22893+
22894+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
22895+ return;
22896+
22897+ set = current->signal;
22898+
22899+ spin_lock_bh(&gr_conn_table_lock);
22900+ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
22901+ inet->dport, inet->sport);
22902+ if (unlikely(p != NULL)) {
22903+ set->curr_ip = p->curr_ip;
22904+ set->used_accept = 1;
22905+ gr_del_task_from_ip_table_nolock(p);
22906+ spin_unlock_bh(&gr_conn_table_lock);
22907+ return;
22908+ }
22909+ spin_unlock_bh(&gr_conn_table_lock);
22910+
22911+ set->curr_ip = inet->daddr;
22912+ set->used_accept = 1;
22913+#endif
22914+ return;
22915+}
22916+
22917+int
22918+gr_handle_sock_all(const int family, const int type, const int protocol)
22919+{
22920+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
22921+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
22922+ (family != AF_UNIX) && (family != AF_LOCAL)) {
22923+ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
22924+ return -EACCES;
22925+ }
22926+#endif
22927+ return 0;
22928+}
22929+
22930+int
22931+gr_handle_sock_server(const struct sockaddr *sck)
22932+{
22933+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
22934+ if (grsec_enable_socket_server &&
22935+ in_group_p(grsec_socket_server_gid) &&
22936+ sck && (sck->sa_family != AF_UNIX) &&
22937+ (sck->sa_family != AF_LOCAL)) {
22938+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
22939+ return -EACCES;
22940+ }
22941+#endif
22942+ return 0;
22943+}
22944+
22945+int
22946+gr_handle_sock_server_other(const struct sock *sck)
22947+{
22948+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
22949+ if (grsec_enable_socket_server &&
22950+ in_group_p(grsec_socket_server_gid) &&
22951+ sck && (sck->sk_family != AF_UNIX) &&
22952+ (sck->sk_family != AF_LOCAL)) {
22953+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
22954+ return -EACCES;
22955+ }
22956+#endif
22957+ return 0;
22958+}
22959+
22960+int
22961+gr_handle_sock_client(const struct sockaddr *sck)
22962+{
22963+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
22964+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
22965+ sck && (sck->sa_family != AF_UNIX) &&
22966+ (sck->sa_family != AF_LOCAL)) {
22967+ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
22968+ return -EACCES;
22969+ }
22970+#endif
22971+ return 0;
22972+}
22973+
22974+__u32
22975+gr_cap_rtnetlink(void)
22976+{
22977+#ifdef CONFIG_GRKERNSEC
22978+ if (!gr_acl_is_enabled())
22979+ return current->cap_effective;
22980+ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
22981+ gr_task_is_capable(current, CAP_NET_ADMIN))
22982+ return current->cap_effective;
22983+ else
22984+ return 0;
22985+#else
22986+ return current->cap_effective;
22987+#endif
22988+}
22989diff -urNp linux-2.6.22.1/grsecurity/grsec_sysctl.c linux-2.6.22.1/grsecurity/grsec_sysctl.c
22990--- linux-2.6.22.1/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
22991+++ linux-2.6.22.1/grsecurity/grsec_sysctl.c 2007-08-02 11:09:16.000000000 -0400
22992@@ -0,0 +1,456 @@
22993+#include <linux/kernel.h>
22994+#include <linux/sched.h>
22995+#include <linux/sysctl.h>
22996+#include <linux/grsecurity.h>
22997+#include <linux/grinternal.h>
22998+
22999+#ifdef CONFIG_GRKERNSEC_MODSTOP
23000+int grsec_modstop;
23001+#endif
23002+
23003+int
23004+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
23005+{
23006+#ifdef CONFIG_GRKERNSEC_SYSCTL
23007+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
23008+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
23009+ return -EACCES;
23010+ }
23011+#endif
23012+#ifdef CONFIG_GRKERNSEC_MODSTOP
23013+ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
23014+ grsec_modstop && (op & 002)) {
23015+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
23016+ return -EACCES;
23017+ }
23018+#endif
23019+ return 0;
23020+}
23021+
23022+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
23023+enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
23024+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
23025+GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
23026+GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
23027+GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
23028+GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
23029+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
23030+GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
23031+GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
23032+
23033+
23034+ctl_table grsecurity_table[] = {
23035+#ifdef CONFIG_GRKERNSEC_SYSCTL
23036+#ifdef CONFIG_GRKERNSEC_LINK
23037+ {
23038+ .ctl_name = GS_LINK,
23039+ .procname = "linking_restrictions",
23040+ .data = &grsec_enable_link,
23041+ .maxlen = sizeof(int),
23042+ .mode = 0600,
23043+ .proc_handler = &proc_dointvec,
23044+ },
23045+#endif
23046+#ifdef CONFIG_GRKERNSEC_FIFO
23047+ {
23048+ .ctl_name = GS_FIFO,
23049+ .procname = "fifo_restrictions",
23050+ .data = &grsec_enable_fifo,
23051+ .maxlen = sizeof(int),
23052+ .mode = 0600,
23053+ .proc_handler = &proc_dointvec,
23054+ },
23055+#endif
23056+#ifdef CONFIG_GRKERNSEC_EXECVE
23057+ {
23058+ .ctl_name = GS_EXECVE,
23059+ .procname = "execve_limiting",
23060+ .data = &grsec_enable_execve,
23061+ .maxlen = sizeof(int),
23062+ .mode = 0600,
23063+ .proc_handler = &proc_dointvec,
23064+ },
23065+#endif
23066+#ifdef CONFIG_GRKERNSEC_EXECLOG
23067+ {
23068+ .ctl_name = GS_EXECLOG,
23069+ .procname = "exec_logging",
23070+ .data = &grsec_enable_execlog,
23071+ .maxlen = sizeof(int),
23072+ .mode = 0600,
23073+ .proc_handler = &proc_dointvec,
23074+ },
23075+#endif
23076+#ifdef CONFIG_GRKERNSEC_SIGNAL
23077+ {
23078+ .ctl_name = GS_SIGNAL,
23079+ .procname = "signal_logging",
23080+ .data = &grsec_enable_signal,
23081+ .maxlen = sizeof(int),
23082+ .mode = 0600,
23083+ .proc_handler = &proc_dointvec,
23084+ },
23085+#endif
23086+#ifdef CONFIG_GRKERNSEC_FORKFAIL
23087+ {
23088+ .ctl_name = GS_FORKFAIL,
23089+ .procname = "forkfail_logging",
23090+ .data = &grsec_enable_forkfail,
23091+ .maxlen = sizeof(int),
23092+ .mode = 0600,
23093+ .proc_handler = &proc_dointvec,
23094+ },
23095+#endif
23096+#ifdef CONFIG_GRKERNSEC_TIME
23097+ {
23098+ .ctl_name = GS_TIME,
23099+ .procname = "timechange_logging",
23100+ .data = &grsec_enable_time,
23101+ .maxlen = sizeof(int),
23102+ .mode = 0600,
23103+ .proc_handler = &proc_dointvec,
23104+ },
23105+#endif
23106+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23107+ {
23108+ .ctl_name = GS_CHROOT_SHMAT,
23109+ .procname = "chroot_deny_shmat",
23110+ .data = &grsec_enable_chroot_shmat,
23111+ .maxlen = sizeof(int),
23112+ .mode = 0600,
23113+ .proc_handler = &proc_dointvec,
23114+ },
23115+#endif
23116+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23117+ {
23118+ .ctl_name = GS_CHROOT_UNIX,
23119+ .procname = "chroot_deny_unix",
23120+ .data = &grsec_enable_chroot_unix,
23121+ .maxlen = sizeof(int),
23122+ .mode = 0600,
23123+ .proc_handler = &proc_dointvec,
23124+ },
23125+#endif
23126+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23127+ {
23128+ .ctl_name = GS_CHROOT_MNT,
23129+ .procname = "chroot_deny_mount",
23130+ .data = &grsec_enable_chroot_mount,
23131+ .maxlen = sizeof(int),
23132+ .mode = 0600,
23133+ .proc_handler = &proc_dointvec,
23134+ },
23135+#endif
23136+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23137+ {
23138+ .ctl_name = GS_CHROOT_FCHDIR,
23139+ .procname = "chroot_deny_fchdir",
23140+ .data = &grsec_enable_chroot_fchdir,
23141+ .maxlen = sizeof(int),
23142+ .mode = 0600,
23143+ .proc_handler = &proc_dointvec,
23144+ },
23145+#endif
23146+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23147+ {
23148+ .ctl_name = GS_CHROOT_DBL,
23149+ .procname = "chroot_deny_chroot",
23150+ .data = &grsec_enable_chroot_double,
23151+ .maxlen = sizeof(int),
23152+ .mode = 0600,
23153+ .proc_handler = &proc_dointvec,
23154+ },
23155+#endif
23156+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23157+ {
23158+ .ctl_name = GS_CHROOT_PVT,
23159+ .procname = "chroot_deny_pivot",
23160+ .data = &grsec_enable_chroot_pivot,
23161+ .maxlen = sizeof(int),
23162+ .mode = 0600,
23163+ .proc_handler = &proc_dointvec,
23164+ },
23165+#endif
23166+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23167+ {
23168+ .ctl_name = GS_CHROOT_CD,
23169+ .procname = "chroot_enforce_chdir",
23170+ .data = &grsec_enable_chroot_chdir,
23171+ .maxlen = sizeof(int),
23172+ .mode = 0600,
23173+ .proc_handler = &proc_dointvec,
23174+ },
23175+#endif
23176+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23177+ {
23178+ .ctl_name = GS_CHROOT_CM,
23179+ .procname = "chroot_deny_chmod",
23180+ .data = &grsec_enable_chroot_chmod,
23181+ .maxlen = sizeof(int),
23182+ .mode = 0600,
23183+ .proc_handler = &proc_dointvec,
23184+ },
23185+#endif
23186+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23187+ {
23188+ .ctl_name = GS_CHROOT_MK,
23189+ .procname = "chroot_deny_mknod",
23190+ .data = &grsec_enable_chroot_mknod,
23191+ .maxlen = sizeof(int),
23192+ .mode = 0600,
23193+ .proc_handler = &proc_dointvec,
23194+ },
23195+#endif
23196+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23197+ {
23198+ .ctl_name = GS_CHROOT_NI,
23199+ .procname = "chroot_restrict_nice",
23200+ .data = &grsec_enable_chroot_nice,
23201+ .maxlen = sizeof(int),
23202+ .mode = 0600,
23203+ .proc_handler = &proc_dointvec,
23204+ },
23205+#endif
23206+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23207+ {
23208+ .ctl_name = GS_CHROOT_EXECLOG,
23209+ .procname = "chroot_execlog",
23210+ .data = &grsec_enable_chroot_execlog,
23211+ .maxlen = sizeof(int),
23212+ .mode = 0600,
23213+ .proc_handler = &proc_dointvec,
23214+ },
23215+#endif
23216+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23217+ {
23218+ .ctl_name = GS_CHROOT_CAPS,
23219+ .procname = "chroot_caps",
23220+ .data = &grsec_enable_chroot_caps,
23221+ .maxlen = sizeof(int),
23222+ .mode = 0600,
23223+ .proc_handler = &proc_dointvec,
23224+ },
23225+#endif
23226+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23227+ {
23228+ .ctl_name = GS_CHROOT_SYSCTL,
23229+ .procname = "chroot_deny_sysctl",
23230+ .data = &grsec_enable_chroot_sysctl,
23231+ .maxlen = sizeof(int),
23232+ .mode = 0600,
23233+ .proc_handler = &proc_dointvec,
23234+ },
23235+#endif
23236+#ifdef CONFIG_GRKERNSEC_TPE
23237+ {
23238+ .ctl_name = GS_TPE,
23239+ .procname = "tpe",
23240+ .data = &grsec_enable_tpe,
23241+ .maxlen = sizeof(int),
23242+ .mode = 0600,
23243+ .proc_handler = &proc_dointvec,
23244+ },
23245+ {
23246+ .ctl_name = GS_TPE_GID,
23247+ .procname = "tpe_gid",
23248+ .data = &grsec_tpe_gid,
23249+ .maxlen = sizeof(int),
23250+ .mode = 0600,
23251+ .proc_handler = &proc_dointvec,
23252+ },
23253+#endif
23254+#ifdef CONFIG_GRKERNSEC_TPE_ALL
23255+ {
23256+ .ctl_name = GS_TPE_ALL,
23257+ .procname = "tpe_restrict_all",
23258+ .data = &grsec_enable_tpe_all,
23259+ .maxlen = sizeof(int),
23260+ .mode = 0600,
23261+ .proc_handler = &proc_dointvec,
23262+ },
23263+#endif
23264+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
23265+ {
23266+ .ctl_name = GS_SOCKET_ALL,
23267+ .procname = "socket_all",
23268+ .data = &grsec_enable_socket_all,
23269+ .maxlen = sizeof(int),
23270+ .mode = 0600,
23271+ .proc_handler = &proc_dointvec,
23272+ },
23273+ {
23274+ .ctl_name = GS_SOCKET_ALL_GID,
23275+ .procname = "socket_all_gid",
23276+ .data = &grsec_socket_all_gid,
23277+ .maxlen = sizeof(int),
23278+ .mode = 0600,
23279+ .proc_handler = &proc_dointvec,
23280+ },
23281+#endif
23282+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
23283+ {
23284+ .ctl_name = GS_SOCKET_CLIENT,
23285+ .procname = "socket_client",
23286+ .data = &grsec_enable_socket_client,
23287+ .maxlen = sizeof(int),
23288+ .mode = 0600,
23289+ .proc_handler = &proc_dointvec,
23290+ },
23291+ {
23292+ .ctl_name = GS_SOCKET_CLIENT_GID,
23293+ .procname = "socket_client_gid",
23294+ .data = &grsec_socket_client_gid,
23295+ .maxlen = sizeof(int),
23296+ .mode = 0600,
23297+ .proc_handler = &proc_dointvec,
23298+ },
23299+#endif
23300+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
23301+ {
23302+ .ctl_name = GS_SOCKET_SERVER,
23303+ .procname = "socket_server",
23304+ .data = &grsec_enable_socket_server,
23305+ .maxlen = sizeof(int),
23306+ .mode = 0600,
23307+ .proc_handler = &proc_dointvec,
23308+ },
23309+ {
23310+ .ctl_name = GS_SOCKET_SERVER_GID,
23311+ .procname = "socket_server_gid",
23312+ .data = &grsec_socket_server_gid,
23313+ .maxlen = sizeof(int),
23314+ .mode = 0600,
23315+ .proc_handler = &proc_dointvec,
23316+ },
23317+#endif
23318+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
23319+ {
23320+ .ctl_name = GS_GROUP,
23321+ .procname = "audit_group",
23322+ .data = &grsec_enable_group,
23323+ .maxlen = sizeof(int),
23324+ .mode = 0600,
23325+ .proc_handler = &proc_dointvec,
23326+ },
23327+ {
23328+ .ctl_name = GS_GID,
23329+ .procname = "audit_gid",
23330+ .data = &grsec_audit_gid,
23331+ .maxlen = sizeof(int),
23332+ .mode = 0600,
23333+ .proc_handler = &proc_dointvec,
23334+ },
23335+#endif
23336+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23337+ {
23338+ .ctl_name = GS_ACHDIR,
23339+ .procname = "audit_chdir",
23340+ .data = &grsec_enable_chdir,
23341+ .maxlen = sizeof(int),
23342+ .mode = 0600,
23343+ .proc_handler = &proc_dointvec,
23344+ },
23345+#endif
23346+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23347+ {
23348+ .ctl_name = GS_AMOUNT,
23349+ .procname = "audit_mount",
23350+ .data = &grsec_enable_mount,
23351+ .maxlen = sizeof(int),
23352+ .mode = 0600,
23353+ .proc_handler = &proc_dointvec,
23354+ },
23355+#endif
23356+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23357+ {
23358+ .ctl_name = GS_AIPC,
23359+ .procname = "audit_ipc",
23360+ .data = &grsec_enable_audit_ipc,
23361+ .maxlen = sizeof(int),
23362+ .mode = 0600,
23363+ .proc_handler = &proc_dointvec,
23364+ },
23365+#endif
23366+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23367+ {
23368+ .ctl_name = GS_TEXTREL,
23369+ .procname = "audit_textrel",
23370+ .data = &grsec_enable_audit_textrel,
23371+ .maxlen = sizeof(int),
23372+ .mode = 0600,
23373+ .proc_handler = &proc_dointvec,
23374+ },
23375+#endif
23376+#ifdef CONFIG_GRKERNSEC_DMESG
23377+ {
23378+ .ctl_name = GS_DMSG,
23379+ .procname = "dmesg",
23380+ .data = &grsec_enable_dmesg,
23381+ .maxlen = sizeof(int),
23382+ .mode = 0600,
23383+ .proc_handler = &proc_dointvec,
23384+ },
23385+#endif
23386+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23387+ {
23388+ .ctl_name = GS_FINDTASK,
23389+ .procname = "chroot_findtask",
23390+ .data = &grsec_enable_chroot_findtask,
23391+ .maxlen = sizeof(int),
23392+ .mode = 0600,
23393+ .proc_handler = &proc_dointvec,
23394+ },
23395+#endif
23396+#ifdef CONFIG_GRKERNSEC_SHM
23397+ {
23398+ .ctl_name = GS_SHM,
23399+ .procname = "destroy_unused_shm",
23400+ .data = &grsec_enable_shm,
23401+ .maxlen = sizeof(int),
23402+ .mode = 0600,
23403+ .proc_handler = &proc_dointvec,
23404+ },
23405+#endif
23406+#ifdef CONFIG_GRKERNSEC_RESLOG
23407+ {
23408+ .ctl_name = GS_RESLOG,
23409+ .procname = "resource_logging",
23410+ .data = &grsec_resource_logging,
23411+ .maxlen = sizeof(int),
23412+ .mode = 0600,
23413+ .proc_handler = &proc_dointvec,
23414+ },
23415+#endif
23416+ {
23417+ .ctl_name = GS_LOCK,
23418+ .procname = "grsec_lock",
23419+ .data = &grsec_lock,
23420+ .maxlen = sizeof(int),
23421+ .mode = 0600,
23422+ .proc_handler = &proc_dointvec,
23423+ },
23424+#endif
23425+#ifdef CONFIG_GRKERNSEC_MODSTOP
23426+ {
23427+ .ctl_name = GS_MODSTOP,
23428+ .procname = "disable_modules",
23429+ .data = &grsec_modstop,
23430+ .maxlen = sizeof(int),
23431+ .mode = 0600,
23432+ .proc_handler = &proc_dointvec,
23433+ },
23434+#endif
23435+ { .ctl_name = 0 }
23436+};
23437+#endif
23438+
23439+int gr_check_modstop(void)
23440+{
23441+#ifdef CONFIG_GRKERNSEC_MODSTOP
23442+ if (grsec_modstop == 1) {
23443+ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
23444+ return 1;
23445+ }
23446+#endif
23447+ return 0;
23448+}
23449diff -urNp linux-2.6.22.1/grsecurity/grsec_textrel.c linux-2.6.22.1/grsecurity/grsec_textrel.c
23450--- linux-2.6.22.1/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
23451+++ linux-2.6.22.1/grsecurity/grsec_textrel.c 2007-08-02 11:09:16.000000000 -0400
23452@@ -0,0 +1,16 @@
23453+#include <linux/kernel.h>
23454+#include <linux/sched.h>
23455+#include <linux/mm.h>
23456+#include <linux/file.h>
23457+#include <linux/grinternal.h>
23458+#include <linux/grsecurity.h>
23459+
23460+void
23461+gr_log_textrel(struct vm_area_struct * vma)
23462+{
23463+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23464+ if (grsec_enable_audit_textrel)
23465+ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
23466+#endif
23467+ return;
23468+}
23469diff -urNp linux-2.6.22.1/grsecurity/grsec_time.c linux-2.6.22.1/grsecurity/grsec_time.c
23470--- linux-2.6.22.1/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
23471+++ linux-2.6.22.1/grsecurity/grsec_time.c 2007-08-02 11:09:16.000000000 -0400
23472@@ -0,0 +1,13 @@
23473+#include <linux/kernel.h>
23474+#include <linux/sched.h>
23475+#include <linux/grinternal.h>
23476+
23477+void
23478+gr_log_timechange(void)
23479+{
23480+#ifdef CONFIG_GRKERNSEC_TIME
23481+ if (grsec_enable_time)
23482+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
23483+#endif
23484+ return;
23485+}
23486diff -urNp linux-2.6.22.1/grsecurity/grsec_tpe.c linux-2.6.22.1/grsecurity/grsec_tpe.c
23487--- linux-2.6.22.1/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
23488+++ linux-2.6.22.1/grsecurity/grsec_tpe.c 2007-08-02 11:09:16.000000000 -0400
23489@@ -0,0 +1,37 @@
23490+#include <linux/kernel.h>
23491+#include <linux/sched.h>
23492+#include <linux/file.h>
23493+#include <linux/fs.h>
23494+#include <linux/grinternal.h>
23495+
23496+extern int gr_acl_tpe_check(void);
23497+
23498+int
23499+gr_tpe_allow(const struct file *file)
23500+{
23501+#ifdef CONFIG_GRKERNSEC
23502+ struct inode *inode = file->f_dentry->d_parent->d_inode;
23503+
23504+ if (current->uid && ((grsec_enable_tpe &&
23505+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
23506+ !in_group_p(grsec_tpe_gid)
23507+#else
23508+ in_group_p(grsec_tpe_gid)
23509+#endif
23510+ ) || gr_acl_tpe_check()) &&
23511+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
23512+ (inode->i_mode & S_IWOTH))))) {
23513+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
23514+ return 0;
23515+ }
23516+#ifdef CONFIG_GRKERNSEC_TPE_ALL
23517+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
23518+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
23519+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
23520+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
23521+ return 0;
23522+ }
23523+#endif
23524+#endif
23525+ return 1;
23526+}
23527diff -urNp linux-2.6.22.1/grsecurity/grsum.c linux-2.6.22.1/grsecurity/grsum.c
23528--- linux-2.6.22.1/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
23529+++ linux-2.6.22.1/grsecurity/grsum.c 2007-08-02 11:09:16.000000000 -0400
23530@@ -0,0 +1,58 @@
23531+#include <linux/kernel.h>
23532+#include <linux/sched.h>
23533+#include <linux/mm.h>
23534+#include <linux/scatterlist.h>
23535+#include <linux/crypto.h>
23536+#include <linux/gracl.h>
23537+
23538+
23539+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
23540+#error "crypto and sha256 must be built into the kernel"
23541+#endif
23542+
23543+int
23544+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
23545+{
23546+ char *p;
23547+ struct crypto_hash *tfm;
23548+ struct hash_desc desc;
23549+ struct scatterlist sg;
23550+ unsigned char temp_sum[GR_SHA_LEN];
23551+ volatile int retval = 0;
23552+ volatile int dummy = 0;
23553+ unsigned int i;
23554+
23555+ tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
23556+ if (IS_ERR(tfm)) {
23557+ /* should never happen, since sha256 should be built in */
23558+ return 1;
23559+ }
23560+
23561+ desc.tfm = tfm;
23562+ desc.flags = 0;
23563+
23564+ crypto_hash_init(&desc);
23565+
23566+ p = salt;
23567+ sg_set_buf(&sg, p, GR_SALT_LEN);
23568+ crypto_hash_update(&desc, &sg, sg.length);
23569+
23570+ p = entry->pw;
23571+ sg_set_buf(&sg, p, strlen(p));
23572+
23573+ crypto_hash_update(&desc, &sg, sg.length);
23574+
23575+ crypto_hash_final(&desc, temp_sum);
23576+
23577+ memset(entry->pw, 0, GR_PW_LEN);
23578+
23579+ for (i = 0; i < GR_SHA_LEN; i++)
23580+ if (sum[i] != temp_sum[i])
23581+ retval = 1;
23582+ else
23583+ dummy = 1; // waste a cycle
23584+
23585+ crypto_free_hash(tfm);
23586+
23587+ return retval;
23588+}
23589diff -urNp linux-2.6.22.1/grsecurity/Kconfig linux-2.6.22.1/grsecurity/Kconfig
23590--- linux-2.6.22.1/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
23591+++ linux-2.6.22.1/grsecurity/Kconfig 2007-08-02 11:09:16.000000000 -0400
23592@@ -0,0 +1,873 @@
23593+#
23594+# grecurity configuration
23595+#
23596+
23597+menu "Grsecurity"
23598+
23599+config GRKERNSEC
23600+ bool "Grsecurity"
23601+ select CRYPTO
23602+ select CRYPTO_SHA256
23603+ help
23604+ If you say Y here, you will be able to configure many features
23605+ that will enhance the security of your system. It is highly
23606+ recommended that you say Y here and read through the help
23607+ for each option so that you fully understand the features and
23608+ can evaluate their usefulness for your machine.
23609+
23610+choice
23611+ prompt "Security Level"
23612+ depends GRKERNSEC
23613+ default GRKERNSEC_CUSTOM
23614+
23615+config GRKERNSEC_LOW
23616+ bool "Low"
23617+ select GRKERNSEC_LINK
23618+ select GRKERNSEC_FIFO
23619+ select GRKERNSEC_EXECVE
23620+ select GRKERNSEC_RANDNET
23621+ select GRKERNSEC_DMESG
23622+ select GRKERNSEC_CHROOT_CHDIR
23623+ select GRKERNSEC_MODSTOP if (MODULES)
23624+
23625+ help
23626+ If you choose this option, several of the grsecurity options will
23627+ be enabled that will give you greater protection against a number
23628+ of attacks, while assuring that none of your software will have any
23629+ conflicts with the additional security measures. If you run a lot
23630+ of unusual software, or you are having problems with the higher
23631+ security levels, you should say Y here. With this option, the
23632+ following features are enabled:
23633+
23634+ - Linking restrictions
23635+ - FIFO restrictions
23636+ - Enforcing RLIMIT_NPROC on execve
23637+ - Restricted dmesg
23638+ - Enforced chdir("/") on chroot
23639+ - Runtime module disabling
23640+
23641+config GRKERNSEC_MEDIUM
23642+ bool "Medium"
23643+ select PAX
23644+ select PAX_EI_PAX
23645+ select PAX_PT_PAX_FLAGS
23646+ select PAX_HAVE_ACL_FLAGS
23647+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
23648+ select GRKERNSEC_CHROOT_SYSCTL
23649+ select GRKERNSEC_LINK
23650+ select GRKERNSEC_FIFO
23651+ select GRKERNSEC_EXECVE
23652+ select GRKERNSEC_DMESG
23653+ select GRKERNSEC_RANDNET
23654+ select GRKERNSEC_FORKFAIL
23655+ select GRKERNSEC_TIME
23656+ select GRKERNSEC_SIGNAL
23657+ select GRKERNSEC_CHROOT
23658+ select GRKERNSEC_CHROOT_UNIX
23659+ select GRKERNSEC_CHROOT_MOUNT
23660+ select GRKERNSEC_CHROOT_PIVOT
23661+ select GRKERNSEC_CHROOT_DOUBLE
23662+ select GRKERNSEC_CHROOT_CHDIR
23663+ select GRKERNSEC_CHROOT_MKNOD
23664+ select GRKERNSEC_PROC
23665+ select GRKERNSEC_PROC_USERGROUP
23666+ select GRKERNSEC_MODSTOP if (MODULES)
23667+ select PAX_RANDUSTACK
23668+ select PAX_ASLR
23669+ select PAX_RANDMMAP
23670+
23671+ help
23672+ If you say Y here, several features in addition to those included
23673+ in the low additional security level will be enabled. These
23674+ features provide even more security to your system, though in rare
23675+ cases they may be incompatible with very old or poorly written
23676+ software. If you enable this option, make sure that your auth
23677+ service (identd) is running as gid 1001. With this option,
23678+ the following features (in addition to those provided in the
23679+ low additional security level) will be enabled:
23680+
23681+ - Randomized TCP source ports
23682+ - Failed fork logging
23683+ - Time change logging
23684+ - Signal logging
23685+ - Deny mounts in chroot
23686+ - Deny double chrooting
23687+ - Deny sysctl writes in chroot
23688+ - Deny mknod in chroot
23689+ - Deny access to abstract AF_UNIX sockets out of chroot
23690+ - Deny pivot_root in chroot
23691+ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
23692+ - /proc restrictions with special GID set to 10 (usually wheel)
23693+ - Address Space Layout Randomization (ASLR)
23694+
23695+config GRKERNSEC_HIGH
23696+ bool "High"
23697+ select GRKERNSEC_LINK
23698+ select GRKERNSEC_FIFO
23699+ select GRKERNSEC_EXECVE
23700+ select GRKERNSEC_DMESG
23701+ select GRKERNSEC_FORKFAIL
23702+ select GRKERNSEC_TIME
23703+ select GRKERNSEC_SIGNAL
23704+ select GRKERNSEC_CHROOT_SHMAT
23705+ select GRKERNSEC_CHROOT_UNIX
23706+ select GRKERNSEC_CHROOT_MOUNT
23707+ select GRKERNSEC_CHROOT_FCHDIR
23708+ select GRKERNSEC_CHROOT_PIVOT
23709+ select GRKERNSEC_CHROOT_DOUBLE
23710+ select GRKERNSEC_CHROOT_CHDIR
23711+ select GRKERNSEC_CHROOT_MKNOD
23712+ select GRKERNSEC_CHROOT_CAPS
23713+ select GRKERNSEC_CHROOT_SYSCTL
23714+ select GRKERNSEC_CHROOT_FINDTASK
23715+ select GRKERNSEC_PROC
23716+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
23717+ select GRKERNSEC_HIDESYM
23718+ select GRKERNSEC_BRUTE
23719+ select GRKERNSEC_SHM if (SYSVIPC)
23720+ select GRKERNSEC_PROC_USERGROUP
23721+ select GRKERNSEC_KMEM
23722+ select GRKERNSEC_RESLOG
23723+ select GRKERNSEC_RANDNET
23724+ select GRKERNSEC_PROC_ADD
23725+ select GRKERNSEC_CHROOT_CHMOD
23726+ select GRKERNSEC_CHROOT_NICE
23727+ select GRKERNSEC_AUDIT_MOUNT
23728+ select GRKERNSEC_MODSTOP if (MODULES)
23729+ select PAX
23730+ select PAX_RANDUSTACK
23731+ select PAX_ASLR
23732+ select PAX_RANDMMAP
23733+ select PAX_NOEXEC
23734+ select PAX_MPROTECT
23735+ select PAX_EI_PAX
23736+ select PAX_PT_PAX_FLAGS
23737+ select PAX_HAVE_ACL_FLAGS
23738+ select PAX_KERNEXEC if (!X86_64 && !EFI && !COMPAT_VDSO && !PARAVIRT && X86_WP_WORKS_OK)
23739+ select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
23740+ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
23741+ select PAX_SEGMEXEC if (X86 && !X86_64)
23742+ select PAX_PAGEEXEC if (!X86)
23743+ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
23744+ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
23745+ select PAX_SYSCALL if (PPC32)
23746+ select PAX_EMUTRAMP if (PARISC)
23747+ select PAX_EMUSIGRT if (PARISC)
23748+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
23749+ help
23750+ If you say Y here, many of the features of grsecurity will be
23751+ enabled, which will protect you against many kinds of attacks
23752+ against your system. The heightened security comes at a cost
23753+ of an increased chance of incompatibilities with rare software
23754+ on your machine. Since this security level enables PaX, you should
23755+ view <http://pax.grsecurity.net> and read about the PaX
23756+ project. While you are there, download chpax and run it on
23757+ binaries that cause problems with PaX. Also remember that
23758+ since the /proc restrictions are enabled, you must run your
23759+ identd as gid 1001. This security level enables the following
23760+ features in addition to those listed in the low and medium
23761+ security levels:
23762+
23763+ - Additional /proc restrictions
23764+ - Chmod restrictions in chroot
23765+ - No signals, ptrace, or viewing of processes outside of chroot
23766+ - Capability restrictions in chroot
23767+ - Deny fchdir out of chroot
23768+ - Priority restrictions in chroot
23769+ - Segmentation-based implementation of PaX
23770+ - Mprotect restrictions
23771+ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
23772+ - Kernel stack randomization
23773+ - Mount/unmount/remount logging
23774+ - Kernel symbol hiding
23775+ - Destroy unused shared memory
23776+ - Prevention of memory exhaustion-based exploits
23777+config GRKERNSEC_CUSTOM
23778+ bool "Custom"
23779+ help
23780+ If you say Y here, you will be able to configure every grsecurity
23781+ option, which allows you to enable many more features that aren't
23782+ covered in the basic security levels. These additional features
23783+ include TPE, socket restrictions, and the sysctl system for
23784+ grsecurity. It is advised that you read through the help for
23785+ each option to determine its usefulness in your situation.
23786+
23787+endchoice
23788+
23789+menu "Address Space Protection"
23790+depends on GRKERNSEC
23791+
23792+config GRKERNSEC_KMEM
23793+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
23794+ help
23795+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
23796+ be written to via mmap or otherwise to modify the running kernel.
23797+ /dev/port will also not be allowed to be opened. If you have module
23798+ support disabled, enabling this will close up four ways that are
23799+ currently used to insert malicious code into the running kernel.
23800+ Even with all these features enabled, we still highly recommend that
23801+ you use the RBAC system, as it is still possible for an attacker to
23802+ modify the running kernel through privileged I/O granted by ioperm/iopl.
23803+ If you are not using XFree86, you may be able to stop this additional
23804+ case by enabling the 'Disable privileged I/O' option. Though nothing
23805+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
23806+ but only to video memory, which is the only writing we allow in this
23807+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
23808+ not be allowed to mprotect it with PROT_WRITE later.
23809+ It is highly recommended that you say Y here if you meet all the
23810+ conditions above.
23811+
23812+config GRKERNSEC_IO
23813+ bool "Disable privileged I/O"
23814+ depends on X86
23815+ select RTC
23816+ help
23817+ If you say Y here, all ioperm and iopl calls will return an error.
23818+ Ioperm and iopl can be used to modify the running kernel.
23819+ Unfortunately, some programs need this access to operate properly,
23820+ the most notable of which are XFree86 and hwclock. hwclock can be
23821+ remedied by having RTC support in the kernel, so CONFIG_RTC is
23822+ enabled if this option is enabled, to ensure that hwclock operates
23823+ correctly. XFree86 still will not operate correctly with this option
23824+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
23825+ and you still want to protect your kernel against modification,
23826+ use the RBAC system.
23827+
23828+config GRKERNSEC_PROC_MEMMAP
23829+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
23830+ depends on PAX_NOEXEC || PAX_ASLR
23831+ help
23832+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
23833+ give no information about the addresses of its mappings if
23834+ PaX features that rely on random addresses are enabled on the task.
23835+ If you use PaX it is greatly recommended that you say Y here as it
23836+ closes up a hole that makes the full ASLR useless for suid
23837+ binaries.
23838+
23839+config GRKERNSEC_BRUTE
23840+ bool "Deter exploit bruteforcing"
23841+ help
23842+ If you say Y here, attempts to bruteforce exploits against forking
23843+ daemons such as apache or sshd will be deterred. When a child of a
23844+ forking daemon is killed by PaX or crashes due to an illegal
23845+ instruction, the parent process will be delayed 30 seconds upon every
23846+ subsequent fork until the administrator is able to assess the
23847+ situation and restart the daemon. It is recommended that you also
23848+ enable signal logging in the auditing section so that logs are
23849+ generated when a process performs an illegal instruction.
23850+
23851+config GRKERNSEC_MODSTOP
23852+ bool "Runtime module disabling"
23853+ depends on MODULES
23854+ help
23855+ If you say Y here, you will be able to disable the ability to (un)load
23856+ modules at runtime. This feature is useful if you need the ability
23857+ to load kernel modules at boot time, but do not want to allow an
23858+ attacker to load a rootkit kernel module into the system, or to remove
23859+ a loaded kernel module important to system functioning. You should
23860+ enable the /dev/mem protection feature as well, since rootkits can be
23861+ inserted into the kernel via other methods than kernel modules. Since
23862+ an untrusted module could still be loaded by modifying init scripts and
23863+ rebooting the system, it is also recommended that you enable the RBAC
23864+ system. If you enable this option, a sysctl option with name
23865+ "disable_modules" will be created. Setting this option to "1" disables
23866+ module loading. After this option is set, no further writes to it are
23867+ allowed until the system is rebooted.
23868+
23869+config GRKERNSEC_HIDESYM
23870+ bool "Hide kernel symbols"
23871+ help
23872+ If you say Y here, getting information on loaded modules, and
23873+ displaying all kernel symbols through a syscall will be restricted
23874+ to users with CAP_SYS_MODULE. This option is only effective
23875+ provided the following conditions are met:
23876+ 1) The kernel using grsecurity is not precompiled by some distribution
23877+ 2) You are using the RBAC system and hiding other files such as your
23878+ kernel image and System.map
23879+ 3) You have the additional /proc restrictions enabled, which removes
23880+ /proc/kcore
23881+ If the above conditions are met, this option will aid to provide a
23882+ useful protection against local and remote kernel exploitation of
23883+ overflows and arbitrary read/write vulnerabilities.
23884+
23885+endmenu
23886+menu "Role Based Access Control Options"
23887+depends on GRKERNSEC
23888+
23889+config GRKERNSEC_ACL_HIDEKERN
23890+ bool "Hide kernel processes"
23891+ help
23892+ If you say Y here, all kernel threads will be hidden to all
23893+ processes but those whose subject has the "view hidden processes"
23894+ flag.
23895+
23896+config GRKERNSEC_ACL_MAXTRIES
23897+ int "Maximum tries before password lockout"
23898+ default 3
23899+ help
23900+ This option enforces the maximum number of times a user can attempt
23901+ to authorize themselves with the grsecurity RBAC system before being
23902+ denied the ability to attempt authorization again for a specified time.
23903+ The lower the number, the harder it will be to brute-force a password.
23904+
23905+config GRKERNSEC_ACL_TIMEOUT
23906+ int "Time to wait after max password tries, in seconds"
23907+ default 30
23908+ help
23909+ This option specifies the time the user must wait after attempting to
23910+ authorize to the RBAC system with the maximum number of invalid
23911+ passwords. The higher the number, the harder it will be to brute-force
23912+ a password.
23913+
23914+endmenu
23915+menu "Filesystem Protections"
23916+depends on GRKERNSEC
23917+
23918+config GRKERNSEC_PROC
23919+ bool "Proc restrictions"
23920+ help
23921+ If you say Y here, the permissions of the /proc filesystem
23922+ will be altered to enhance system security and privacy. You MUST
23923+ choose either a user only restriction or a user and group restriction.
23924+ Depending upon the option you choose, you can either restrict users to
23925+ see only the processes they themselves run, or choose a group that can
23926+ view all processes and files normally restricted to root if you choose
23927+ the "restrict to user only" option. NOTE: If you're running identd as
23928+ a non-root user, you will have to run it as the group you specify here.
23929+
23930+config GRKERNSEC_PROC_USER
23931+ bool "Restrict /proc to user only"
23932+ depends on GRKERNSEC_PROC
23933+ help
23934+ If you say Y here, non-root users will only be able to view their own
23935+ processes, and restricts them from viewing network-related information,
23936+ and viewing kernel symbol and module information.
23937+
23938+config GRKERNSEC_PROC_USERGROUP
23939+ bool "Allow special group"
23940+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
23941+ help
23942+ If you say Y here, you will be able to select a group that will be
23943+ able to view all processes, network-related information, and
23944+ kernel and symbol information. This option is useful if you want
23945+ to run identd as a non-root user.
23946+
23947+config GRKERNSEC_PROC_GID
23948+ int "GID for special group"
23949+ depends on GRKERNSEC_PROC_USERGROUP
23950+ default 1001
23951+
23952+config GRKERNSEC_PROC_ADD
23953+ bool "Additional restrictions"
23954+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
23955+ help
23956+ If you say Y here, additional restrictions will be placed on
23957+ /proc that keep normal users from viewing device information and
23958+ slabinfo information that could be useful for exploits.
23959+
23960+config GRKERNSEC_LINK
23961+ bool "Linking restrictions"
23962+ help
23963+ If you say Y here, /tmp race exploits will be prevented, since users
23964+ will no longer be able to follow symlinks owned by other users in
23965+ world-writable +t directories (i.e. /tmp), unless the owner of the
23966+ symlink is the owner of the directory. users will also not be
23967+ able to hardlink to files they do not own. If the sysctl option is
23968+ enabled, a sysctl option with name "linking_restrictions" is created.
23969+
23970+config GRKERNSEC_FIFO
23971+ bool "FIFO restrictions"
23972+ help
23973+ If you say Y here, users will not be able to write to FIFOs they don't
23974+ own in world-writable +t directories (i.e. /tmp), unless the owner of
23975+ the FIFO is the same owner of the directory it's held in. If the sysctl
23976+ option is enabled, a sysctl option with name "fifo_restrictions" is
23977+ created.
23978+
23979+config GRKERNSEC_CHROOT
23980+ bool "Chroot jail restrictions"
23981+ help
23982+ If you say Y here, you will be able to choose several options that will
23983+ make breaking out of a chrooted jail much more difficult. If you
23984+ encounter no software incompatibilities with the following options, it
23985+ is recommended that you enable each one.
23986+
23987+config GRKERNSEC_CHROOT_MOUNT
23988+ bool "Deny mounts"
23989+ depends on GRKERNSEC_CHROOT
23990+ help
23991+ If you say Y here, processes inside a chroot will not be able to
23992+ mount or remount filesystems. If the sysctl option is enabled, a
23993+ sysctl option with name "chroot_deny_mount" is created.
23994+
23995+config GRKERNSEC_CHROOT_DOUBLE
23996+ bool "Deny double-chroots"
23997+ depends on GRKERNSEC_CHROOT
23998+ help
23999+ If you say Y here, processes inside a chroot will not be able to chroot
24000+ again outside the chroot. This is a widely used method of breaking
24001+ out of a chroot jail and should not be allowed. If the sysctl
24002+ option is enabled, a sysctl option with name
24003+ "chroot_deny_chroot" is created.
24004+
24005+config GRKERNSEC_CHROOT_PIVOT
24006+ bool "Deny pivot_root in chroot"
24007+ depends on GRKERNSEC_CHROOT
24008+ help
24009+ If you say Y here, processes inside a chroot will not be able to use
24010+ a function called pivot_root() that was introduced in Linux 2.3.41. It
24011+ works similar to chroot in that it changes the root filesystem. This
24012+ function could be misused in a chrooted process to attempt to break out
24013+ of the chroot, and therefore should not be allowed. If the sysctl
24014+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
24015+ created.
24016+
24017+config GRKERNSEC_CHROOT_CHDIR
24018+ bool "Enforce chdir(\"/\") on all chroots"
24019+ depends on GRKERNSEC_CHROOT
24020+ help
24021+ If you say Y here, the current working directory of all newly-chrooted
24022+ applications will be set to the the root directory of the chroot.
24023+ The man page on chroot(2) states:
24024+ Note that this call does not change the current working
24025+ directory, so that `.' can be outside the tree rooted at
24026+ `/'. In particular, the super-user can escape from a
24027+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
24028+
24029+ It is recommended that you say Y here, since it's not known to break
24030+ any software. If the sysctl option is enabled, a sysctl option with
24031+ name "chroot_enforce_chdir" is created.
24032+
24033+config GRKERNSEC_CHROOT_CHMOD
24034+ bool "Deny (f)chmod +s"
24035+ depends on GRKERNSEC_CHROOT
24036+ help
24037+ If you say Y here, processes inside a chroot will not be able to chmod
24038+ or fchmod files to make them have suid or sgid bits. This protects
24039+ against another published method of breaking a chroot. If the sysctl
24040+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
24041+ created.
24042+
24043+config GRKERNSEC_CHROOT_FCHDIR
24044+ bool "Deny fchdir out of chroot"
24045+ depends on GRKERNSEC_CHROOT
24046+ help
24047+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
24048+ to a file descriptor of the chrooting process that points to a directory
24049+ outside the filesystem will be stopped. If the sysctl option
24050+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
24051+
24052+config GRKERNSEC_CHROOT_MKNOD
24053+ bool "Deny mknod"
24054+ depends on GRKERNSEC_CHROOT
24055+ help
24056+ If you say Y here, processes inside a chroot will not be allowed to
24057+ mknod. The problem with using mknod inside a chroot is that it
24058+ would allow an attacker to create a device entry that is the same
24059+ as one on the physical root of your system, which could range from
24060+ anything from the console device to a device for your harddrive (which
24061+ they could then use to wipe the drive or steal data). It is recommended
24062+ that you say Y here, unless you run into software incompatibilities.
24063+ If the sysctl option is enabled, a sysctl option with name
24064+ "chroot_deny_mknod" is created.
24065+
24066+config GRKERNSEC_CHROOT_SHMAT
24067+ bool "Deny shmat() out of chroot"
24068+ depends on GRKERNSEC_CHROOT
24069+ help
24070+ If you say Y here, processes inside a chroot will not be able to attach
24071+ to shared memory segments that were created outside of the chroot jail.
24072+ It is recommended that you say Y here. If the sysctl option is enabled,
24073+ a sysctl option with name "chroot_deny_shmat" is created.
24074+
24075+config GRKERNSEC_CHROOT_UNIX
24076+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
24077+ depends on GRKERNSEC_CHROOT
24078+ help
24079+ If you say Y here, processes inside a chroot will not be able to
24080+ connect to abstract (meaning not belonging to a filesystem) Unix
24081+ domain sockets that were bound outside of a chroot. It is recommended
24082+ that you say Y here. If the sysctl option is enabled, a sysctl option
24083+ with name "chroot_deny_unix" is created.
24084+
24085+config GRKERNSEC_CHROOT_FINDTASK
24086+ bool "Protect outside processes"
24087+ depends on GRKERNSEC_CHROOT
24088+ help
24089+ If you say Y here, processes inside a chroot will not be able to
24090+ kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
24091+ or view any process outside of the chroot. If the sysctl
24092+ option is enabled, a sysctl option with name "chroot_findtask" is
24093+ created.
24094+
24095+config GRKERNSEC_CHROOT_NICE
24096+ bool "Restrict priority changes"
24097+ depends on GRKERNSEC_CHROOT
24098+ help
24099+ If you say Y here, processes inside a chroot will not be able to raise
24100+ the priority of processes in the chroot, or alter the priority of
24101+ processes outside the chroot. This provides more security than simply
24102+ removing CAP_SYS_NICE from the process' capability set. If the
24103+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
24104+ is created.
24105+
24106+config GRKERNSEC_CHROOT_SYSCTL
24107+ bool "Deny sysctl writes"
24108+ depends on GRKERNSEC_CHROOT
24109+ help
24110+ If you say Y here, an attacker in a chroot will not be able to
24111+ write to sysctl entries, either by sysctl(2) or through a /proc
24112+ interface. It is strongly recommended that you say Y here. If the
24113+ sysctl option is enabled, a sysctl option with name
24114+ "chroot_deny_sysctl" is created.
24115+
24116+config GRKERNSEC_CHROOT_CAPS
24117+ bool "Capability restrictions"
24118+ depends on GRKERNSEC_CHROOT
24119+ help
24120+ If you say Y here, the capabilities on all root processes within a
24121+ chroot jail will be lowered to stop module insertion, raw i/o,
24122+ system and net admin tasks, rebooting the system, modifying immutable
24123+ files, modifying IPC owned by another, and changing the system time.
24124+ This is left an option because it can break some apps. Disable this
24125+ if your chrooted apps are having problems performing those kinds of
24126+ tasks. If the sysctl option is enabled, a sysctl option with
24127+ name "chroot_caps" is created.
24128+
24129+endmenu
24130+menu "Kernel Auditing"
24131+depends on GRKERNSEC
24132+
24133+config GRKERNSEC_AUDIT_GROUP
24134+ bool "Single group for auditing"
24135+ help
24136+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
24137+ will only operate on a group you specify. This option is recommended
24138+ if you only want to watch certain users instead of having a large
24139+ amount of logs from the entire system. If the sysctl option is enabled,
24140+ a sysctl option with name "audit_group" is created.
24141+
24142+config GRKERNSEC_AUDIT_GID
24143+ int "GID for auditing"
24144+ depends on GRKERNSEC_AUDIT_GROUP
24145+ default 1007
24146+
24147+config GRKERNSEC_EXECLOG
24148+ bool "Exec logging"
24149+ help
24150+ If you say Y here, all execve() calls will be logged (since the
24151+ other exec*() calls are frontends to execve(), all execution
24152+ will be logged). Useful for shell-servers that like to keep track
24153+ of their users. If the sysctl option is enabled, a sysctl option with
24154+ name "exec_logging" is created.
24155+ WARNING: This option when enabled will produce a LOT of logs, especially
24156+ on an active system.
24157+
24158+config GRKERNSEC_RESLOG
24159+ bool "Resource logging"
24160+ help
24161+ If you say Y here, all attempts to overstep resource limits will
24162+ be logged with the resource name, the requested size, and the current
24163+ limit. It is highly recommended that you say Y here. If the sysctl
24164+ option is enabled, a sysctl option with name "resource_logging" is
24165+ created. If the RBAC system is enabled, the sysctl value is ignored.
24166+
24167+config GRKERNSEC_CHROOT_EXECLOG
24168+ bool "Log execs within chroot"
24169+ help
24170+ If you say Y here, all executions inside a chroot jail will be logged
24171+ to syslog. This can cause a large amount of logs if certain
24172+ applications (eg. djb's daemontools) are installed on the system, and
24173+ is therefore left as an option. If the sysctl option is enabled, a
24174+ sysctl option with name "chroot_execlog" is created.
24175+
24176+config GRKERNSEC_AUDIT_CHDIR
24177+ bool "Chdir logging"
24178+ help
24179+ If you say Y here, all chdir() calls will be logged. If the sysctl
24180+ option is enabled, a sysctl option with name "audit_chdir" is created.
24181+
24182+config GRKERNSEC_AUDIT_MOUNT
24183+ bool "(Un)Mount logging"
24184+ help
24185+ If you say Y here, all mounts and unmounts will be logged. If the
24186+ sysctl option is enabled, a sysctl option with name "audit_mount" is
24187+ created.
24188+
24189+config GRKERNSEC_AUDIT_IPC
24190+ bool "IPC logging"
24191+ help
24192+ If you say Y here, creation and removal of message queues, semaphores,
24193+ and shared memory will be logged. If the sysctl option is enabled, a
24194+ sysctl option with name "audit_ipc" is created.
24195+
24196+config GRKERNSEC_SIGNAL
24197+ bool "Signal logging"
24198+ help
24199+ If you say Y here, certain important signals will be logged, such as
24200+ SIGSEGV, which will as a result inform you of when a error in a program
24201+ occurred, which in some cases could mean a possible exploit attempt.
24202+ If the sysctl option is enabled, a sysctl option with name
24203+ "signal_logging" is created.
24204+
24205+config GRKERNSEC_FORKFAIL
24206+ bool "Fork failure logging"
24207+ help
24208+ If you say Y here, all failed fork() attempts will be logged.
24209+ This could suggest a fork bomb, or someone attempting to overstep
24210+ their process limit. If the sysctl option is enabled, a sysctl option
24211+ with name "forkfail_logging" is created.
24212+
24213+config GRKERNSEC_TIME
24214+ bool "Time change logging"
24215+ help
24216+ If you say Y here, any changes of the system clock will be logged.
24217+ If the sysctl option is enabled, a sysctl option with name
24218+ "timechange_logging" is created.
24219+
24220+config GRKERNSEC_PROC_IPADDR
24221+ bool "/proc/<pid>/ipaddr support"
24222+ help
24223+ If you say Y here, a new entry will be added to each /proc/<pid>
24224+ directory that contains the IP address of the person using the task.
24225+ The IP is carried across local TCP and AF_UNIX stream sockets.
24226+ This information can be useful for IDS/IPSes to perform remote response
24227+ to a local attack. The entry is readable by only the owner of the
24228+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
24229+ the RBAC system), and thus does not create privacy concerns.
24230+
24231+config GRKERNSEC_AUDIT_TEXTREL
24232+ bool 'ELF text relocations logging (READ HELP)'
24233+ depends on PAX_MPROTECT
24234+ help
24235+ If you say Y here, text relocations will be logged with the filename
24236+ of the offending library or binary. The purpose of the feature is
24237+ to help Linux distribution developers get rid of libraries and
24238+ binaries that need text relocations which hinder the future progress
24239+ of PaX. Only Linux distribution developers should say Y here, and
24240+ never on a production machine, as this option creates an information
24241+ leak that could aid an attacker in defeating the randomization of
24242+ a single memory region. If the sysctl option is enabled, a sysctl
24243+ option with name "audit_textrel" is created.
24244+
24245+endmenu
24246+
24247+menu "Executable Protections"
24248+depends on GRKERNSEC
24249+
24250+config GRKERNSEC_EXECVE
24251+ bool "Enforce RLIMIT_NPROC on execs"
24252+ help
24253+ If you say Y here, users with a resource limit on processes will
24254+ have the value checked during execve() calls. The current system
24255+ only checks the system limit during fork() calls. If the sysctl option
24256+ is enabled, a sysctl option with name "execve_limiting" is created.
24257+
24258+config GRKERNSEC_SHM
24259+ bool "Destroy unused shared memory"
24260+ depends on SYSVIPC
24261+ help
24262+ If you say Y here, shared memory will be destroyed when no one is
24263+ attached to it. Otherwise, resources involved with the shared
24264+ memory can be used up and not be associated with any process (as the
24265+ shared memory still exists, and the creating process has exited). If
24266+ the sysctl option is enabled, a sysctl option with name
24267+ "destroy_unused_shm" is created.
24268+
24269+config GRKERNSEC_DMESG
24270+ bool "Dmesg(8) restriction"
24271+ help
24272+ If you say Y here, non-root users will not be able to use dmesg(8)
24273+ to view up to the last 4kb of messages in the kernel's log buffer.
24274+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
24275+ created.
24276+
24277+config GRKERNSEC_TPE
24278+ bool "Trusted Path Execution (TPE)"
24279+ help
24280+ If you say Y here, you will be able to choose a gid to add to the
24281+ supplementary groups of users you want to mark as "untrusted."
24282+ These users will not be able to execute any files that are not in
24283+ root-owned directories writable only by root. If the sysctl option
24284+ is enabled, a sysctl option with name "tpe" is created.
24285+
24286+config GRKERNSEC_TPE_ALL
24287+ bool "Partially restrict non-root users"
24288+ depends on GRKERNSEC_TPE
24289+ help
24290+ If you say Y here, All non-root users other than the ones in the
24291+ group specified in the main TPE option will only be allowed to
24292+ execute files in directories they own that are not group or
24293+ world-writable, or in directories owned by root and writable only by
24294+ root. If the sysctl option is enabled, a sysctl option with name
24295+ "tpe_restrict_all" is created.
24296+
24297+config GRKERNSEC_TPE_INVERT
24298+ bool "Invert GID option"
24299+ depends on GRKERNSEC_TPE
24300+ help
24301+ If you say Y here, the group you specify in the TPE configuration will
24302+ decide what group TPE restrictions will be *disabled* for. This
24303+ option is useful if you want TPE restrictions to be applied to most
24304+ users on the system.
24305+
24306+config GRKERNSEC_TPE_GID
24307+ int "GID for untrusted users"
24308+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
24309+ default 1005
24310+ help
24311+ If you have selected the "Invert GID option" above, setting this
24312+ GID determines what group TPE restrictions will be *disabled* for.
24313+ If you have not selected the "Invert GID option" above, setting this
24314+ GID determines what group TPE restrictions will be *enabled* for.
24315+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
24316+ is created.
24317+
24318+config GRKERNSEC_TPE_GID
24319+ int "GID for trusted users"
24320+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
24321+ default 1005
24322+ help
24323+ If you have selected the "Invert GID option" above, setting this
24324+ GID determines what group TPE restrictions will be *disabled* for.
24325+ If you have not selected the "Invert GID option" above, setting this
24326+ GID determines what group TPE restrictions will be *enabled* for.
24327+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
24328+ is created.
24329+
24330+endmenu
24331+menu "Network Protections"
24332+depends on GRKERNSEC
24333+
24334+config GRKERNSEC_RANDNET
24335+ bool "Larger entropy pools"
24336+ help
24337+ If you say Y here, the entropy pools used for many features of Linux
24338+ and grsecurity will be doubled in size. Since several grsecurity
24339+ features use additional randomness, it is recommended that you say Y
24340+ here. Saying Y here has a similar effect as modifying
24341+ /proc/sys/kernel/random/poolsize.
24342+
24343+config GRKERNSEC_SOCKET
24344+ bool "Socket restrictions"
24345+ help
24346+ If you say Y here, you will be able to choose from several options.
24347+ If you assign a GID on your system and add it to the supplementary
24348+ groups of users you want to restrict socket access to, this patch
24349+ will perform up to three things, based on the option(s) you choose.
24350+
24351+config GRKERNSEC_SOCKET_ALL
24352+ bool "Deny any sockets to group"
24353+ depends on GRKERNSEC_SOCKET
24354+ help
24355+ If you say Y here, you will be able to choose a GID of whose users will
24356+ be unable to connect to other hosts from your machine or run server
24357+ applications from your machine. If the sysctl option is enabled, a
24358+ sysctl option with name "socket_all" is created.
24359+
24360+config GRKERNSEC_SOCKET_ALL_GID
24361+ int "GID to deny all sockets for"
24362+ depends on GRKERNSEC_SOCKET_ALL
24363+ default 1004
24364+ help
24365+ Here you can choose the GID to disable socket access for. Remember to
24366+ add the users you want socket access disabled for to the GID
24367+ specified here. If the sysctl option is enabled, a sysctl option
24368+ with name "socket_all_gid" is created.
24369+
24370+config GRKERNSEC_SOCKET_CLIENT
24371+ bool "Deny client sockets to group"
24372+ depends on GRKERNSEC_SOCKET
24373+ help
24374+ If you say Y here, you will be able to choose a GID of whose users will
24375+ be unable to connect to other hosts from your machine, but will be
24376+ able to run servers. If this option is enabled, all users in the group
24377+ you specify will have to use passive mode when initiating ftp transfers
24378+ from the shell on your machine. If the sysctl option is enabled, a
24379+ sysctl option with name "socket_client" is created.
24380+
24381+config GRKERNSEC_SOCKET_CLIENT_GID
24382+ int "GID to deny client sockets for"
24383+ depends on GRKERNSEC_SOCKET_CLIENT
24384+ default 1003
24385+ help
24386+ Here you can choose the GID to disable client socket access for.
24387+ Remember to add the users you want client socket access disabled for to
24388+ the GID specified here. If the sysctl option is enabled, a sysctl
24389+ option with name "socket_client_gid" is created.
24390+
24391+config GRKERNSEC_SOCKET_SERVER
24392+ bool "Deny server sockets to group"
24393+ depends on GRKERNSEC_SOCKET
24394+ help
24395+ If you say Y here, you will be able to choose a GID of whose users will
24396+ be unable to run server applications from your machine. If the sysctl
24397+ option is enabled, a sysctl option with name "socket_server" is created.
24398+
24399+config GRKERNSEC_SOCKET_SERVER_GID
24400+ int "GID to deny server sockets for"
24401+ depends on GRKERNSEC_SOCKET_SERVER
24402+ default 1002
24403+ help
24404+ Here you can choose the GID to disable server socket access for.
24405+ Remember to add the users you want server socket access disabled for to
24406+ the GID specified here. If the sysctl option is enabled, a sysctl
24407+ option with name "socket_server_gid" is created.
24408+
24409+endmenu
24410+menu "Sysctl support"
24411+depends on GRKERNSEC && SYSCTL
24412+
24413+config GRKERNSEC_SYSCTL
24414+ bool "Sysctl support"
24415+ help
24416+ If you say Y here, you will be able to change the options that
24417+ grsecurity runs with at bootup, without having to recompile your
24418+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
24419+ to enable (1) or disable (0) various features. All the sysctl entries
24420+ are mutable until the "grsec_lock" entry is set to a non-zero value.
24421+ All features enabled in the kernel configuration are disabled at boot
24422+ if you do not say Y to the "Turn on features by default" option.
24423+ All options should be set at startup, and the grsec_lock entry should
24424+ be set to a non-zero value after all the options are set.
24425+ *THIS IS EXTREMELY IMPORTANT*
24426+
24427+config GRKERNSEC_SYSCTL_ON
24428+ bool "Turn on features by default"
24429+ depends on GRKERNSEC_SYSCTL
24430+ help
24431+ If you say Y here, instead of having all features enabled in the
24432+ kernel configuration disabled at boot time, the features will be
24433+ enabled at boot time. It is recommended you say Y here unless
24434+ there is some reason you would want all sysctl-tunable features to
24435+ be disabled by default. As mentioned elsewhere, it is important
24436+ to enable the grsec_lock entry once you have finished modifying
24437+ the sysctl entries.
24438+
24439+endmenu
24440+menu "Logging Options"
24441+depends on GRKERNSEC
24442+
24443+config GRKERNSEC_FLOODTIME
24444+ int "Seconds in between log messages (minimum)"
24445+ default 10
24446+ help
24447+ This option allows you to enforce the number of seconds between
24448+ grsecurity log messages. The default should be suitable for most
24449+ people, however, if you choose to change it, choose a value small enough
24450+ to allow informative logs to be produced, but large enough to
24451+ prevent flooding.
24452+
24453+config GRKERNSEC_FLOODBURST
24454+ int "Number of messages in a burst (maximum)"
24455+ default 4
24456+ help
24457+ This option allows you to choose the maximum number of messages allowed
24458+ within the flood time interval you chose in a separate option. The
24459+ default should be suitable for most people, however if you find that
24460+ many of your logs are being interpreted as flooding, you may want to
24461+ raise this value.
24462+
24463+endmenu
24464+
24465+endmenu
24466diff -urNp linux-2.6.22.1/grsecurity/Makefile linux-2.6.22.1/grsecurity/Makefile
24467--- linux-2.6.22.1/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
24468+++ linux-2.6.22.1/grsecurity/Makefile 2007-08-02 11:09:16.000000000 -0400
24469@@ -0,0 +1,20 @@
24470+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
24471+# during 2001-2005 it has been completely redesigned by Brad Spengler
24472+# into an RBAC system
24473+#
24474+# All code in this directory and various hooks inserted throughout the kernel
24475+# are copyright Brad Spengler, and released under the GPL v2 or higher
24476+
24477+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
24478+ grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
24479+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
24480+
24481+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
24482+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
24483+ gracl_learn.o grsec_log.o
24484+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
24485+
24486+ifndef CONFIG_GRKERNSEC
24487+obj-y += grsec_disabled.o
24488+endif
24489+
24490diff -urNp linux-2.6.22.1/include/acpi/acmacros.h linux-2.6.22.1/include/acpi/acmacros.h
24491--- linux-2.6.22.1/include/acpi/acmacros.h 2007-07-10 14:56:30.000000000 -0400
24492+++ linux-2.6.22.1/include/acpi/acmacros.h 2007-08-02 11:38:47.000000000 -0400
24493@@ -617,7 +617,7 @@
24494 #define ACPI_DUMP_PATHNAME(a,b,c,d)
24495 #define ACPI_DUMP_RESOURCE_LIST(a)
24496 #define ACPI_DUMP_BUFFER(a,b)
24497-#define ACPI_DEBUG_PRINT(pl)
24498+#define ACPI_DEBUG_PRINT(pl) do {} while (0)
24499 #define ACPI_DEBUG_PRINT_RAW(pl)
24500
24501 #define return_VOID return
24502diff -urNp linux-2.6.22.1/include/asm-alpha/a.out.h linux-2.6.22.1/include/asm-alpha/a.out.h
24503--- linux-2.6.22.1/include/asm-alpha/a.out.h 2007-07-10 14:56:30.000000000 -0400
24504+++ linux-2.6.22.1/include/asm-alpha/a.out.h 2007-08-02 11:38:47.000000000 -0400
24505@@ -98,7 +98,7 @@ struct exec
24506 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
24507 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
24508
24509-#define STACK_TOP \
24510+#define __STACK_TOP \
24511 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
24512
24513 #endif
24514diff -urNp linux-2.6.22.1/include/asm-alpha/elf.h linux-2.6.22.1/include/asm-alpha/elf.h
24515--- linux-2.6.22.1/include/asm-alpha/elf.h 2007-07-10 14:56:30.000000000 -0400
24516+++ linux-2.6.22.1/include/asm-alpha/elf.h 2007-08-02 11:38:47.000000000 -0400
24517@@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
24518
24519 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
24520
24521+#ifdef CONFIG_PAX_ASLR
24522+#define PAX_ELF_ET_DYN_BASE (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
24523+
24524+#define PAX_DELTA_MMAP_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
24525+#define PAX_DELTA_STACK_LEN (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
24526+#endif
24527+
24528 /* $0 is set by ld.so to a pointer to a function which might be
24529 registered using atexit. This provides a mean for the dynamic
24530 linker to call DT_FINI functions for shared libraries that have
24531diff -urNp linux-2.6.22.1/include/asm-alpha/kmap_types.h linux-2.6.22.1/include/asm-alpha/kmap_types.h
24532--- linux-2.6.22.1/include/asm-alpha/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24533+++ linux-2.6.22.1/include/asm-alpha/kmap_types.h 2007-08-02 11:38:47.000000000 -0400
24534@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
24535 D(10) KM_IRQ1,
24536 D(11) KM_SOFTIRQ0,
24537 D(12) KM_SOFTIRQ1,
24538-D(13) KM_TYPE_NR
24539+D(13) KM_CLEARPAGE,
24540+D(14) KM_TYPE_NR
24541 };
24542
24543 #undef D
24544diff -urNp linux-2.6.22.1/include/asm-alpha/pgtable.h linux-2.6.22.1/include/asm-alpha/pgtable.h
24545--- linux-2.6.22.1/include/asm-alpha/pgtable.h 2007-07-10 14:56:30.000000000 -0400
24546+++ linux-2.6.22.1/include/asm-alpha/pgtable.h 2007-08-02 11:38:47.000000000 -0400
24547@@ -101,6 +101,17 @@ struct vm_area_struct;
24548 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
24549 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
24550 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
24551+
24552+#ifdef CONFIG_PAX_PAGEEXEC
24553+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
24554+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
24555+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
24556+#else
24557+# define PAGE_SHARED_NOEXEC PAGE_SHARED
24558+# define PAGE_COPY_NOEXEC PAGE_COPY
24559+# define PAGE_READONLY_NOEXEC PAGE_READONLY
24560+#endif
24561+
24562 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
24563
24564 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
24565diff -urNp linux-2.6.22.1/include/asm-arm/a.out.h linux-2.6.22.1/include/asm-arm/a.out.h
24566--- linux-2.6.22.1/include/asm-arm/a.out.h 2007-07-10 14:56:30.000000000 -0400
24567+++ linux-2.6.22.1/include/asm-arm/a.out.h 2007-08-02 11:38:47.000000000 -0400
24568@@ -28,7 +28,7 @@ struct exec
24569 #define M_ARM 103
24570
24571 #ifdef __KERNEL__
24572-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
24573+#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
24574 TASK_SIZE : TASK_SIZE_26)
24575 #endif
24576
24577diff -urNp linux-2.6.22.1/include/asm-arm/elf.h linux-2.6.22.1/include/asm-arm/elf.h
24578--- linux-2.6.22.1/include/asm-arm/elf.h 2007-07-10 14:56:30.000000000 -0400
24579+++ linux-2.6.22.1/include/asm-arm/elf.h 2007-08-02 11:38:48.000000000 -0400
24580@@ -110,6 +110,13 @@ extern char elf_platform[];
24581
24582 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
24583
24584+#ifdef CONFIG_PAX_ASLR
24585+#define PAX_ELF_ET_DYN_BASE 0x00008000UL
24586+
24587+#define PAX_DELTA_MMAP_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
24588+#define PAX_DELTA_STACK_LEN ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
24589+#endif
24590+
24591 /* When the program starts, a1 contains a pointer to a function to be
24592 registered with atexit, as per the SVR4 ABI. A value of 0 means we
24593 have no such handler. */
24594diff -urNp linux-2.6.22.1/include/asm-arm/kmap_types.h linux-2.6.22.1/include/asm-arm/kmap_types.h
24595--- linux-2.6.22.1/include/asm-arm/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24596+++ linux-2.6.22.1/include/asm-arm/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24597@@ -18,6 +18,7 @@ enum km_type {
24598 KM_IRQ1,
24599 KM_SOFTIRQ0,
24600 KM_SOFTIRQ1,
24601+ KM_CLEARPAGE,
24602 KM_TYPE_NR
24603 };
24604
24605diff -urNp linux-2.6.22.1/include/asm-arm26/kmap_types.h linux-2.6.22.1/include/asm-arm26/kmap_types.h
24606--- linux-2.6.22.1/include/asm-arm26/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24607+++ linux-2.6.22.1/include/asm-arm26/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24608@@ -6,7 +6,8 @@
24609 */
24610 enum km_type {
24611 KM_IRQ0,
24612- KM_USER1
24613+ KM_USER1,
24614+ KM_CLEARPAGE
24615 };
24616
24617 #endif
24618diff -urNp linux-2.6.22.1/include/asm-avr32/a.out.h linux-2.6.22.1/include/asm-avr32/a.out.h
24619--- linux-2.6.22.1/include/asm-avr32/a.out.h 2007-07-10 14:56:30.000000000 -0400
24620+++ linux-2.6.22.1/include/asm-avr32/a.out.h 2007-08-02 11:38:48.000000000 -0400
24621@@ -19,7 +19,7 @@ struct exec
24622
24623 #ifdef __KERNEL__
24624
24625-#define STACK_TOP TASK_SIZE
24626+#define __STACK_TOP TASK_SIZE
24627
24628 #endif
24629
24630diff -urNp linux-2.6.22.1/include/asm-avr32/elf.h linux-2.6.22.1/include/asm-avr32/elf.h
24631--- linux-2.6.22.1/include/asm-avr32/elf.h 2007-07-10 14:56:30.000000000 -0400
24632+++ linux-2.6.22.1/include/asm-avr32/elf.h 2007-08-02 11:38:48.000000000 -0400
24633@@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
24634 the loader. We need to make sure that it is out of the way of the program
24635 that it will "exec", and that there is sufficient room for the brk. */
24636
24637-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
24638+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
24639
24640+#ifdef CONFIG_PAX_ASLR
24641+#define PAX_ELF_ET_DYN_BASE 0x00001000UL
24642+
24643+#define PAX_DELTA_MMAP_LEN 15
24644+#define PAX_DELTA_STACK_LEN 15
24645+#endif
24646
24647 /* This yields a mask that user programs can use to figure out what
24648 instruction set this CPU supports. This could be done in user space,
24649diff -urNp linux-2.6.22.1/include/asm-avr32/kmap_types.h linux-2.6.22.1/include/asm-avr32/kmap_types.h
24650--- linux-2.6.22.1/include/asm-avr32/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24651+++ linux-2.6.22.1/include/asm-avr32/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24652@@ -22,7 +22,8 @@ D(10) KM_IRQ0,
24653 D(11) KM_IRQ1,
24654 D(12) KM_SOFTIRQ0,
24655 D(13) KM_SOFTIRQ1,
24656-D(14) KM_TYPE_NR
24657+D(14) KM_CLEARPAGE,
24658+D(15) KM_TYPE_NR
24659 };
24660
24661 #undef D
24662diff -urNp linux-2.6.22.1/include/asm-blackfin/kmap_types.h linux-2.6.22.1/include/asm-blackfin/kmap_types.h
24663--- linux-2.6.22.1/include/asm-blackfin/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24664+++ linux-2.6.22.1/include/asm-blackfin/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24665@@ -15,6 +15,7 @@ enum km_type {
24666 KM_IRQ1,
24667 KM_SOFTIRQ0,
24668 KM_SOFTIRQ1,
24669+ KM_CLEARPAGE,
24670 KM_TYPE_NR
24671 };
24672
24673diff -urNp linux-2.6.22.1/include/asm-cris/kmap_types.h linux-2.6.22.1/include/asm-cris/kmap_types.h
24674--- linux-2.6.22.1/include/asm-cris/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24675+++ linux-2.6.22.1/include/asm-cris/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24676@@ -19,6 +19,7 @@ enum km_type {
24677 KM_IRQ1,
24678 KM_SOFTIRQ0,
24679 KM_SOFTIRQ1,
24680+ KM_CLEARPAGE,
24681 KM_TYPE_NR
24682 };
24683
24684diff -urNp linux-2.6.22.1/include/asm-frv/kmap_types.h linux-2.6.22.1/include/asm-frv/kmap_types.h
24685--- linux-2.6.22.1/include/asm-frv/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24686+++ linux-2.6.22.1/include/asm-frv/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24687@@ -23,6 +23,7 @@ enum km_type {
24688 KM_IRQ1,
24689 KM_SOFTIRQ0,
24690 KM_SOFTIRQ1,
24691+ KM_CLEARPAGE,
24692 KM_TYPE_NR
24693 };
24694
24695diff -urNp linux-2.6.22.1/include/asm-generic/futex.h linux-2.6.22.1/include/asm-generic/futex.h
24696--- linux-2.6.22.1/include/asm-generic/futex.h 2007-07-10 14:56:30.000000000 -0400
24697+++ linux-2.6.22.1/include/asm-generic/futex.h 2007-08-02 11:38:48.000000000 -0400
24698@@ -8,7 +8,7 @@
24699 #include <asm/uaccess.h>
24700
24701 static inline int
24702-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
24703+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
24704 {
24705 int op = (encoded_op >> 28) & 7;
24706 int cmp = (encoded_op >> 24) & 15;
24707@@ -50,7 +50,7 @@ futex_atomic_op_inuser (int encoded_op,
24708 }
24709
24710 static inline int
24711-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
24712+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
24713 {
24714 return -ENOSYS;
24715 }
24716diff -urNp linux-2.6.22.1/include/asm-generic/vmlinux.lds.h linux-2.6.22.1/include/asm-generic/vmlinux.lds.h
24717--- linux-2.6.22.1/include/asm-generic/vmlinux.lds.h 2007-07-10 14:56:30.000000000 -0400
24718+++ linux-2.6.22.1/include/asm-generic/vmlinux.lds.h 2007-08-02 11:38:48.000000000 -0400
24719@@ -19,6 +19,7 @@
24720 .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
24721 VMLINUX_SYMBOL(__start_rodata) = .; \
24722 *(.rodata) *(.rodata.*) \
24723+ *(.data.read_only) \
24724 *(__vermagic) /* Kernel version magic */ \
24725 } \
24726 \
24727diff -urNp linux-2.6.22.1/include/asm-h8300/kmap_types.h linux-2.6.22.1/include/asm-h8300/kmap_types.h
24728--- linux-2.6.22.1/include/asm-h8300/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
24729+++ linux-2.6.22.1/include/asm-h8300/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
24730@@ -15,6 +15,7 @@ enum km_type {
24731 KM_IRQ1,
24732 KM_SOFTIRQ0,
24733 KM_SOFTIRQ1,
24734+ KM_CLEARPAGE,
24735 KM_TYPE_NR
24736 };
24737
24738diff -urNp linux-2.6.22.1/include/asm-i386/alternative.h linux-2.6.22.1/include/asm-i386/alternative.h
24739--- linux-2.6.22.1/include/asm-i386/alternative.h 2007-07-10 14:56:30.000000000 -0400
24740+++ linux-2.6.22.1/include/asm-i386/alternative.h 2007-08-02 11:38:48.000000000 -0400
24741@@ -54,7 +54,7 @@ static inline void alternatives_smp_swit
24742 " .byte 662b-661b\n" /* sourcelen */ \
24743 " .byte 664f-663f\n" /* replacementlen */ \
24744 ".previous\n" \
24745- ".section .altinstr_replacement,\"ax\"\n" \
24746+ ".section .altinstr_replacement,\"a\"\n" \
24747 "663:\n\t" newinstr "\n664:\n" /* replacement */\
24748 ".previous" :: "i" (feature) : "memory")
24749
24750@@ -78,7 +78,7 @@ static inline void alternatives_smp_swit
24751 " .byte 662b-661b\n" /* sourcelen */ \
24752 " .byte 664f-663f\n" /* replacementlen */ \
24753 ".previous\n" \
24754- ".section .altinstr_replacement,\"ax\"\n" \
24755+ ".section .altinstr_replacement,\"a\"\n" \
24756 "663:\n\t" newinstr "\n664:\n" /* replacement */\
24757 ".previous" :: "i" (feature), ##input)
24758
24759diff -urNp linux-2.6.22.1/include/asm-i386/a.out.h linux-2.6.22.1/include/asm-i386/a.out.h
24760--- linux-2.6.22.1/include/asm-i386/a.out.h 2007-07-10 14:56:30.000000000 -0400
24761+++ linux-2.6.22.1/include/asm-i386/a.out.h 2007-08-02 11:38:48.000000000 -0400
24762@@ -19,7 +19,11 @@ struct exec
24763
24764 #ifdef __KERNEL__
24765
24766-#define STACK_TOP TASK_SIZE
24767+#ifdef CONFIG_PAX_SEGMEXEC
24768+#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
24769+#else
24770+#define __STACK_TOP TASK_SIZE
24771+#endif
24772
24773 #endif
24774
24775diff -urNp linux-2.6.22.1/include/asm-i386/apic.h linux-2.6.22.1/include/asm-i386/apic.h
24776--- linux-2.6.22.1/include/asm-i386/apic.h 2007-07-10 14:56:30.000000000 -0400
24777+++ linux-2.6.22.1/include/asm-i386/apic.h 2007-08-02 11:38:48.000000000 -0400
24778@@ -8,7 +8,7 @@
24779 #include <asm/processor.h>
24780 #include <asm/system.h>
24781
24782-#define Dprintk(x...)
24783+#define Dprintk(x...) do {} while (0)
24784
24785 /*
24786 * Debugging macros
24787diff -urNp linux-2.6.22.1/include/asm-i386/cache.h linux-2.6.22.1/include/asm-i386/cache.h
24788--- linux-2.6.22.1/include/asm-i386/cache.h 2007-07-10 14:56:30.000000000 -0400
24789+++ linux-2.6.22.1/include/asm-i386/cache.h 2007-08-02 11:38:48.000000000 -0400
24790@@ -10,5 +10,6 @@
24791 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
24792
24793 #define __read_mostly __attribute__((__section__(".data.read_mostly")))
24794+#define __read_only __attribute__((__section__(".data.read_only")))
24795
24796 #endif
24797diff -urNp linux-2.6.22.1/include/asm-i386/checksum.h linux-2.6.22.1/include/asm-i386/checksum.h
24798--- linux-2.6.22.1/include/asm-i386/checksum.h 2007-07-10 14:56:30.000000000 -0400
24799+++ linux-2.6.22.1/include/asm-i386/checksum.h 2007-08-02 11:38:48.000000000 -0400
24800@@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
24801 asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
24802 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
24803
24804+asmlinkage __wsum csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
24805+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
24806+
24807+asmlinkage __wsum csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
24808+ int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
24809+
24810 /*
24811 * Note: when you get a NULL pointer exception here this means someone
24812 * passed in an incorrect kernel address to one of these functions.
24813@@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
24814 int len, __wsum sum, int *err_ptr)
24815 {
24816 might_sleep();
24817- return csum_partial_copy_generic((__force void *)src, dst,
24818+ return csum_partial_copy_generic_from_user((__force void *)src, dst,
24819 len, sum, err_ptr, NULL);
24820 }
24821
24822@@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
24823 {
24824 might_sleep();
24825 if (access_ok(VERIFY_WRITE, dst, len))
24826- return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
24827+ return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
24828
24829 if (len)
24830 *err_ptr = -EFAULT;
24831diff -urNp linux-2.6.22.1/include/asm-i386/desc.h linux-2.6.22.1/include/asm-i386/desc.h
24832--- linux-2.6.22.1/include/asm-i386/desc.h 2007-07-10 14:56:30.000000000 -0400
24833+++ linux-2.6.22.1/include/asm-i386/desc.h 2007-08-02 11:38:48.000000000 -0400
24834@@ -7,26 +7,22 @@
24835 #ifndef __ASSEMBLY__
24836
24837 #include <linux/preempt.h>
24838-#include <linux/smp.h>
24839 #include <linux/percpu.h>
24840+#include <linux/smp.h>
24841
24842 #include <asm/mmu.h>
24843
24844+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
24845+
24846 struct Xgt_desc_struct {
24847 unsigned short size;
24848- unsigned long address __attribute__((packed));
24849+ struct desc_struct *address __attribute__((packed));
24850 unsigned short pad;
24851 } __attribute__ ((packed));
24852
24853-struct gdt_page
24854-{
24855- struct desc_struct gdt[GDT_ENTRIES];
24856-} __attribute__((aligned(PAGE_SIZE)));
24857-DECLARE_PER_CPU(struct gdt_page, gdt_page);
24858-
24859 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
24860 {
24861- return per_cpu(gdt_page, cpu).gdt;
24862+ return cpu_gdt_table[cpu];
24863 }
24864
24865 extern struct Xgt_desc_struct idt_descr;
24866@@ -81,8 +77,20 @@ static inline void pack_gate(__u32 *a, _
24867 static inline void write_dt_entry(struct desc_struct *dt,
24868 int entry, u32 entry_low, u32 entry_high)
24869 {
24870+
24871+#ifdef CONFIG_PAX_KERNEXEC
24872+ unsigned long cr0;
24873+
24874+ pax_open_kernel(cr0);
24875+#endif
24876+
24877 dt[entry].a = entry_low;
24878 dt[entry].b = entry_high;
24879+
24880+#ifdef CONFIG_PAX_KERNEXEC
24881+ pax_close_kernel(cr0);
24882+#endif
24883+
24884 }
24885
24886 static inline void native_set_ldt(const void *addr, unsigned int entries)
24887@@ -139,8 +147,19 @@ static inline void native_load_tls(struc
24888 unsigned int i;
24889 struct desc_struct *gdt = get_cpu_gdt_table(cpu);
24890
24891+#ifdef CONFIG_PAX_KERNEXEC
24892+ unsigned long cr0;
24893+
24894+ pax_open_kernel(cr0);
24895+#endif
24896+
24897 for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
24898 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
24899+
24900+#ifdef CONFIG_PAX_KERNEXEC
24901+ pax_close_kernel(cr0);
24902+#endif
24903+
24904 }
24905
24906 static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg)
24907@@ -175,7 +194,7 @@ static inline void __set_tss_desc(unsign
24908 ((info)->seg_32bit << 22) | \
24909 ((info)->limit_in_pages << 23) | \
24910 ((info)->useable << 20) | \
24911- 0x7000)
24912+ 0x7100)
24913
24914 #define LDT_empty(info) (\
24915 (info)->base_addr == 0 && \
24916@@ -207,15 +226,25 @@ static inline void load_LDT(mm_context_t
24917 preempt_enable();
24918 }
24919
24920-static inline unsigned long get_desc_base(unsigned long *desc)
24921+static inline unsigned long get_desc_base(struct desc_struct *desc)
24922 {
24923 unsigned long base;
24924- base = ((desc[0] >> 16) & 0x0000ffff) |
24925- ((desc[1] << 16) & 0x00ff0000) |
24926- (desc[1] & 0xff000000);
24927+ base = ((desc->a >> 16) & 0x0000ffff) |
24928+ ((desc->b << 16) & 0x00ff0000) |
24929+ (desc->b & 0xff000000);
24930 return base;
24931 }
24932
24933+static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
24934+{
24935+ __u32 a, b;
24936+
24937+ if (likely(limit))
24938+ limit = (limit - 1UL) >> PAGE_SHIFT;
24939+ pack_descriptor(&a, &b, base, limit, 0xFB, 0xC);
24940+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
24941+}
24942+
24943 #else /* __ASSEMBLY__ */
24944
24945 /*
24946diff -urNp linux-2.6.22.1/include/asm-i386/elf.h linux-2.6.22.1/include/asm-i386/elf.h
24947--- linux-2.6.22.1/include/asm-i386/elf.h 2007-07-10 14:56:30.000000000 -0400
24948+++ linux-2.6.22.1/include/asm-i386/elf.h 2007-08-02 11:38:48.000000000 -0400
24949@@ -73,7 +73,18 @@ typedef struct user_fxsr_struct elf_fpxr
24950 the loader. We need to make sure that it is out of the way of the program
24951 that it will "exec", and that there is sufficient room for the brk. */
24952
24953+#ifdef CONFIG_PAX_SEGMEXEC
24954+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
24955+#else
24956 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
24957+#endif
24958+
24959+#ifdef CONFIG_PAX_ASLR
24960+#define PAX_ELF_ET_DYN_BASE 0x10000000UL
24961+
24962+#define PAX_DELTA_MMAP_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
24963+#define PAX_DELTA_STACK_LEN (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
24964+#endif
24965
24966 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
24967 now struct_user_regs, they are different) */
24968@@ -131,7 +142,7 @@ extern int dump_task_extended_fpu (struc
24969 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
24970
24971 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
24972-#define VDSO_CURRENT_BASE ((unsigned long)current->mm->context.vdso)
24973+#define VDSO_CURRENT_BASE (current->mm->context.vdso)
24974 #define VDSO_PRELINK 0
24975
24976 #define VDSO_SYM(x) \
24977diff -urNp linux-2.6.22.1/include/asm-i386/futex.h linux-2.6.22.1/include/asm-i386/futex.h
24978--- linux-2.6.22.1/include/asm-i386/futex.h 2007-07-10 14:56:30.000000000 -0400
24979+++ linux-2.6.22.1/include/asm-i386/futex.h 2007-08-02 11:38:48.000000000 -0400
24980@@ -11,8 +11,11 @@
24981
24982 #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
24983 __asm__ __volatile ( \
24984+ "movw %w6, %%ds\n"\
24985 "1: " insn "\n" \
24986-"2: .section .fixup,\"ax\"\n\
24987+"2: pushl %%ss\n\
24988+ popl %%ds\n\
24989+ .section .fixup,\"ax\"\n\
24990 3: mov %3, %1\n\
24991 jmp 2b\n\
24992 .previous\n\
24993@@ -21,16 +24,19 @@
24994 .long 1b,3b\n\
24995 .previous" \
24996 : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
24997- : "i" (-EFAULT), "0" (oparg), "1" (0))
24998+ : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
24999
25000 #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
25001 __asm__ __volatile ( \
25002-"1: movl %2, %0\n\
25003+" movw %w7, %%es\n\
25004+1: movl %%es:%2, %0\n\
25005 movl %0, %3\n" \
25006 insn "\n" \
25007-"2: " LOCK_PREFIX "cmpxchgl %3, %2\n\
25008+"2: " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\
25009 jnz 1b\n\
25010-3: .section .fixup,\"ax\"\n\
25011+3: pushl %%ss\n\
25012+ popl %%es\n\
25013+ .section .fixup,\"ax\"\n\
25014 4: mov %5, %1\n\
25015 jmp 3b\n\
25016 .previous\n\
25017@@ -40,10 +46,10 @@
25018 .previous" \
25019 : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr), \
25020 "=&r" (tem) \
25021- : "r" (oparg), "i" (-EFAULT), "1" (0))
25022+ : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
25023
25024 static inline int
25025-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
25026+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
25027 {
25028 int op = (encoded_op >> 28) & 7;
25029 int cmp = (encoded_op >> 24) & 15;
25030@@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op,
25031 pagefault_disable();
25032
25033 if (op == FUTEX_OP_SET)
25034- __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
25035+ __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
25036 else {
25037 #ifndef CONFIG_X86_BSWAP
25038 if (boot_cpu_data.x86 == 3)
25039@@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op,
25040 #endif
25041 switch (op) {
25042 case FUTEX_OP_ADD:
25043- __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
25044+ __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret,
25045 oldval, uaddr, oparg);
25046 break;
25047 case FUTEX_OP_OR:
25048@@ -105,15 +111,17 @@ futex_atomic_op_inuser (int encoded_op,
25049 }
25050
25051 static inline int
25052-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
25053+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
25054 {
25055 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
25056 return -EFAULT;
25057
25058 __asm__ __volatile__(
25059- "1: " LOCK_PREFIX "cmpxchgl %3, %1 \n"
25060-
25061- "2: .section .fixup, \"ax\" \n"
25062+ " movw %w5, %%ds \n"
25063+ "1: " LOCK_PREFIX "cmpxchgl %3, %%ds:%1 \n"
25064+ "2: pushl %%ss \n"
25065+ " popl %%ds \n"
25066+ " .section .fixup, \"ax\" \n"
25067 "3: mov %2, %0 \n"
25068 " jmp 2b \n"
25069 " .previous \n"
25070@@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
25071 " .previous \n"
25072
25073 : "=a" (oldval), "+m" (*uaddr)
25074- : "i" (-EFAULT), "r" (newval), "0" (oldval)
25075+ : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
25076 : "memory"
25077 );
25078
25079diff -urNp linux-2.6.22.1/include/asm-i386/i387.h linux-2.6.22.1/include/asm-i386/i387.h
25080--- linux-2.6.22.1/include/asm-i386/i387.h 2007-07-10 14:56:30.000000000 -0400
25081+++ linux-2.6.22.1/include/asm-i386/i387.h 2007-08-02 11:38:48.000000000 -0400
25082@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
25083 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
25084
25085 /* We need a safe address that is cheap to find and that is already
25086- in L1 during context switch. The best choices are unfortunately
25087- different for UP and SMP */
25088-#ifdef CONFIG_SMP
25089-#define safe_address (__per_cpu_offset[0])
25090-#else
25091-#define safe_address (kstat_cpu(0).cpustat.user)
25092-#endif
25093+ in L1 during context switch. */
25094+#define safe_address (init_tss[smp_processor_id()].x86_tss.esp0)
25095
25096 /*
25097 * These must be called with preempt disabled
25098diff -urNp linux-2.6.22.1/include/asm-i386/irqflags.h linux-2.6.22.1/include/asm-i386/irqflags.h
25099--- linux-2.6.22.1/include/asm-i386/irqflags.h 2007-07-10 14:56:30.000000000 -0400
25100+++ linux-2.6.22.1/include/asm-i386/irqflags.h 2007-08-02 11:38:48.000000000 -0400
25101@@ -108,6 +108,8 @@ static inline unsigned long __raw_local_
25102 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
25103 #define INTERRUPT_RETURN iret
25104 #define GET_CR0_INTO_EAX movl %cr0, %eax
25105+#define GET_CR0_INTO_EDX movl %cr0, %edx
25106+#define SET_CR0_FROM_EDX movl %edx, %cr0
25107 #endif /* __ASSEMBLY__ */
25108 #endif /* CONFIG_PARAVIRT */
25109
25110diff -urNp linux-2.6.22.1/include/asm-i386/kmap_types.h linux-2.6.22.1/include/asm-i386/kmap_types.h
25111--- linux-2.6.22.1/include/asm-i386/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
25112+++ linux-2.6.22.1/include/asm-i386/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
25113@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
25114 D(10) KM_IRQ1,
25115 D(11) KM_SOFTIRQ0,
25116 D(12) KM_SOFTIRQ1,
25117-D(13) KM_TYPE_NR
25118+D(13) KM_CLEARPAGE,
25119+D(14) KM_TYPE_NR
25120 };
25121
25122 #undef D
25123diff -urNp linux-2.6.22.1/include/asm-i386/mach-default/apm.h linux-2.6.22.1/include/asm-i386/mach-default/apm.h
25124--- linux-2.6.22.1/include/asm-i386/mach-default/apm.h 2007-07-10 14:56:30.000000000 -0400
25125+++ linux-2.6.22.1/include/asm-i386/mach-default/apm.h 2007-08-02 11:38:48.000000000 -0400
25126@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
25127 __asm__ __volatile__(APM_DO_ZERO_SEGS
25128 "pushl %%edi\n\t"
25129 "pushl %%ebp\n\t"
25130- "lcall *%%cs:apm_bios_entry\n\t"
25131+ "lcall *%%ss:apm_bios_entry\n\t"
25132 "setc %%al\n\t"
25133 "popl %%ebp\n\t"
25134 "popl %%edi\n\t"
25135@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
25136 __asm__ __volatile__(APM_DO_ZERO_SEGS
25137 "pushl %%edi\n\t"
25138 "pushl %%ebp\n\t"
25139- "lcall *%%cs:apm_bios_entry\n\t"
25140+ "lcall *%%ss:apm_bios_entry\n\t"
25141 "setc %%bl\n\t"
25142 "popl %%ebp\n\t"
25143 "popl %%edi\n\t"
25144diff -urNp linux-2.6.22.1/include/asm-i386/mman.h linux-2.6.22.1/include/asm-i386/mman.h
25145--- linux-2.6.22.1/include/asm-i386/mman.h 2007-07-10 14:56:30.000000000 -0400
25146+++ linux-2.6.22.1/include/asm-i386/mman.h 2007-08-02 11:38:48.000000000 -0400
25147@@ -14,4 +14,12 @@
25148 #define MCL_CURRENT 1 /* lock all current mappings */
25149 #define MCL_FUTURE 2 /* lock all future mappings */
25150
25151+#ifdef __KERNEL__
25152+#ifndef __ASSEMBLY__
25153+#define arch_mmap_check i386_mmap_check
25154+int i386_mmap_check(unsigned long addr, unsigned long len,
25155+ unsigned long flags);
25156+#endif
25157+#endif
25158+
25159 #endif /* __I386_MMAN_H__ */
25160diff -urNp linux-2.6.22.1/include/asm-i386/mmu_context.h linux-2.6.22.1/include/asm-i386/mmu_context.h
25161--- linux-2.6.22.1/include/asm-i386/mmu_context.h 2007-07-10 14:56:30.000000000 -0400
25162+++ linux-2.6.22.1/include/asm-i386/mmu_context.h 2007-08-02 11:38:48.000000000 -0400
25163@@ -55,6 +55,22 @@ static inline void switch_mm(struct mm_s
25164 */
25165 if (unlikely(prev->context.ldt != next->context.ldt))
25166 load_LDT_nolock(&next->context);
25167+
25168+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
25169+ if (!nx_enabled) {
25170+ smp_mb__before_clear_bit();
25171+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
25172+ smp_mb__after_clear_bit();
25173+ cpu_set(cpu, next->context.cpu_user_cs_mask);
25174+ }
25175+#endif
25176+
25177+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
25178+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
25179+ prev->context.user_cs_limit != next->context.user_cs_limit))
25180+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
25181+#endif
25182+
25183 }
25184 #ifdef CONFIG_SMP
25185 else {
25186@@ -67,6 +83,19 @@ static inline void switch_mm(struct mm_s
25187 */
25188 load_cr3(next->pgd);
25189 load_LDT_nolock(&next->context);
25190+
25191+#ifdef CONFIG_PAX_PAGEEXEC
25192+ if (!nx_enabled)
25193+ cpu_set(cpu, next->context.cpu_user_cs_mask);
25194+#endif
25195+
25196+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
25197+#ifdef CONFIG_PAX_PAGEEXEC
25198+ if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
25199+#endif
25200+ set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
25201+#endif
25202+
25203 }
25204 }
25205 #endif
25206diff -urNp linux-2.6.22.1/include/asm-i386/mmu.h linux-2.6.22.1/include/asm-i386/mmu.h
25207--- linux-2.6.22.1/include/asm-i386/mmu.h 2007-07-10 14:56:30.000000000 -0400
25208+++ linux-2.6.22.1/include/asm-i386/mmu.h 2007-08-02 11:38:48.000000000 -0400
25209@@ -11,8 +11,19 @@
25210 typedef struct {
25211 int size;
25212 struct semaphore sem;
25213- void *ldt;
25214- void *vdso;
25215+ struct desc_struct *ldt;
25216+ unsigned long vdso;
25217+
25218+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
25219+ unsigned long user_cs_base;
25220+ unsigned long user_cs_limit;
25221+
25222+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
25223+ cpumask_t cpu_user_cs_mask;
25224+#endif
25225+
25226+#endif
25227+
25228 } mm_context_t;
25229
25230 #endif
25231diff -urNp linux-2.6.22.1/include/asm-i386/module.h linux-2.6.22.1/include/asm-i386/module.h
25232--- linux-2.6.22.1/include/asm-i386/module.h 2007-07-10 14:56:30.000000000 -0400
25233+++ linux-2.6.22.1/include/asm-i386/module.h 2007-08-02 11:09:16.000000000 -0400
25234@@ -70,6 +70,12 @@ struct mod_arch_specific
25235 #define MODULE_STACKSIZE ""
25236 #endif
25237
25238-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
25239+#ifdef CONFIG_GRKERNSEC
25240+#define MODULE_GRSEC "GRSECURTY "
25241+#else
25242+#define MODULE_GRSEC ""
25243+#endif
25244+
25245+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
25246
25247 #endif /* _ASM_I386_MODULE_H */
25248diff -urNp linux-2.6.22.1/include/asm-i386/page.h linux-2.6.22.1/include/asm-i386/page.h
25249--- linux-2.6.22.1/include/asm-i386/page.h 2007-07-10 14:56:30.000000000 -0400
25250+++ linux-2.6.22.1/include/asm-i386/page.h 2007-08-02 11:38:48.000000000 -0400
25251@@ -10,6 +10,7 @@
25252 #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
25253
25254 #ifdef __KERNEL__
25255+#include <asm/boot.h>
25256 #ifndef __ASSEMBLY__
25257
25258 #ifdef CONFIG_X86_USE_3DNOW
25259@@ -90,7 +91,6 @@ static inline pte_t native_make_pte(unsi
25260 typedef struct { unsigned long pte_low; } pte_t;
25261 typedef struct { unsigned long pgd; } pgd_t;
25262 typedef struct { unsigned long pgprot; } pgprot_t;
25263-#define boot_pte_t pte_t /* or would you rather have a typedef */
25264
25265 static inline unsigned long native_pgd_val(pgd_t pgd)
25266 {
25267@@ -175,6 +175,15 @@ extern int page_is_ram(unsigned long pag
25268 #define __PAGE_OFFSET ((unsigned long)CONFIG_PAGE_OFFSET)
25269 #endif
25270
25271+#ifdef CONFIG_PAX_KERNEXEC
25272+#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 4*1024*1024 - 1) & ~(4*1024*1024 - 1)))
25273+#ifndef __ASSEMBLY__
25274+extern unsigned char MODULES_VADDR[];
25275+extern unsigned char MODULES_END[];
25276+#endif
25277+#else
25278+#define __KERNEL_TEXT_OFFSET (0)
25279+#endif
25280
25281 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
25282 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
25283@@ -197,6 +206,10 @@ extern int page_is_ram(unsigned long pag
25284 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
25285 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25286
25287+#ifdef CONFIG_PAX_PAGEEXEC
25288+#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
25289+#endif
25290+
25291 #include <asm-generic/memory_model.h>
25292 #include <asm-generic/page.h>
25293
25294diff -urNp linux-2.6.22.1/include/asm-i386/paravirt.h linux-2.6.22.1/include/asm-i386/paravirt.h
25295--- linux-2.6.22.1/include/asm-i386/paravirt.h 2007-07-10 14:56:30.000000000 -0400
25296+++ linux-2.6.22.1/include/asm-i386/paravirt.h 2007-08-02 11:38:48.000000000 -0400
25297@@ -1041,23 +1041,23 @@ static inline unsigned long __raw_local_
25298
25299 #define INTERRUPT_RETURN \
25300 PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \
25301- jmp *%cs:paravirt_ops+PARAVIRT_iret)
25302+ jmp *%ss:paravirt_ops+PARAVIRT_iret)
25303
25304 #define DISABLE_INTERRUPTS(clobbers) \
25305 PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \
25306 pushl %eax; pushl %ecx; pushl %edx; \
25307- call *%cs:paravirt_ops+PARAVIRT_irq_disable; \
25308+ call *%ss:paravirt_ops+PARAVIRT_irq_disable; \
25309 popl %edx; popl %ecx; popl %eax) \
25310
25311 #define ENABLE_INTERRUPTS(clobbers) \
25312 PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \
25313 pushl %eax; pushl %ecx; pushl %edx; \
25314- call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
25315+ call *%ss:paravirt_ops+PARAVIRT_irq_enable; \
25316 popl %edx; popl %ecx; popl %eax)
25317
25318 #define ENABLE_INTERRUPTS_SYSEXIT \
25319 PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \
25320- jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
25321+ jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit)
25322
25323 #define GET_CR0_INTO_EAX \
25324 push %ecx; push %edx; \
25325diff -urNp linux-2.6.22.1/include/asm-i386/percpu.h linux-2.6.22.1/include/asm-i386/percpu.h
25326--- linux-2.6.22.1/include/asm-i386/percpu.h 2007-07-10 14:56:30.000000000 -0400
25327+++ linux-2.6.22.1/include/asm-i386/percpu.h 2007-08-02 11:38:48.000000000 -0400
25328@@ -22,7 +22,7 @@
25329 #define PER_CPU_VAR(var) %fs:per_cpu__##var
25330 #else /* ! SMP */
25331 #define PER_CPU(var, reg) \
25332- movl $per_cpu__##var, reg
25333+ movl per_cpu__##var, reg
25334 #define PER_CPU_VAR(var) per_cpu__##var
25335 #endif /* SMP */
25336
25337@@ -42,12 +42,12 @@
25338 */
25339 #ifdef CONFIG_SMP
25340 /* Same as generic implementation except for optimized local access. */
25341-#define __GENERIC_PER_CPU
25342
25343 /* This is used for other cpus to find our section. */
25344 extern unsigned long __per_cpu_offset[];
25345+extern void setup_per_cpu_areas(void);
25346
25347-#define per_cpu_offset(x) (__per_cpu_offset[x])
25348+#define per_cpu_offset(x) (__per_cpu_offset[x] - (unsigned long)__per_cpu_start)
25349
25350 /* Separate out the type, so (int[3], foo) works. */
25351 #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name
25352@@ -59,11 +59,11 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
25353
25354 /* var is in discarded region: offset to particular copy we want */
25355 #define per_cpu(var, cpu) (*({ \
25356- extern int simple_indentifier_##var(void); \
25357+ extern int simple_identifier_##var(void); \
25358 RELOC_HIDE(&per_cpu__##var, __per_cpu_offset[cpu]); }))
25359
25360 #define __raw_get_cpu_var(var) (*({ \
25361- extern int simple_indentifier_##var(void); \
25362+ extern int simple_identifier_##var(void); \
25363 RELOC_HIDE(&per_cpu__##var, x86_read_percpu(this_cpu_off)); \
25364 }))
25365
25366@@ -74,7 +74,7 @@ DECLARE_PER_CPU(unsigned long, this_cpu_
25367 do { \
25368 unsigned int __i; \
25369 for_each_possible_cpu(__i) \
25370- memcpy((pcpudst)+__per_cpu_offset[__i], \
25371+ memcpy((pcpudst)+per_cpu_offset(__i), \
25372 (src), (size)); \
25373 } while (0)
25374
25375diff -urNp linux-2.6.22.1/include/asm-i386/pgalloc.h linux-2.6.22.1/include/asm-i386/pgalloc.h
25376--- linux-2.6.22.1/include/asm-i386/pgalloc.h 2007-07-10 14:56:30.000000000 -0400
25377+++ linux-2.6.22.1/include/asm-i386/pgalloc.h 2007-08-02 11:38:48.000000000 -0400
25378@@ -15,11 +15,19 @@
25379 #define paravirt_release_pd(pfn) do { } while (0)
25380 #endif
25381
25382+#ifdef CONFIG_COMPAT_VDSO
25383 #define pmd_populate_kernel(mm, pmd, pte) \
25384 do { \
25385 paravirt_alloc_pt(__pa(pte) >> PAGE_SHIFT); \
25386 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))); \
25387 } while (0)
25388+#else
25389+#define pmd_populate_kernel(mm, pmd, pte) \
25390+do { \
25391+ paravirt_alloc_pt(__pa(pte) >> PAGE_SHIFT); \
25392+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte))); \
25393+} while (0)
25394+#endif
25395
25396 #define pmd_populate(mm, pmd, pte) \
25397 do { \
25398diff -urNp linux-2.6.22.1/include/asm-i386/pgtable-2level.h linux-2.6.22.1/include/asm-i386/pgtable-2level.h
25399--- linux-2.6.22.1/include/asm-i386/pgtable-2level.h 2007-07-10 14:56:30.000000000 -0400
25400+++ linux-2.6.22.1/include/asm-i386/pgtable-2level.h 2007-08-02 11:38:48.000000000 -0400
25401@@ -22,7 +22,19 @@ static inline void native_set_pte_at(str
25402 }
25403 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
25404 {
25405+
25406+#ifdef CONFIG_PAX_KERNEXEC
25407+ unsigned long cr0;
25408+
25409+ pax_open_kernel(cr0);
25410+#endif
25411+
25412 *pmdp = pmd;
25413+
25414+#ifdef CONFIG_PAX_KERNEXEC
25415+ pax_close_kernel(cr0);
25416+#endif
25417+
25418 }
25419 #ifndef CONFIG_PARAVIRT
25420 #define set_pte(pteptr, pteval) native_set_pte(pteptr, pteval)
25421diff -urNp linux-2.6.22.1/include/asm-i386/pgtable-3level.h linux-2.6.22.1/include/asm-i386/pgtable-3level.h
25422--- linux-2.6.22.1/include/asm-i386/pgtable-3level.h 2007-07-10 14:56:30.000000000 -0400
25423+++ linux-2.6.22.1/include/asm-i386/pgtable-3level.h 2007-08-02 11:38:48.000000000 -0400
25424@@ -82,11 +82,34 @@ static inline void native_set_pte_atomic
25425 }
25426 static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
25427 {
25428+#ifdef CONFIG_PAX_KERNEXEC
25429+ unsigned long cr0;
25430+
25431+ pax_open_kernel(cr0);
25432+#endif
25433+
25434 set_64bit((unsigned long long *)(pmdp),native_pmd_val(pmd));
25435+
25436+#ifdef CONFIG_PAX_KERNEXEC
25437+ pax_close_kernel(cr0);
25438+#endif
25439+
25440 }
25441 static inline void native_set_pud(pud_t *pudp, pud_t pud)
25442 {
25443+
25444+#ifdef CONFIG_PAX_KERNEXEC
25445+ unsigned long cr0;
25446+
25447+ pax_open_kernel(cr0);
25448+#endif
25449+
25450 *pudp = pud;
25451+
25452+#ifdef CONFIG_PAX_KERNEXEC
25453+ pax_close_kernel(cr0);
25454+#endif
25455+
25456 }
25457
25458 /*
25459diff -urNp linux-2.6.22/include/asm-i386/pgtable.h linux-2.6.22/include/asm-i386/pgtable.h
25460--- linux-2.6.22/include/asm-i386/pgtable.h 2007-07-10 14:56:30.000000000 -0400
25461+++ linux-2.6.22/include/asm-i386/pgtable.h 2007-07-10 14:56:30.000000000 -0400
25462@@ -34,7 +34,6 @@ struct vm_area_struct;
25463 */
25464 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
25465 extern unsigned long empty_zero_page[1024];
25466-extern pgd_t swapper_pg_dir[1024];
25467 extern struct kmem_cache *pmd_cache;
25468 extern spinlock_t pgd_lock;
25469 extern struct page *pgd_list;
25470@@ -58,6 +57,11 @@ void paging_init(void);
25471 # include <asm/pgtable-2level-defs.h>
25472 #endif
25473
25474+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
25475+#ifdef CONFIG_X86_PAE
25476+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
25477+#endif
25478+
25479 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
25480 #define PGDIR_MASK (~(PGDIR_SIZE-1))
25481
25482@@ -67,9 +71,11 @@ void paging_init(void);
25483 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
25484 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
25485
25486+#ifndef CONFIG_X86_PAE
25487 #define TWOLEVEL_PGDIR_SHIFT 22
25488 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
25489 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
25490+#endif
25491
25492 /* Just any arbitrary offset to the start of the vmalloc VM area: the
25493 * current 8MB value just means that there will be a 8MB "hole" after the
25494@@ -136,7 +142,7 @@ void paging_init(void);
25495 #define PAGE_NONE \
25496 __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
25497 #define PAGE_SHARED \
25498- __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
25499+ __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
25500
25501 #define PAGE_SHARED_EXEC \
25502 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
25503@@ -202,7 +208,7 @@ extern unsigned long long __PAGE_KERNEL,
25504 #undef TEST_ACCESS_OK
25505
25506 /* The boot page tables (all created as a single array) */
25507-extern unsigned long pg0[];
25508+extern pte_t pg0[];
25509
25510 #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
25511
25512@@ -225,29 +231,51 @@ static inline int pte_young(pte_t pte)
25513 static inline int pte_write(pte_t pte) { return (pte).pte_low & _PAGE_RW; }
25514 static inline int pte_huge(pte_t pte) { return (pte).pte_low & _PAGE_PSE; }
25515
25516+#ifdef CONFIG_X86_PAE
25517+# include <asm/pgtable-3level.h>
25518+#else
25519+# include <asm/pgtable-2level.h>
25520+#endif
25521+
25522 /*
25523 * The following only works if pte_present() is not true.
25524 */
25525 static inline int pte_file(pte_t pte) { return (pte).pte_low & _PAGE_FILE; }
25526
25527 static inline pte_t pte_rdprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; }
25528-static inline pte_t pte_exprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_USER; return pte; }
25529+
25530+static inline pte_t pte_exprotect(pte_t pte)
25531+{
25532+#ifdef CONFIG_X86_PAE
25533+ if (__supported_pte_mask & _PAGE_NX)
25534+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
25535+ else
25536+#endif
25537+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
25538+ return pte;
25539+}
25540+
25541 static inline pte_t pte_mkclean(pte_t pte) { (pte).pte_low &= ~_PAGE_DIRTY; return pte; }
25542 static inline pte_t pte_mkold(pte_t pte) { (pte).pte_low &= ~_PAGE_ACCESSED; return pte; }
25543 static inline pte_t pte_wrprotect(pte_t pte) { (pte).pte_low &= ~_PAGE_RW; return pte; }
25544 static inline pte_t pte_mkread(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
25545-static inline pte_t pte_mkexec(pte_t pte) { (pte).pte_low |= _PAGE_USER; return pte; }
25546+
25547+static inline pte_t pte_mkexec(pte_t pte)
25548+{
25549+#ifdef CONFIG_X86_PAE
25550+ if (__supported_pte_mask & _PAGE_NX)
25551+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
25552+ else
25553+#endif
25554+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
25555+ return pte;
25556+}
25557+
25558 static inline pte_t pte_mkdirty(pte_t pte) { (pte).pte_low |= _PAGE_DIRTY; return pte; }
25559 static inline pte_t pte_mkyoung(pte_t pte) { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
25560 static inline pte_t pte_mkwrite(pte_t pte) { (pte).pte_low |= _PAGE_RW; return pte; }
25561 static inline pte_t pte_mkhuge(pte_t pte) { (pte).pte_low |= _PAGE_PSE; return pte; }
25562
25563-#ifdef CONFIG_X86_PAE
25564-# include <asm/pgtable-3level.h>
25565-#else
25566-# include <asm/pgtable-2level.h>
25567-#endif
25568-
25569 #ifndef CONFIG_PARAVIRT
25570 /*
25571 * Rules for using pte_update - it must be called after any PTE update which
25572@@ -538,6 +566,9 @@ static inline void paravirt_pagetable_se
25573
25574 #endif /* !__ASSEMBLY__ */
25575
25576+#define HAVE_ARCH_UNMAPPED_AREA
25577+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
25578+
25579 #ifdef CONFIG_FLATMEM
25580 #define kern_addr_valid(addr) (1)
25581 #endif /* CONFIG_FLATMEM */
25582diff -urNp linux-2.6.22.1/include/asm-i386/processor.h linux-2.6.22.1/include/asm-i386/processor.h
25583--- linux-2.6.22.1/include/asm-i386/processor.h 2007-07-10 14:56:30.000000000 -0400
25584+++ linux-2.6.22.1/include/asm-i386/processor.h 2007-08-02 11:38:48.000000000 -0400
25585@@ -100,8 +100,6 @@ struct cpuinfo_x86 {
25586
25587 extern struct cpuinfo_x86 boot_cpu_data;
25588 extern struct cpuinfo_x86 new_cpu_data;
25589-extern struct tss_struct doublefault_tss;
25590-DECLARE_PER_CPU(struct tss_struct, init_tss);
25591
25592 #ifdef CONFIG_SMP
25593 extern struct cpuinfo_x86 cpu_data[];
25594@@ -220,11 +218,19 @@ extern int bootloader_type;
25595 */
25596 #define TASK_SIZE (PAGE_OFFSET)
25597
25598+#ifdef CONFIG_PAX_SEGMEXEC
25599+#define SEGMEXEC_TASK_SIZE (TASK_SIZE / 2)
25600+#endif
25601+
25602 /* This decides where the kernel will search for a free chunk of vm
25603 * space during mmap's.
25604 */
25605 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
25606
25607+#ifdef CONFIG_PAX_SEGMEXEC
25608+#define SEGMEXEC_TASK_UNMAPPED_BASE (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
25609+#endif
25610+
25611 #define HAVE_ARCH_PICK_MMAP_LAYOUT
25612
25613 /*
25614@@ -345,6 +352,9 @@ struct tss_struct {
25615
25616 #define ARCH_MIN_TASKALIGN 16
25617
25618+extern struct tss_struct doublefault_tss;
25619+extern struct tss_struct init_tss[NR_CPUS];
25620+
25621 struct thread_struct {
25622 /* cached TLS descriptors. */
25623 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
25624@@ -373,7 +383,7 @@ struct thread_struct {
25625 };
25626
25627 #define INIT_THREAD { \
25628- .esp0 = sizeof(init_stack) + (long)&init_stack, \
25629+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
25630 .vm86_info = NULL, \
25631 .sysenter_cs = __KERNEL_CS, \
25632 .io_bitmap_ptr = NULL, \
25633@@ -388,7 +398,7 @@ struct thread_struct {
25634 */
25635 #define INIT_TSS { \
25636 .x86_tss = { \
25637- .esp0 = sizeof(init_stack) + (long)&init_stack, \
25638+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
25639 .ss0 = __KERNEL_DS, \
25640 .ss1 = __KERNEL_CS, \
25641 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
25642@@ -429,11 +439,7 @@ void show_trace(struct task_struct *task
25643 unsigned long get_wchan(struct task_struct *p);
25644
25645 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
25646-#define KSTK_TOP(info) \
25647-({ \
25648- unsigned long *__ptr = (unsigned long *)(info); \
25649- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
25650-})
25651+#define KSTK_TOP(info) ((info)->task.thread.esp0)
25652
25653 /*
25654 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
25655@@ -448,7 +454,7 @@ unsigned long get_wchan(struct task_stru
25656 #define task_pt_regs(task) \
25657 ({ \
25658 struct pt_regs *__regs__; \
25659- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
25660+ __regs__ = (struct pt_regs *)((task)->thread.esp0); \
25661 __regs__ - 1; \
25662 })
25663
25664@@ -610,8 +616,8 @@ static inline void cpuid(unsigned int op
25665 }
25666
25667 /* Some CPUID calls want 'count' to be placed in ecx */
25668-static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx,
25669- int *edx)
25670+static inline void cpuid_count(unsigned int op, unsigned int count, unsigned int *eax, unsigned int *ebx, unsigned int *ecx,
25671+ unsigned int *edx)
25672 {
25673 *eax = op;
25674 *ecx = count;
25675diff -urNp linux-2.6.22.1/include/asm-i386/ptrace.h linux-2.6.22.1/include/asm-i386/ptrace.h
25676--- linux-2.6.22.1/include/asm-i386/ptrace.h 2007-07-10 14:56:30.000000000 -0400
25677+++ linux-2.6.22.1/include/asm-i386/ptrace.h 2007-08-02 11:38:48.000000000 -0400
25678@@ -35,17 +35,18 @@ struct task_struct;
25679 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
25680
25681 /*
25682- * user_mode_vm(regs) determines whether a register set came from user mode.
25683+ * user_mode(regs) determines whether a register set came from user mode.
25684 * This is true if V8086 mode was enabled OR if the register set was from
25685 * protected mode with RPL-3 CS value. This tricky test checks that with
25686 * one comparison. Many places in the kernel can bypass this full check
25687- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
25688+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
25689+ * be used.
25690 */
25691-static inline int user_mode(struct pt_regs *regs)
25692+static inline int user_mode_novm(struct pt_regs *regs)
25693 {
25694 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
25695 }
25696-static inline int user_mode_vm(struct pt_regs *regs)
25697+static inline int user_mode(struct pt_regs *regs)
25698 {
25699 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
25700 }
25701diff -urNp linux-2.6.22.1/include/asm-i386/reboot.h linux-2.6.22.1/include/asm-i386/reboot.h
25702--- linux-2.6.22.1/include/asm-i386/reboot.h 2007-07-10 14:56:30.000000000 -0400
25703+++ linux-2.6.22.1/include/asm-i386/reboot.h 2007-08-02 11:38:48.000000000 -0400
25704@@ -15,6 +15,6 @@ struct machine_ops
25705
25706 extern struct machine_ops machine_ops;
25707
25708-void machine_real_restart(unsigned char *code, int length);
25709+void machine_real_restart(const unsigned char *code, unsigned int length);
25710
25711 #endif /* _ASM_REBOOT_H */
25712diff -urNp linux-2.6.22.1/include/asm-i386/segment.h linux-2.6.22.1/include/asm-i386/segment.h
25713--- linux-2.6.22.1/include/asm-i386/segment.h 2007-07-10 14:56:30.000000000 -0400
25714+++ linux-2.6.22.1/include/asm-i386/segment.h 2007-08-03 14:38:20.000000000 -0400
25715@@ -81,6 +81,12 @@
25716 #define __KERNEL_PERCPU 0
25717 #endif
25718
25719+#define GDT_ENTRY_PCIBIOS_CS (GDT_ENTRY_KERNEL_BASE + 16)
25720+#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
25721+
25722+#define GDT_ENTRY_PCIBIOS_DS (GDT_ENTRY_KERNEL_BASE + 17)
25723+#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
25724+
25725 #define GDT_ENTRY_DOUBLEFAULT_TSS 31
25726
25727 /*
25728@@ -140,9 +146,9 @@
25729 #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
25730
25731 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
25732-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
25733+#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
25734
25735 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
25736-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
25737+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
25738
25739 #endif
25740diff -urNp linux-2.6.22.1/include/asm-i386/system.h linux-2.6.22.1/include/asm-i386/system.h
25741--- linux-2.6.22.1/include/asm-i386/system.h 2007-07-10 14:56:30.000000000 -0400
25742+++ linux-2.6.22.1/include/asm-i386/system.h 2007-08-02 11:38:48.000000000 -0400
25743@@ -183,6 +183,21 @@ static inline void native_wbinvd(void)
25744 /* Set the 'TS' bit */
25745 #define stts() write_cr0(8 | read_cr0())
25746
25747+#define pax_open_kernel(cr0) \
25748+do { \
25749+ typecheck(unsigned long, cr0); \
25750+ preempt_disable(); \
25751+ cr0 = read_cr0(); \
25752+ write_cr0(cr0 & ~X86_CR0_WP); \
25753+} while (0)
25754+
25755+#define pax_close_kernel(cr0) \
25756+do { \
25757+ typecheck(unsigned long, cr0); \
25758+ write_cr0(cr0); \
25759+ preempt_enable_no_resched(); \
25760+} while (0)
25761+
25762 #endif /* __KERNEL__ */
25763
25764 static inline unsigned long get_limit(unsigned long segment)
25765@@ -190,7 +205,7 @@ static inline unsigned long get_limit(un
25766 unsigned long __limit;
25767 __asm__("lsll %1,%0"
25768 :"=r" (__limit):"r" (segment));
25769- return __limit+1;
25770+ return __limit;
25771 }
25772
25773 #define nop() __asm__ __volatile__ ("nop")
25774@@ -319,7 +334,7 @@ static inline void sched_cacheflush(void
25775 wbinvd();
25776 }
25777
25778-extern unsigned long arch_align_stack(unsigned long sp);
25779+#define arch_align_stack(x) (x)
25780 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
25781
25782 void default_idle(void);
25783diff -urNp linux-2.6.22.1/include/asm-i386/uaccess.h linux-2.6.22.1/include/asm-i386/uaccess.h
25784--- linux-2.6.22.1/include/asm-i386/uaccess.h 2007-07-10 14:56:30.000000000 -0400
25785+++ linux-2.6.22.1/include/asm-i386/uaccess.h 2007-08-02 11:38:48.000000000 -0400
25786@@ -9,6 +9,7 @@
25787 #include <linux/prefetch.h>
25788 #include <linux/string.h>
25789 #include <asm/page.h>
25790+#include <asm/segment.h>
25791
25792 #define VERIFY_READ 0
25793 #define VERIFY_WRITE 1
25794@@ -29,7 +30,8 @@
25795
25796 #define get_ds() (KERNEL_DS)
25797 #define get_fs() (current_thread_info()->addr_limit)
25798-#define set_fs(x) (current_thread_info()->addr_limit = (x))
25799+void __set_fs(mm_segment_t x, int cpu);
25800+void set_fs(mm_segment_t x);
25801
25802 #define segment_eq(a,b) ((a).seg == (b).seg)
25803
25804@@ -280,9 +282,12 @@ extern void __put_user_8(void);
25805
25806 #define __put_user_u64(x, addr, err) \
25807 __asm__ __volatile__( \
25808- "1: movl %%eax,0(%2)\n" \
25809- "2: movl %%edx,4(%2)\n" \
25810+ " movw %w5,%%ds\n" \
25811+ "1: movl %%eax,%%ds:0(%2)\n" \
25812+ "2: movl %%edx,%%ds:4(%2)\n" \
25813 "3:\n" \
25814+ " pushl %%ss\n" \
25815+ " popl %%ds\n" \
25816 ".section .fixup,\"ax\"\n" \
25817 "4: movl %3,%0\n" \
25818 " jmp 3b\n" \
25819@@ -293,7 +298,8 @@ extern void __put_user_8(void);
25820 " .long 2b,4b\n" \
25821 ".previous" \
25822 : "=r"(err) \
25823- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
25824+ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
25825+ "r"(__USER_DS))
25826
25827 #ifdef CONFIG_X86_WP_WORKS_OK
25828
25829@@ -332,8 +338,11 @@ struct __large_struct { unsigned long bu
25830 */
25831 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
25832 __asm__ __volatile__( \
25833- "1: mov"itype" %"rtype"1,%2\n" \
25834+ " movw %w5,%%ds\n" \
25835+ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
25836 "2:\n" \
25837+ " pushl %%ss\n" \
25838+ " popl %%ds\n" \
25839 ".section .fixup,\"ax\"\n" \
25840 "3: movl %3,%0\n" \
25841 " jmp 2b\n" \
25842@@ -343,7 +352,8 @@ struct __large_struct { unsigned long bu
25843 " .long 1b,3b\n" \
25844 ".previous" \
25845 : "=r"(err) \
25846- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
25847+ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
25848+ "r"(__USER_DS))
25849
25850
25851 #define __get_user_nocheck(x,ptr,size) \
25852@@ -371,8 +381,11 @@ do { \
25853
25854 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
25855 __asm__ __volatile__( \
25856- "1: mov"itype" %2,%"rtype"1\n" \
25857+ " movw %w5,%%ds\n" \
25858+ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
25859 "2:\n" \
25860+ " pushl %%ss\n" \
25861+ " popl %%ds\n" \
25862 ".section .fixup,\"ax\"\n" \
25863 "3: movl %3,%0\n" \
25864 " xor"itype" %"rtype"1,%"rtype"1\n" \
25865@@ -383,7 +396,7 @@ do { \
25866 " .long 1b,3b\n" \
25867 ".previous" \
25868 : "=r"(err), ltype (x) \
25869- : "m"(__m(addr)), "i"(errret), "0"(err))
25870+ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
25871
25872
25873 unsigned long __must_check __copy_to_user_ll(void __user *to,
25874diff -urNp linux-2.6.22.1/include/asm-ia64/elf.h linux-2.6.22.1/include/asm-ia64/elf.h
25875--- linux-2.6.22.1/include/asm-ia64/elf.h 2007-07-10 14:56:30.000000000 -0400
25876+++ linux-2.6.22.1/include/asm-ia64/elf.h 2007-08-02 11:38:48.000000000 -0400
25877@@ -162,7 +162,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
25878 typedef struct ia64_fpreg elf_fpreg_t;
25879 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
25880
25881+#ifdef CONFIG_PAX_ASLR
25882+#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
25883
25884+#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
25885+#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
25886+#endif
25887
25888 struct pt_regs; /* forward declaration... */
25889 extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
25890diff -urNp linux-2.6.22.1/include/asm-ia64/kmap_types.h linux-2.6.22.1/include/asm-ia64/kmap_types.h
25891--- linux-2.6.22.1/include/asm-ia64/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
25892+++ linux-2.6.22.1/include/asm-ia64/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
25893@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
25894 D(10) KM_IRQ1,
25895 D(11) KM_SOFTIRQ0,
25896 D(12) KM_SOFTIRQ1,
25897-D(13) KM_TYPE_NR
25898+D(13) KM_CLEARPAGE,
25899+D(14) KM_TYPE_NR
25900 };
25901
25902 #undef D
25903diff -urNp linux-2.6.22.1/include/asm-ia64/pgtable.h linux-2.6.22.1/include/asm-ia64/pgtable.h
25904--- linux-2.6.22.1/include/asm-ia64/pgtable.h 2007-07-10 14:56:30.000000000 -0400
25905+++ linux-2.6.22.1/include/asm-ia64/pgtable.h 2007-08-02 11:38:48.000000000 -0400
25906@@ -143,6 +143,17 @@
25907 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
25908 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
25909 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
25910+
25911+#ifdef CONFIG_PAX_PAGEEXEC
25912+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
25913+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
25914+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
25915+#else
25916+# define PAGE_SHARED_NOEXEC PAGE_SHARED
25917+# define PAGE_READONLY_NOEXEC PAGE_READONLY
25918+# define PAGE_COPY_NOEXEC PAGE_COPY
25919+#endif
25920+
25921 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
25922 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
25923 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
25924diff -urNp linux-2.6.22.1/include/asm-ia64/processor.h linux-2.6.22.1/include/asm-ia64/processor.h
25925--- linux-2.6.22.1/include/asm-ia64/processor.h 2007-07-10 14:56:30.000000000 -0400
25926+++ linux-2.6.22.1/include/asm-ia64/processor.h 2007-08-02 11:38:48.000000000 -0400
25927@@ -275,7 +275,7 @@ struct thread_struct {
25928 .on_ustack = 0, \
25929 .ksp = 0, \
25930 .map_base = DEFAULT_MAP_BASE, \
25931- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
25932+ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
25933 .task_size = DEFAULT_TASK_SIZE, \
25934 .last_fph_cpu = -1, \
25935 INIT_THREAD_IA32 \
25936diff -urNp linux-2.6.22.1/include/asm-ia64/ustack.h linux-2.6.22.1/include/asm-ia64/ustack.h
25937--- linux-2.6.22.1/include/asm-ia64/ustack.h 2007-07-10 14:56:30.000000000 -0400
25938+++ linux-2.6.22.1/include/asm-ia64/ustack.h 2007-08-02 11:38:48.000000000 -0400
25939@@ -10,10 +10,10 @@
25940
25941 /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
25942 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
25943-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
25944+#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
25945 #endif
25946
25947-/* Make a default stack size of 2GiB */
25948+/* Make a default stack size of 2GB */
25949 #define DEFAULT_USER_STACK_SIZE (1UL << 31)
25950
25951 #endif /* _ASM_IA64_USTACK_H */
25952diff -urNp linux-2.6.22.1/include/asm-m32r/kmap_types.h linux-2.6.22.1/include/asm-m32r/kmap_types.h
25953--- linux-2.6.22.1/include/asm-m32r/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
25954+++ linux-2.6.22.1/include/asm-m32r/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
25955@@ -21,7 +21,8 @@ D(9) KM_IRQ0,
25956 D(10) KM_IRQ1,
25957 D(11) KM_SOFTIRQ0,
25958 D(12) KM_SOFTIRQ1,
25959-D(13) KM_TYPE_NR
25960+D(13) KM_CLEARPAGE,
25961+D(14) KM_TYPE_NR
25962 };
25963
25964 #undef D
25965diff -urNp linux-2.6.22.1/include/asm-m68k/kmap_types.h linux-2.6.22.1/include/asm-m68k/kmap_types.h
25966--- linux-2.6.22.1/include/asm-m68k/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
25967+++ linux-2.6.22.1/include/asm-m68k/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
25968@@ -15,6 +15,7 @@ enum km_type {
25969 KM_IRQ1,
25970 KM_SOFTIRQ0,
25971 KM_SOFTIRQ1,
25972+ KM_CLEARPAGE,
25973 KM_TYPE_NR
25974 };
25975
25976diff -urNp linux-2.6.22.1/include/asm-m68knommu/kmap_types.h linux-2.6.22.1/include/asm-m68knommu/kmap_types.h
25977--- linux-2.6.22.1/include/asm-m68knommu/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
25978+++ linux-2.6.22.1/include/asm-m68knommu/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
25979@@ -15,6 +15,7 @@ enum km_type {
25980 KM_IRQ1,
25981 KM_SOFTIRQ0,
25982 KM_SOFTIRQ1,
25983+ KM_CLEARPAGE,
25984 KM_TYPE_NR
25985 };
25986
25987diff -urNp linux-2.6.22.1/include/asm-mips/a.out.h linux-2.6.22.1/include/asm-mips/a.out.h
25988--- linux-2.6.22.1/include/asm-mips/a.out.h 2007-07-10 14:56:30.000000000 -0400
25989+++ linux-2.6.22.1/include/asm-mips/a.out.h 2007-08-02 11:38:48.000000000 -0400
25990@@ -35,10 +35,10 @@ struct exec
25991 #ifdef __KERNEL__
25992
25993 #ifdef CONFIG_32BIT
25994-#define STACK_TOP TASK_SIZE
25995+#define __STACK_TOP TASK_SIZE
25996 #endif
25997 #ifdef CONFIG_64BIT
25998-#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
25999+#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
26000 #endif
26001
26002 #endif
26003diff -urNp linux-2.6.22.1/include/asm-mips/elf.h linux-2.6.22.1/include/asm-mips/elf.h
26004--- linux-2.6.22.1/include/asm-mips/elf.h 2007-07-10 14:56:30.000000000 -0400
26005+++ linux-2.6.22.1/include/asm-mips/elf.h 2007-08-02 11:38:48.000000000 -0400
26006@@ -371,4 +371,11 @@ extern int dump_task_fpu(struct task_str
26007 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
26008 #endif
26009
26010+#ifdef CONFIG_PAX_ASLR
26011+#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
26012+
26013+#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26014+#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26015+#endif
26016+
26017 #endif /* _ASM_ELF_H */
26018diff -urNp linux-2.6.22.1/include/asm-mips/kmap_types.h linux-2.6.22.1/include/asm-mips/kmap_types.h
26019--- linux-2.6.22.1/include/asm-mips/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26020+++ linux-2.6.22.1/include/asm-mips/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26021@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26022 D(10) KM_IRQ1,
26023 D(11) KM_SOFTIRQ0,
26024 D(12) KM_SOFTIRQ1,
26025-D(13) KM_TYPE_NR
26026+D(13) KM_CLEARPAGE,
26027+D(14) KM_TYPE_NR
26028 };
26029
26030 #undef D
26031diff -urNp linux-2.6.22.1/include/asm-mips/page.h linux-2.6.22.1/include/asm-mips/page.h
26032--- linux-2.6.22.1/include/asm-mips/page.h 2007-07-10 14:56:30.000000000 -0400
26033+++ linux-2.6.22.1/include/asm-mips/page.h 2007-08-02 11:38:48.000000000 -0400
26034@@ -89,7 +89,7 @@ extern void copy_user_highpage(struct pa
26035 #ifdef CONFIG_CPU_MIPS32
26036 typedef struct { unsigned long pte_low, pte_high; } pte_t;
26037 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
26038- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
26039+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
26040 #else
26041 typedef struct { unsigned long long pte; } pte_t;
26042 #define pte_val(x) ((x).pte)
26043diff -urNp linux-2.6.22.1/include/asm-parisc/a.out.h linux-2.6.22.1/include/asm-parisc/a.out.h
26044--- linux-2.6.22.1/include/asm-parisc/a.out.h 2007-07-10 14:56:30.000000000 -0400
26045+++ linux-2.6.22.1/include/asm-parisc/a.out.h 2007-08-02 11:38:48.000000000 -0400
26046@@ -22,7 +22,7 @@ struct exec
26047 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
26048 * prumpf */
26049
26050-#define STACK_TOP TASK_SIZE
26051+#define __STACK_TOP TASK_SIZE
26052
26053 #endif
26054
26055diff -urNp linux-2.6.22.1/include/asm-parisc/elf.h linux-2.6.22.1/include/asm-parisc/elf.h
26056--- linux-2.6.22.1/include/asm-parisc/elf.h 2007-07-10 14:56:30.000000000 -0400
26057+++ linux-2.6.22.1/include/asm-parisc/elf.h 2007-08-02 11:38:48.000000000 -0400
26058@@ -337,6 +337,13 @@ struct pt_regs; /* forward declaration..
26059
26060 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
26061
26062+#ifdef CONFIG_PAX_ASLR
26063+#define PAX_ELF_ET_DYN_BASE 0x10000UL
26064+
26065+#define PAX_DELTA_MMAP_LEN 16
26066+#define PAX_DELTA_STACK_LEN 16
26067+#endif
26068+
26069 /* This yields a mask that user programs can use to figure out what
26070 instruction set this CPU supports. This could be done in user space,
26071 but it's not easy, and we've already done it here. */
26072diff -urNp linux-2.6.22.1/include/asm-parisc/kmap_types.h linux-2.6.22.1/include/asm-parisc/kmap_types.h
26073--- linux-2.6.22.1/include/asm-parisc/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26074+++ linux-2.6.22.1/include/asm-parisc/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26075@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
26076 D(10) KM_IRQ1,
26077 D(11) KM_SOFTIRQ0,
26078 D(12) KM_SOFTIRQ1,
26079-D(13) KM_TYPE_NR
26080+D(13) KM_CLEARPAGE,
26081+D(14) KM_TYPE_NR
26082 };
26083
26084 #undef D
26085diff -urNp linux-2.6.22.1/include/asm-parisc/pgtable.h linux-2.6.22.1/include/asm-parisc/pgtable.h
26086--- linux-2.6.22.1/include/asm-parisc/pgtable.h 2007-07-10 14:56:30.000000000 -0400
26087+++ linux-2.6.22.1/include/asm-parisc/pgtable.h 2007-08-02 11:38:48.000000000 -0400
26088@@ -218,6 +218,17 @@ extern void *vmalloc_start;
26089 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
26090 #define PAGE_COPY PAGE_EXECREAD
26091 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
26092+
26093+#ifdef CONFIG_PAX_PAGEEXEC
26094+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
26095+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26096+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26097+#else
26098+# define PAGE_SHARED_NOEXEC PAGE_SHARED
26099+# define PAGE_COPY_NOEXEC PAGE_COPY
26100+# define PAGE_READONLY_NOEXEC PAGE_READONLY
26101+#endif
26102+
26103 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
26104 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
26105 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
26106diff -urNp linux-2.6.22.1/include/asm-powerpc/a.out.h linux-2.6.22.1/include/asm-powerpc/a.out.h
26107--- linux-2.6.22.1/include/asm-powerpc/a.out.h 2007-07-10 14:56:30.000000000 -0400
26108+++ linux-2.6.22.1/include/asm-powerpc/a.out.h 2007-08-02 11:38:48.000000000 -0400
26109@@ -23,12 +23,12 @@ struct exec
26110 #define STACK_TOP_USER64 TASK_SIZE_USER64
26111 #define STACK_TOP_USER32 TASK_SIZE_USER32
26112
26113-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
26114+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
26115 STACK_TOP_USER32 : STACK_TOP_USER64)
26116
26117 #else /* __powerpc64__ */
26118
26119-#define STACK_TOP TASK_SIZE
26120+#define __STACK_TOP TASK_SIZE
26121
26122 #endif /* __powerpc64__ */
26123 #endif /* __KERNEL__ */
26124diff -urNp linux-2.6.22.1/include/asm-powerpc/elf.h linux-2.6.22.1/include/asm-powerpc/elf.h
26125--- linux-2.6.22.1/include/asm-powerpc/elf.h 2007-07-10 14:56:30.000000000 -0400
26126+++ linux-2.6.22.1/include/asm-powerpc/elf.h 2007-08-02 11:38:48.000000000 -0400
26127@@ -159,6 +159,18 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
26128 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
26129 #endif
26130
26131+#ifdef CONFIG_PAX_ASLR
26132+#define PAX_ELF_ET_DYN_BASE (0x10000000UL)
26133+
26134+#ifdef __powerpc64__
26135+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
26136+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 16 : 28)
26137+#else
26138+#define PAX_DELTA_MMAP_LEN 15
26139+#define PAX_DELTA_STACK_LEN 15
26140+#endif
26141+#endif
26142+
26143 #ifdef __KERNEL__
26144 /*
26145 * This is used to ensure we don't load something for the wrong architecture.
26146diff -urNp linux-2.6.22.1/include/asm-powerpc/kmap_types.h linux-2.6.22.1/include/asm-powerpc/kmap_types.h
26147--- linux-2.6.22.1/include/asm-powerpc/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26148+++ linux-2.6.22.1/include/asm-powerpc/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26149@@ -26,6 +26,7 @@ enum km_type {
26150 KM_SOFTIRQ1,
26151 KM_PPC_SYNC_PAGE,
26152 KM_PPC_SYNC_ICACHE,
26153+ KM_CLEARPAGE,
26154 KM_TYPE_NR
26155 };
26156
26157diff -urNp linux-2.6.22.1/include/asm-powerpc/page_64.h linux-2.6.22.1/include/asm-powerpc/page_64.h
26158--- linux-2.6.22.1/include/asm-powerpc/page_64.h 2007-07-10 14:56:30.000000000 -0400
26159+++ linux-2.6.22.1/include/asm-powerpc/page_64.h 2007-08-02 11:38:48.000000000 -0400
26160@@ -158,15 +158,18 @@ extern int is_hugepage_only_range(struct
26161 * stack by default, so in the absense of a PT_GNU_STACK program header
26162 * we turn execute permission off.
26163 */
26164-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
26165- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26166+#define VM_STACK_DEFAULT_FLAGS32 \
26167+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
26168+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26169
26170 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
26171 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26172
26173+#ifndef CONFIG_PAX_PAGEEXEC
26174 #define VM_STACK_DEFAULT_FLAGS \
26175 (test_thread_flag(TIF_32BIT) ? \
26176 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
26177+#endif
26178
26179 #include <asm-generic/page.h>
26180
26181diff -urNp linux-2.6.22.1/include/asm-powerpc/page.h linux-2.6.22.1/include/asm-powerpc/page.h
26182--- linux-2.6.22.1/include/asm-powerpc/page.h 2007-07-10 14:56:30.000000000 -0400
26183+++ linux-2.6.22.1/include/asm-powerpc/page.h 2007-08-02 11:38:48.000000000 -0400
26184@@ -71,8 +71,9 @@
26185 * and needs to be executable. This means the whole heap ends
26186 * up being executable.
26187 */
26188-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
26189- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26190+#define VM_DATA_DEFAULT_FLAGS32 \
26191+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
26192+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26193
26194 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
26195 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
26196diff -urNp linux-2.6.22.1/include/asm-ppc/mmu_context.h linux-2.6.22.1/include/asm-ppc/mmu_context.h
26197--- linux-2.6.22.1/include/asm-ppc/mmu_context.h 2007-07-10 14:56:30.000000000 -0400
26198+++ linux-2.6.22.1/include/asm-ppc/mmu_context.h 2007-08-02 11:38:48.000000000 -0400
26199@@ -145,7 +145,8 @@ static inline void get_mmu_context(struc
26200 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
26201 {
26202 mm->context.id = NO_CONTEXT;
26203- mm->context.vdso_base = 0;
26204+ if (t == current)
26205+ mm->context.vdso_base = ~0UL;
26206 return 0;
26207 }
26208
26209diff -urNp linux-2.6.22.1/include/asm-ppc/pgtable.h linux-2.6.22.1/include/asm-ppc/pgtable.h
26210--- linux-2.6.22.1/include/asm-ppc/pgtable.h 2007-07-10 14:56:30.000000000 -0400
26211+++ linux-2.6.22.1/include/asm-ppc/pgtable.h 2007-08-02 11:38:48.000000000 -0400
26212@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
26213
26214 #define PAGE_NONE __pgprot(_PAGE_BASE)
26215 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
26216-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
26217+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
26218 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
26219-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
26220+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
26221 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
26222-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
26223+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
26224+
26225+#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
26226+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
26227+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
26228+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
26229+#else
26230+# define PAGE_SHARED_NOEXEC PAGE_SHARED
26231+# define PAGE_COPY_NOEXEC PAGE_COPY
26232+# define PAGE_READONLY_NOEXEC PAGE_READONLY
26233+#endif
26234
26235 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
26236 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
26237@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
26238 * This is the closest we can get..
26239 */
26240 #define __P000 PAGE_NONE
26241-#define __P001 PAGE_READONLY_X
26242-#define __P010 PAGE_COPY
26243-#define __P011 PAGE_COPY_X
26244-#define __P100 PAGE_READONLY
26245+#define __P001 PAGE_READONLY_NOEXEC
26246+#define __P010 PAGE_COPY_NOEXEC
26247+#define __P011 PAGE_COPY_NOEXEC
26248+#define __P100 PAGE_READONLY_X
26249 #define __P101 PAGE_READONLY_X
26250-#define __P110 PAGE_COPY
26251+#define __P110 PAGE_COPY_X
26252 #define __P111 PAGE_COPY_X
26253
26254 #define __S000 PAGE_NONE
26255-#define __S001 PAGE_READONLY_X
26256-#define __S010 PAGE_SHARED
26257-#define __S011 PAGE_SHARED_X
26258-#define __S100 PAGE_READONLY
26259+#define __S001 PAGE_READONLY_NOEXEC
26260+#define __S010 PAGE_SHARED_NOEXEC
26261+#define __S011 PAGE_SHARED_NOEXEC
26262+#define __S100 PAGE_READONLY_X
26263 #define __S101 PAGE_READONLY_X
26264-#define __S110 PAGE_SHARED
26265+#define __S110 PAGE_SHARED_X
26266 #define __S111 PAGE_SHARED_X
26267
26268 #ifndef __ASSEMBLY__
26269diff -urNp linux-2.6.22.1/include/asm-s390/kmap_types.h linux-2.6.22.1/include/asm-s390/kmap_types.h
26270--- linux-2.6.22.1/include/asm-s390/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26271+++ linux-2.6.22.1/include/asm-s390/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26272@@ -16,6 +16,7 @@ enum km_type {
26273 KM_IRQ1,
26274 KM_SOFTIRQ0,
26275 KM_SOFTIRQ1,
26276+ KM_CLEARPAGE,
26277 KM_TYPE_NR
26278 };
26279
26280diff -urNp linux-2.6.22.1/include/asm-sh/kmap_types.h linux-2.6.22.1/include/asm-sh/kmap_types.h
26281--- linux-2.6.22.1/include/asm-sh/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26282+++ linux-2.6.22.1/include/asm-sh/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26283@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
26284 D(10) KM_IRQ1,
26285 D(11) KM_SOFTIRQ0,
26286 D(12) KM_SOFTIRQ1,
26287-D(13) KM_TYPE_NR
26288+D(13) KM_CLEARPAGE,
26289+D(14) KM_TYPE_NR
26290 };
26291
26292 #undef D
26293diff -urNp linux-2.6.22.1/include/asm-sparc/a.out.h linux-2.6.22.1/include/asm-sparc/a.out.h
26294--- linux-2.6.22.1/include/asm-sparc/a.out.h 2007-07-10 14:56:30.000000000 -0400
26295+++ linux-2.6.22.1/include/asm-sparc/a.out.h 2007-08-02 11:38:48.000000000 -0400
26296@@ -91,7 +91,7 @@ struct relocation_info /* used when head
26297
26298 #include <asm/page.h>
26299
26300-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
26301+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
26302
26303 #endif /* __KERNEL__ */
26304
26305diff -urNp linux-2.6.22.1/include/asm-sparc/elf.h linux-2.6.22.1/include/asm-sparc/elf.h
26306--- linux-2.6.22.1/include/asm-sparc/elf.h 2007-07-10 14:56:30.000000000 -0400
26307+++ linux-2.6.22.1/include/asm-sparc/elf.h 2007-08-02 11:38:48.000000000 -0400
26308@@ -143,6 +143,13 @@ do { unsigned long *dest = &(__elf_regs[
26309
26310 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
26311
26312+#ifdef CONFIG_PAX_ASLR
26313+#define PAX_ELF_ET_DYN_BASE 0x10000UL
26314+
26315+#define PAX_DELTA_MMAP_LEN 16
26316+#define PAX_DELTA_STACK_LEN 16
26317+#endif
26318+
26319 /* This yields a mask that user programs can use to figure out what
26320 instruction set this cpu supports. This can NOT be done in userspace
26321 on Sparc. */
26322diff -urNp linux-2.6.22.1/include/asm-sparc/kmap_types.h linux-2.6.22.1/include/asm-sparc/kmap_types.h
26323--- linux-2.6.22.1/include/asm-sparc/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26324+++ linux-2.6.22.1/include/asm-sparc/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26325@@ -15,6 +15,7 @@ enum km_type {
26326 KM_IRQ1,
26327 KM_SOFTIRQ0,
26328 KM_SOFTIRQ1,
26329+ KM_CLEARPAGE,
26330 KM_TYPE_NR
26331 };
26332
26333diff -urNp linux-2.6.22.1/include/asm-sparc/pgtable.h linux-2.6.22.1/include/asm-sparc/pgtable.h
26334--- linux-2.6.22.1/include/asm-sparc/pgtable.h 2007-07-10 14:56:30.000000000 -0400
26335+++ linux-2.6.22.1/include/asm-sparc/pgtable.h 2007-08-02 11:38:48.000000000 -0400
26336@@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
26337 BTFIXUPDEF_INT(page_shared)
26338 BTFIXUPDEF_INT(page_copy)
26339 BTFIXUPDEF_INT(page_readonly)
26340+
26341+#ifdef CONFIG_PAX_PAGEEXEC
26342+BTFIXUPDEF_INT(page_shared_noexec)
26343+BTFIXUPDEF_INT(page_copy_noexec)
26344+BTFIXUPDEF_INT(page_readonly_noexec)
26345+#endif
26346+
26347 BTFIXUPDEF_INT(page_kernel)
26348
26349 #define PMD_SHIFT SUN4C_PMD_SHIFT
26350@@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
26351 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
26352 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
26353
26354+#ifdef CONFIG_PAX_PAGEEXEC
26355+# define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
26356+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
26357+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
26358+#else
26359+# define PAGE_SHARED_NOEXEC PAGE_SHARED
26360+# define PAGE_COPY_NOEXEC PAGE_COPY
26361+# define PAGE_READONLY_NOEXEC PAGE_READONLY
26362+#endif
26363+
26364 extern unsigned long page_kernel;
26365
26366 #ifdef MODULE
26367diff -urNp linux-2.6.22.1/include/asm-sparc/pgtsrmmu.h linux-2.6.22.1/include/asm-sparc/pgtsrmmu.h
26368--- linux-2.6.22.1/include/asm-sparc/pgtsrmmu.h 2007-07-10 14:56:30.000000000 -0400
26369+++ linux-2.6.22.1/include/asm-sparc/pgtsrmmu.h 2007-08-02 11:38:48.000000000 -0400
26370@@ -115,6 +115,16 @@
26371 SRMMU_EXEC | SRMMU_REF)
26372 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26373 SRMMU_EXEC | SRMMU_REF)
26374+
26375+#ifdef CONFIG_PAX_PAGEEXEC
26376+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26377+ SRMMU_WRITE | SRMMU_REF)
26378+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26379+ SRMMU_REF)
26380+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
26381+ SRMMU_REF)
26382+#endif
26383+
26384 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
26385 SRMMU_DIRTY | SRMMU_REF)
26386
26387diff -urNp linux-2.6.22.1/include/asm-sparc/uaccess.h linux-2.6.22.1/include/asm-sparc/uaccess.h
26388--- linux-2.6.22.1/include/asm-sparc/uaccess.h 2007-07-10 14:56:30.000000000 -0400
26389+++ linux-2.6.22.1/include/asm-sparc/uaccess.h 2007-08-02 11:38:48.000000000 -0400
26390@@ -41,7 +41,7 @@
26391 * No one can read/write anything from userland in the kernel space by setting
26392 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
26393 */
26394-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
26395+#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
26396 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
26397 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
26398 #define access_ok(type, addr, size) \
26399diff -urNp linux-2.6.22.1/include/asm-sparc64/a.out.h linux-2.6.22.1/include/asm-sparc64/a.out.h
26400--- linux-2.6.22.1/include/asm-sparc64/a.out.h 2007-07-10 14:56:30.000000000 -0400
26401+++ linux-2.6.22.1/include/asm-sparc64/a.out.h 2007-08-02 11:38:48.000000000 -0400
26402@@ -98,7 +98,7 @@ struct relocation_info /* used when head
26403 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
26404 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
26405
26406-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
26407+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
26408 STACK_TOP32 : STACK_TOP64)
26409
26410 #endif
26411diff -urNp linux-2.6.22.1/include/asm-sparc64/elf.h linux-2.6.22.1/include/asm-sparc64/elf.h
26412--- linux-2.6.22.1/include/asm-sparc64/elf.h 2007-07-10 14:56:30.000000000 -0400
26413+++ linux-2.6.22.1/include/asm-sparc64/elf.h 2007-08-02 11:38:48.000000000 -0400
26414@@ -142,6 +142,12 @@ typedef struct {
26415 #define ELF_ET_DYN_BASE 0x0000010000000000UL
26416 #endif
26417
26418+#ifdef CONFIG_PAX_ASLR
26419+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
26420+
26421+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_32BIT) ? 14 : 28 )
26422+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_32BIT) ? 15 : 29 )
26423+#endif
26424
26425 /* This yields a mask that user programs can use to figure out what
26426 instruction set this cpu supports. */
26427diff -urNp linux-2.6.22.1/include/asm-sparc64/kmap_types.h linux-2.6.22.1/include/asm-sparc64/kmap_types.h
26428--- linux-2.6.22.1/include/asm-sparc64/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26429+++ linux-2.6.22.1/include/asm-sparc64/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26430@@ -19,6 +19,7 @@ enum km_type {
26431 KM_IRQ1,
26432 KM_SOFTIRQ0,
26433 KM_SOFTIRQ1,
26434+ KM_CLEARPAGE,
26435 KM_TYPE_NR
26436 };
26437
26438diff -urNp linux-2.6.22.1/include/asm-um/kmap_types.h linux-2.6.22.1/include/asm-um/kmap_types.h
26439--- linux-2.6.22.1/include/asm-um/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26440+++ linux-2.6.22.1/include/asm-um/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26441@@ -23,6 +23,7 @@ enum km_type {
26442 KM_IRQ1,
26443 KM_SOFTIRQ0,
26444 KM_SOFTIRQ1,
26445+ KM_CLEARPAGE,
26446 KM_TYPE_NR
26447 };
26448
26449diff -urNp linux-2.6.22.1/include/asm-v850/kmap_types.h linux-2.6.22.1/include/asm-v850/kmap_types.h
26450--- linux-2.6.22.1/include/asm-v850/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26451+++ linux-2.6.22.1/include/asm-v850/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26452@@ -13,6 +13,7 @@ enum km_type {
26453 KM_PTE1,
26454 KM_IRQ0,
26455 KM_IRQ1,
26456+ KM_CLEARPAGE,
26457 KM_TYPE_NR
26458 };
26459
26460diff -urNp linux-2.6.22.1/include/asm-x86_64/a.out.h linux-2.6.22.1/include/asm-x86_64/a.out.h
26461--- linux-2.6.22.1/include/asm-x86_64/a.out.h 2007-07-10 14:56:30.000000000 -0400
26462+++ linux-2.6.22.1/include/asm-x86_64/a.out.h 2007-08-02 11:38:48.000000000 -0400
26463@@ -21,7 +21,7 @@ struct exec
26464
26465 #ifdef __KERNEL__
26466 #include <linux/thread_info.h>
26467-#define STACK_TOP TASK_SIZE
26468+#define __STACK_TOP TASK_SIZE
26469 #endif
26470
26471 #endif /* __A_OUT_GNU_H__ */
26472diff -urNp linux-2.6.22.1/include/asm-x86_64/elf.h linux-2.6.22.1/include/asm-x86_64/elf.h
26473--- linux-2.6.22.1/include/asm-x86_64/elf.h 2007-07-10 14:56:30.000000000 -0400
26474+++ linux-2.6.22.1/include/asm-x86_64/elf.h 2007-08-02 11:38:48.000000000 -0400
26475@@ -92,6 +92,13 @@ typedef struct user_i387_struct elf_fpre
26476
26477 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
26478
26479+#ifdef CONFIG_PAX_ASLR
26480+#define PAX_ELF_ET_DYN_BASE (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
26481+
26482+#define PAX_DELTA_MMAP_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
26483+#define PAX_DELTA_STACK_LEN (test_thread_flag(TIF_IA32) ? 16 : 32)
26484+#endif
26485+
26486 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
26487 now struct_user_regs, they are different). Assumes current is the process
26488 getting dumped. */
26489diff -urNp linux-2.6.22.1/include/asm-x86_64/futex.h linux-2.6.22.1/include/asm-x86_64/futex.h
26490--- linux-2.6.22.1/include/asm-x86_64/futex.h 2007-07-10 14:56:30.000000000 -0400
26491+++ linux-2.6.22.1/include/asm-x86_64/futex.h 2007-08-02 11:38:48.000000000 -0400
26492@@ -42,7 +42,7 @@
26493 : "r" (oparg), "i" (-EFAULT), "m" (*uaddr), "1" (0))
26494
26495 static inline int
26496-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26497+futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26498 {
26499 int op = (encoded_op >> 28) & 7;
26500 int cmp = (encoded_op >> 24) & 15;
26501@@ -95,7 +95,7 @@ futex_atomic_op_inuser (int encoded_op,
26502 }
26503
26504 static inline int
26505-futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26506+futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26507 {
26508 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
26509 return -EFAULT;
26510diff -urNp linux-2.6.22.1/include/asm-x86_64/ia32.h linux-2.6.22.1/include/asm-x86_64/ia32.h
26511--- linux-2.6.22.1/include/asm-x86_64/ia32.h 2007-07-10 14:56:30.000000000 -0400
26512+++ linux-2.6.22.1/include/asm-x86_64/ia32.h 2007-08-02 11:38:48.000000000 -0400
26513@@ -156,7 +156,13 @@ struct ustat32 {
26514 char f_fpack[6];
26515 };
26516
26517-#define IA32_STACK_TOP IA32_PAGE_OFFSET
26518+#ifdef CONFIG_PAX_RANDUSTACK
26519+#define IA32_DELTA_STACK (current->mm->delta_stack)
26520+#else
26521+#define IA32_DELTA_STACK 0UL
26522+#endif
26523+
26524+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
26525
26526 #ifdef __KERNEL__
26527 struct user_desc;
26528diff -urNp linux-2.6.22.1/include/asm-x86_64/kmap_types.h linux-2.6.22.1/include/asm-x86_64/kmap_types.h
26529--- linux-2.6.22.1/include/asm-x86_64/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26530+++ linux-2.6.22.1/include/asm-x86_64/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26531@@ -13,6 +13,7 @@ enum km_type {
26532 KM_IRQ1,
26533 KM_SOFTIRQ0,
26534 KM_SOFTIRQ1,
26535+ KM_CLEARPAGE,
26536 KM_TYPE_NR
26537 };
26538
26539diff -urNp linux-2.6.22.1/include/asm-x86_64/page.h linux-2.6.22.1/include/asm-x86_64/page.h
26540--- linux-2.6.22.1/include/asm-x86_64/page.h 2007-07-10 14:56:30.000000000 -0400
26541+++ linux-2.6.22.1/include/asm-x86_64/page.h 2007-08-02 11:38:48.000000000 -0400
26542@@ -93,6 +93,8 @@ extern unsigned long phys_base;
26543 #define __START_KERNEL_map _AC(0xffffffff80000000, UL)
26544 #define __PAGE_OFFSET _AC(0xffff810000000000, UL)
26545
26546+#define __KERNEL_TEXT_OFFSET (0)
26547+
26548 /* to align the pointer to the (next) page boundary */
26549 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
26550
26551diff -urNp linux-2.6.22.1/include/asm-x86_64/pgalloc.h linux-2.6.22.1/include/asm-x86_64/pgalloc.h
26552--- linux-2.6.22.1/include/asm-x86_64/pgalloc.h 2007-07-10 14:56:30.000000000 -0400
26553+++ linux-2.6.22.1/include/asm-x86_64/pgalloc.h 2007-08-02 11:38:48.000000000 -0400
26554@@ -6,7 +6,7 @@
26555 #include <linux/mm.h>
26556
26557 #define pmd_populate_kernel(mm, pmd, pte) \
26558- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
26559+ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
26560 #define pud_populate(mm, pud, pmd) \
26561 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
26562 #define pgd_populate(mm, pgd, pud) \
26563diff -urNp linux-2.6.22.1/include/asm-x86_64/pgtable.h linux-2.6.22.1/include/asm-x86_64/pgtable.h
26564--- linux-2.6.22.1/include/asm-x86_64/pgtable.h 2007-07-10 14:56:30.000000000 -0400
26565+++ linux-2.6.22.1/include/asm-x86_64/pgtable.h 2007-08-02 11:38:48.000000000 -0400
26566@@ -179,6 +179,10 @@ static inline pte_t ptep_get_and_clear_f
26567 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
26568 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
26569 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
26570+
26571+#define PAGE_READONLY_NOEXEC PAGE_READONLY
26572+#define PAGE_SHARED_NOEXEC PAGE_SHARED
26573+
26574 #define __PAGE_KERNEL \
26575 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
26576 #define __PAGE_KERNEL_EXEC \
26577@@ -268,7 +272,15 @@ static inline pte_t pfn_pte(unsigned lon
26578 #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
26579 static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
26580 static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
26581-static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); }
26582+
26583+static inline int pte_exec(pte_t pte)
26584+{
26585+ if (__supported_pte_mask & _PAGE_NX)
26586+ return !(pte_val(pte) & _PAGE_NX);
26587+ else
26588+ return (pte_val(pte) & _PAGE_USER);
26589+}
26590+
26591 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
26592 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
26593 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
26594@@ -276,12 +288,30 @@ static inline int pte_file(pte_t pte) {
26595 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; }
26596
26597 static inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
26598-static inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
26599+
26600+static inline pte_t pte_exprotect(pte_t pte)
26601+{
26602+ if (__supported_pte_mask & _PAGE_NX)
26603+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
26604+ else
26605+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
26606+ return pte;
26607+}
26608+
26609 static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
26610 static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
26611 static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
26612 static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
26613-static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; }
26614+
26615+static inline pte_t pte_mkexec(pte_t pte)
26616+{
26617+ if (__supported_pte_mask & _PAGE_NX)
26618+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
26619+ else
26620+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
26621+ return pte;
26622+}
26623+
26624 static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
26625 static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
26626 static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
26627diff -urNp linux-2.6.22.1/include/asm-x86_64/system.h linux-2.6.22.1/include/asm-x86_64/system.h
26628--- linux-2.6.22.1/include/asm-x86_64/system.h 2007-07-10 14:56:30.000000000 -0400
26629+++ linux-2.6.22.1/include/asm-x86_64/system.h 2007-08-02 11:38:48.000000000 -0400
26630@@ -159,7 +159,7 @@ static inline void sched_cacheflush(void
26631
26632 void cpu_idle_wait(void);
26633
26634-extern unsigned long arch_align_stack(unsigned long sp);
26635+#define arch_align_stack(x) (x)
26636 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
26637
26638 #endif
26639diff -urNp linux-2.6.22.1/include/asm-xtensa/kmap_types.h linux-2.6.22.1/include/asm-xtensa/kmap_types.h
26640--- linux-2.6.22.1/include/asm-xtensa/kmap_types.h 2007-07-10 14:56:30.000000000 -0400
26641+++ linux-2.6.22.1/include/asm-xtensa/kmap_types.h 2007-08-02 11:38:48.000000000 -0400
26642@@ -25,6 +25,7 @@ enum km_type {
26643 KM_IRQ1,
26644 KM_SOFTIRQ0,
26645 KM_SOFTIRQ1,
26646+ KM_CLEARPAGE,
26647 KM_TYPE_NR
26648 };
26649
26650diff -urNp linux-2.6.22.1/include/linux/a.out.h linux-2.6.22.1/include/linux/a.out.h
26651--- linux-2.6.22.1/include/linux/a.out.h 2007-07-10 14:56:30.000000000 -0400
26652+++ linux-2.6.22.1/include/linux/a.out.h 2007-08-02 11:38:48.000000000 -0400
26653@@ -7,6 +7,16 @@
26654
26655 #include <asm/a.out.h>
26656
26657+#ifdef CONFIG_PAX_RANDUSTACK
26658+#define __DELTA_STACK (current->mm->delta_stack)
26659+#else
26660+#define __DELTA_STACK 0UL
26661+#endif
26662+
26663+#ifndef STACK_TOP
26664+#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
26665+#endif
26666+
26667 #endif /* __STRUCT_EXEC_OVERRIDE__ */
26668
26669 /* these go in the N_MACHTYPE field */
26670@@ -37,6 +47,14 @@ enum machine_type {
26671 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
26672 };
26673
26674+/* Constants for the N_FLAGS field */
26675+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
26676+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
26677+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
26678+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
26679+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
26680+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
26681+
26682 #if !defined (N_MAGIC)
26683 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
26684 #endif
26685diff -urNp linux-2.6.22.1/include/linux/binfmts.h linux-2.6.22.1/include/linux/binfmts.h
26686--- linux-2.6.22.1/include/linux/binfmts.h 2007-07-10 14:56:30.000000000 -0400
26687+++ linux-2.6.22.1/include/linux/binfmts.h 2007-08-02 11:38:48.000000000 -0400
26688@@ -7,10 +7,10 @@ struct pt_regs;
26689
26690 /*
26691 * MAX_ARG_PAGES defines the number of pages allocated for arguments
26692- * and envelope for the new program. 32 should suffice, this gives
26693- * a maximum env+arg of 128kB w/4KB pages!
26694+ * and envelope for the new program. 33 should suffice, this gives
26695+ * a maximum env+arg of 132kB w/4KB pages!
26696 */
26697-#define MAX_ARG_PAGES 32
26698+#define MAX_ARG_PAGES 33
26699
26700 /* sizeof(linux_binprm->buf) */
26701 #define BINPRM_BUF_SIZE 128
26702@@ -40,6 +40,7 @@ struct linux_binprm{
26703 unsigned interp_flags;
26704 unsigned interp_data;
26705 unsigned long loader, exec;
26706+ int misc;
26707 };
26708
26709 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
26710@@ -90,5 +91,8 @@ extern void compute_creds(struct linux_b
26711 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
26712 extern int set_binfmt(struct linux_binfmt *new);
26713
26714+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
26715+void pax_report_insns(void *pc, void *sp);
26716+
26717 #endif /* __KERNEL__ */
26718 #endif /* _LINUX_BINFMTS_H */
26719diff -urNp linux-2.6.22.1/include/linux/cache.h linux-2.6.22.1/include/linux/cache.h
26720--- linux-2.6.22.1/include/linux/cache.h 2007-07-10 14:56:30.000000000 -0400
26721+++ linux-2.6.22.1/include/linux/cache.h 2007-08-02 11:38:48.000000000 -0400
26722@@ -16,6 +16,10 @@
26723 #define __read_mostly
26724 #endif
26725
26726+#ifndef __read_only
26727+#define __read_only
26728+#endif
26729+
26730 #ifndef ____cacheline_aligned
26731 #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
26732 #endif
26733diff -urNp linux-2.6.22.1/include/linux/capability.h linux-2.6.22.1/include/linux/capability.h
26734--- linux-2.6.22.1/include/linux/capability.h 2007-07-10 14:56:30.000000000 -0400
26735+++ linux-2.6.22.1/include/linux/capability.h 2007-08-02 11:09:16.000000000 -0400
26736@@ -366,6 +366,7 @@ static inline kernel_cap_t cap_invert(ke
26737 #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
26738
26739 int capable(int cap);
26740+int capable_nolog(int cap);
26741 int __capable(struct task_struct *t, int cap);
26742
26743 #endif /* __KERNEL__ */
26744diff -urNp linux-2.6.22.1/include/linux/elf.h linux-2.6.22.1/include/linux/elf.h
26745--- linux-2.6.22.1/include/linux/elf.h 2007-07-10 14:56:30.000000000 -0400
26746+++ linux-2.6.22.1/include/linux/elf.h 2007-08-02 11:38:48.000000000 -0400
26747@@ -8,6 +8,10 @@
26748
26749 struct file;
26750
26751+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
26752+#undef elf_read_implies_exec
26753+#endif
26754+
26755 #ifndef elf_read_implies_exec
26756 /* Executables for which elf_read_implies_exec() returns TRUE will
26757 have the READ_IMPLIES_EXEC personality flag set automatically.
26758@@ -49,6 +53,16 @@ typedef __s64 Elf64_Sxword;
26759
26760 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
26761
26762+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
26763+
26764+/* Constants for the e_flags field */
26765+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
26766+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
26767+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
26768+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
26769+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
26770+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
26771+
26772 /* These constants define the different elf file types */
26773 #define ET_NONE 0
26774 #define ET_REL 1
26775@@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword;
26776 #define DT_DEBUG 21
26777 #define DT_TEXTREL 22
26778 #define DT_JMPREL 23
26779+#define DT_FLAGS 30
26780+ #define DF_TEXTREL 0x00000004
26781 #define DT_ENCODING 32
26782 #define OLD_DT_LOOS 0x60000000
26783 #define DT_LOOS 0x6000000d
26784@@ -229,6 +245,19 @@ typedef struct elf64_hdr {
26785 #define PF_W 0x2
26786 #define PF_X 0x1
26787
26788+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
26789+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
26790+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
26791+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
26792+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
26793+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
26794+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
26795+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
26796+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
26797+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
26798+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
26799+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
26800+
26801 typedef struct elf32_phdr{
26802 Elf32_Word p_type;
26803 Elf32_Off p_offset;
26804@@ -321,6 +350,8 @@ typedef struct elf64_shdr {
26805 #define EI_OSABI 7
26806 #define EI_PAD 8
26807
26808+#define EI_PAX 14
26809+
26810 #define ELFMAG0 0x7f /* EI_MAG */
26811 #define ELFMAG1 'E'
26812 #define ELFMAG2 'L'
26813@@ -378,6 +409,7 @@ extern Elf32_Dyn _DYNAMIC [];
26814 #define elf_phdr elf32_phdr
26815 #define elf_note elf32_note
26816 #define elf_addr_t Elf32_Off
26817+#define elf_dyn Elf32_Dyn
26818
26819 #else
26820
26821@@ -386,6 +418,7 @@ extern Elf64_Dyn _DYNAMIC [];
26822 #define elf_phdr elf64_phdr
26823 #define elf_note elf64_note
26824 #define elf_addr_t Elf64_Off
26825+#define elf_dyn Elf64_Dyn
26826
26827 #endif
26828
26829diff -urNp linux-2.6.22.1/include/linux/ext4_fs_extents.h linux-2.6.22.1/include/linux/ext4_fs_extents.h
26830--- linux-2.6.22.1/include/linux/ext4_fs_extents.h 2007-07-10 14:56:30.000000000 -0400
26831+++ linux-2.6.22.1/include/linux/ext4_fs_extents.h 2007-08-02 11:38:48.000000000 -0400
26832@@ -50,7 +50,7 @@
26833 #ifdef EXT_DEBUG
26834 #define ext_debug(a...) printk(a)
26835 #else
26836-#define ext_debug(a...)
26837+#define ext_debug(a...) do {} while (0)
26838 #endif
26839
26840 /*
26841diff -urNp linux-2.6.22.1/include/linux/gracl.h linux-2.6.22.1/include/linux/gracl.h
26842--- linux-2.6.22.1/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
26843+++ linux-2.6.22.1/include/linux/gracl.h 2007-08-02 12:25:41.000000000 -0400
26844@@ -0,0 +1,316 @@
26845+#ifndef GR_ACL_H
26846+#define GR_ACL_H
26847+
26848+#include <linux/grdefs.h>
26849+#include <linux/resource.h>
26850+#include <linux/dcache.h>
26851+#include <asm/resource.h>
26852+
26853+/* Major status information */
26854+
26855+#define GR_VERSION "grsecurity 2.1.11"
26856+#define GRSECURITY_VERSION 0x2111
26857+
26858+enum {
26859+
26860+ SHUTDOWN = 0,
26861+ ENABLE = 1,
26862+ SPROLE = 2,
26863+ RELOAD = 3,
26864+ SEGVMOD = 4,
26865+ STATUS = 5,
26866+ UNSPROLE = 6,
26867+ PASSSET = 7,
26868+ SPROLEPAM = 8
26869+};
26870+
26871+/* Password setup definitions
26872+ * kernel/grhash.c */
26873+enum {
26874+ GR_PW_LEN = 128,
26875+ GR_SALT_LEN = 16,
26876+ GR_SHA_LEN = 32,
26877+};
26878+
26879+enum {
26880+ GR_SPROLE_LEN = 64,
26881+};
26882+
26883+#define GR_NLIMITS (RLIMIT_LOCKS + 2)
26884+
26885+/* Begin Data Structures */
26886+
26887+struct sprole_pw {
26888+ unsigned char *rolename;
26889+ unsigned char salt[GR_SALT_LEN];
26890+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
26891+};
26892+
26893+struct name_entry {
26894+ __u32 key;
26895+ ino_t inode;
26896+ dev_t device;
26897+ char *name;
26898+ __u16 len;
26899+ struct name_entry *prev;
26900+ struct name_entry *next;
26901+};
26902+
26903+struct inodev_entry {
26904+ struct name_entry *nentry;
26905+ struct inodev_entry *prev;
26906+ struct inodev_entry *next;
26907+};
26908+
26909+struct acl_role_db {
26910+ struct acl_role_label **r_hash;
26911+ __u32 r_size;
26912+};
26913+
26914+struct inodev_db {
26915+ struct inodev_entry **i_hash;
26916+ __u32 i_size;
26917+};
26918+
26919+struct name_db {
26920+ struct name_entry **n_hash;
26921+ __u32 n_size;
26922+};
26923+
26924+struct crash_uid {
26925+ uid_t uid;
26926+ unsigned long expires;
26927+};
26928+
26929+struct gr_hash_struct {
26930+ void **table;
26931+ void **nametable;
26932+ void *first;
26933+ __u32 table_size;
26934+ __u32 used_size;
26935+ int type;
26936+};
26937+
26938+/* Userspace Grsecurity ACL data structures */
26939+
26940+struct acl_subject_label {
26941+ char *filename;
26942+ ino_t inode;
26943+ dev_t device;
26944+ __u32 mode;
26945+ __u32 cap_mask;
26946+ __u32 cap_lower;
26947+
26948+ struct rlimit res[GR_NLIMITS];
26949+ __u16 resmask;
26950+
26951+ __u8 user_trans_type;
26952+ __u8 group_trans_type;
26953+ uid_t *user_transitions;
26954+ gid_t *group_transitions;
26955+ __u16 user_trans_num;
26956+ __u16 group_trans_num;
26957+
26958+ __u32 ip_proto[8];
26959+ __u32 ip_type;
26960+ struct acl_ip_label **ips;
26961+ __u32 ip_num;
26962+
26963+ __u32 crashes;
26964+ unsigned long expires;
26965+
26966+ struct acl_subject_label *parent_subject;
26967+ struct gr_hash_struct *hash;
26968+ struct acl_subject_label *prev;
26969+ struct acl_subject_label *next;
26970+
26971+ struct acl_object_label **obj_hash;
26972+ __u32 obj_hash_size;
26973+ __u16 pax_flags;
26974+};
26975+
26976+struct role_allowed_ip {
26977+ __u32 addr;
26978+ __u32 netmask;
26979+
26980+ struct role_allowed_ip *prev;
26981+ struct role_allowed_ip *next;
26982+};
26983+
26984+struct role_transition {
26985+ char *rolename;
26986+
26987+ struct role_transition *prev;
26988+ struct role_transition *next;
26989+};
26990+
26991+struct acl_role_label {
26992+ char *rolename;
26993+ uid_t uidgid;
26994+ __u16 roletype;
26995+
26996+ __u16 auth_attempts;
26997+ unsigned long expires;
26998+
26999+ struct acl_subject_label *root_label;
27000+ struct gr_hash_struct *hash;
27001+
27002+ struct acl_role_label *prev;
27003+ struct acl_role_label *next;
27004+
27005+ struct role_transition *transitions;
27006+ struct role_allowed_ip *allowed_ips;
27007+ uid_t *domain_children;
27008+ __u16 domain_child_num;
27009+
27010+ struct acl_subject_label **subj_hash;
27011+ __u32 subj_hash_size;
27012+};
27013+
27014+struct user_acl_role_db {
27015+ struct acl_role_label **r_table;
27016+ __u32 num_pointers; /* Number of allocations to track */
27017+ __u32 num_roles; /* Number of roles */
27018+ __u32 num_domain_children; /* Number of domain children */
27019+ __u32 num_subjects; /* Number of subjects */
27020+ __u32 num_objects; /* Number of objects */
27021+};
27022+
27023+struct acl_object_label {
27024+ char *filename;
27025+ ino_t inode;
27026+ dev_t device;
27027+ __u32 mode;
27028+
27029+ struct acl_subject_label *nested;
27030+ struct acl_object_label *globbed;
27031+
27032+ /* next two structures not used */
27033+
27034+ struct acl_object_label *prev;
27035+ struct acl_object_label *next;
27036+};
27037+
27038+struct acl_ip_label {
27039+ char *iface;
27040+ __u32 addr;
27041+ __u32 netmask;
27042+ __u16 low, high;
27043+ __u8 mode;
27044+ __u32 type;
27045+ __u32 proto[8];
27046+
27047+ /* next two structures not used */
27048+
27049+ struct acl_ip_label *prev;
27050+ struct acl_ip_label *next;
27051+};
27052+
27053+struct gr_arg {
27054+ struct user_acl_role_db role_db;
27055+ unsigned char pw[GR_PW_LEN];
27056+ unsigned char salt[GR_SALT_LEN];
27057+ unsigned char sum[GR_SHA_LEN];
27058+ unsigned char sp_role[GR_SPROLE_LEN];
27059+ struct sprole_pw *sprole_pws;
27060+ dev_t segv_device;
27061+ ino_t segv_inode;
27062+ uid_t segv_uid;
27063+ __u16 num_sprole_pws;
27064+ __u16 mode;
27065+};
27066+
27067+struct gr_arg_wrapper {
27068+ struct gr_arg *arg;
27069+ __u32 version;
27070+ __u32 size;
27071+};
27072+
27073+struct subject_map {
27074+ struct acl_subject_label *user;
27075+ struct acl_subject_label *kernel;
27076+ struct subject_map *prev;
27077+ struct subject_map *next;
27078+};
27079+
27080+struct acl_subj_map_db {
27081+ struct subject_map **s_hash;
27082+ __u32 s_size;
27083+};
27084+
27085+/* End Data Structures Section */
27086+
27087+/* Hash functions generated by empirical testing by Brad Spengler
27088+ Makes good use of the low bits of the inode. Generally 0-1 times
27089+ in loop for successful match. 0-3 for unsuccessful match.
27090+ Shift/add algorithm with modulus of table size and an XOR*/
27091+
27092+static __inline__ unsigned int
27093+rhash(const uid_t uid, const __u16 type, const unsigned int sz)
27094+{
27095+ return (((uid << type) + (uid ^ type)) % sz);
27096+}
27097+
27098+ static __inline__ unsigned int
27099+shash(const struct acl_subject_label *userp, const unsigned int sz)
27100+{
27101+ return ((const unsigned long)userp % sz);
27102+}
27103+
27104+static __inline__ unsigned int
27105+fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
27106+{
27107+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
27108+}
27109+
27110+static __inline__ unsigned int
27111+nhash(const char *name, const __u16 len, const unsigned int sz)
27112+{
27113+ return full_name_hash(name, len) % sz;
27114+}
27115+
27116+#define FOR_EACH_ROLE_START(role,iter) \
27117+ role = NULL; \
27118+ iter = 0; \
27119+ while (iter < acl_role_set.r_size) { \
27120+ if (role == NULL) \
27121+ role = acl_role_set.r_hash[iter]; \
27122+ if (role == NULL) { \
27123+ iter++; \
27124+ continue; \
27125+ }
27126+
27127+#define FOR_EACH_ROLE_END(role,iter) \
27128+ role = role->next; \
27129+ if (role == NULL) \
27130+ iter++; \
27131+ }
27132+
27133+#define FOR_EACH_SUBJECT_START(role,subj,iter) \
27134+ subj = NULL; \
27135+ iter = 0; \
27136+ while (iter < role->subj_hash_size) { \
27137+ if (subj == NULL) \
27138+ subj = role->subj_hash[iter]; \
27139+ if (subj == NULL) { \
27140+ iter++; \
27141+ continue; \
27142+ }
27143+
27144+#define FOR_EACH_SUBJECT_END(subj,iter) \
27145+ subj = subj->next; \
27146+ if (subj == NULL) \
27147+ iter++; \
27148+ }
27149+
27150+
27151+#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
27152+ subj = role->hash->first; \
27153+ while (subj != NULL) {
27154+
27155+#define FOR_EACH_NESTED_SUBJECT_END(subj) \
27156+ subj = subj->next; \
27157+ }
27158+
27159+#endif
27160+
27161diff -urNp linux-2.6.22.1/include/linux/gralloc.h linux-2.6.22.1/include/linux/gralloc.h
27162--- linux-2.6.22.1/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
27163+++ linux-2.6.22.1/include/linux/gralloc.h 2007-08-02 11:09:16.000000000 -0400
27164@@ -0,0 +1,8 @@
27165+#ifndef __GRALLOC_H
27166+#define __GRALLOC_H
27167+
27168+void acl_free_all(void);
27169+int acl_alloc_stack_init(unsigned long size);
27170+void *acl_alloc(unsigned long len);
27171+
27172+#endif
27173diff -urNp linux-2.6.22.1/include/linux/grdefs.h linux-2.6.22.1/include/linux/grdefs.h
27174--- linux-2.6.22.1/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
27175+++ linux-2.6.22.1/include/linux/grdefs.h 2007-08-02 11:09:16.000000000 -0400
27176@@ -0,0 +1,131 @@
27177+#ifndef GRDEFS_H
27178+#define GRDEFS_H
27179+
27180+/* Begin grsecurity status declarations */
27181+
27182+enum {
27183+ GR_READY = 0x01,
27184+ GR_STATUS_INIT = 0x00 // disabled state
27185+};
27186+
27187+/* Begin ACL declarations */
27188+
27189+/* Role flags */
27190+
27191+enum {
27192+ GR_ROLE_USER = 0x0001,
27193+ GR_ROLE_GROUP = 0x0002,
27194+ GR_ROLE_DEFAULT = 0x0004,
27195+ GR_ROLE_SPECIAL = 0x0008,
27196+ GR_ROLE_AUTH = 0x0010,
27197+ GR_ROLE_NOPW = 0x0020,
27198+ GR_ROLE_GOD = 0x0040,
27199+ GR_ROLE_LEARN = 0x0080,
27200+ GR_ROLE_TPE = 0x0100,
27201+ GR_ROLE_DOMAIN = 0x0200,
27202+ GR_ROLE_PAM = 0x0400
27203+};
27204+
27205+/* ACL Subject and Object mode flags */
27206+enum {
27207+ GR_DELETED = 0x80000000
27208+};
27209+
27210+/* ACL Object-only mode flags */
27211+enum {
27212+ GR_READ = 0x00000001,
27213+ GR_APPEND = 0x00000002,
27214+ GR_WRITE = 0x00000004,
27215+ GR_EXEC = 0x00000008,
27216+ GR_FIND = 0x00000010,
27217+ GR_INHERIT = 0x00000020,
27218+ GR_SETID = 0x00000040,
27219+ GR_CREATE = 0x00000080,
27220+ GR_DELETE = 0x00000100,
27221+ GR_LINK = 0x00000200,
27222+ GR_AUDIT_READ = 0x00000400,
27223+ GR_AUDIT_APPEND = 0x00000800,
27224+ GR_AUDIT_WRITE = 0x00001000,
27225+ GR_AUDIT_EXEC = 0x00002000,
27226+ GR_AUDIT_FIND = 0x00004000,
27227+ GR_AUDIT_INHERIT= 0x00008000,
27228+ GR_AUDIT_SETID = 0x00010000,
27229+ GR_AUDIT_CREATE = 0x00020000,
27230+ GR_AUDIT_DELETE = 0x00040000,
27231+ GR_AUDIT_LINK = 0x00080000,
27232+ GR_PTRACERD = 0x00100000,
27233+ GR_NOPTRACE = 0x00200000,
27234+ GR_SUPPRESS = 0x00400000,
27235+ GR_NOLEARN = 0x00800000
27236+};
27237+
27238+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
27239+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
27240+ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
27241+
27242+/* ACL subject-only mode flags */
27243+enum {
27244+ GR_KILL = 0x00000001,
27245+ GR_VIEW = 0x00000002,
27246+ GR_PROTECTED = 0x00000004,
27247+ GR_LEARN = 0x00000008,
27248+ GR_OVERRIDE = 0x00000010,
27249+ /* just a placeholder, this mode is only used in userspace */
27250+ GR_DUMMY = 0x00000020,
27251+ GR_PROTSHM = 0x00000040,
27252+ GR_KILLPROC = 0x00000080,
27253+ GR_KILLIPPROC = 0x00000100,
27254+ /* just a placeholder, this mode is only used in userspace */
27255+ GR_NOTROJAN = 0x00000200,
27256+ GR_PROTPROCFD = 0x00000400,
27257+ GR_PROCACCT = 0x00000800,
27258+ GR_RELAXPTRACE = 0x00001000,
27259+ GR_NESTED = 0x00002000,
27260+ GR_INHERITLEARN = 0x00004000,
27261+ GR_PROCFIND = 0x00008000,
27262+ GR_POVERRIDE = 0x00010000,
27263+ GR_KERNELAUTH = 0x00020000,
27264+};
27265+
27266+enum {
27267+ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
27268+ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
27269+ GR_PAX_ENABLE_MPROTECT = 0x0004,
27270+ GR_PAX_ENABLE_RANDMMAP = 0x0008,
27271+ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
27272+ GR_PAX_DISABLE_SEGMEXEC = 0x0100,
27273+ GR_PAX_DISABLE_PAGEEXEC = 0x0200,
27274+ GR_PAX_DISABLE_MPROTECT = 0x0400,
27275+ GR_PAX_DISABLE_RANDMMAP = 0x0800,
27276+ GR_PAX_DISABLE_EMUTRAMP = 0x1000,
27277+};
27278+
27279+enum {
27280+ GR_ID_USER = 0x01,
27281+ GR_ID_GROUP = 0x02,
27282+};
27283+
27284+enum {
27285+ GR_ID_ALLOW = 0x01,
27286+ GR_ID_DENY = 0x02,
27287+};
27288+
27289+#define GR_CRASH_RES 11
27290+#define GR_UIDTABLE_MAX 500
27291+
27292+/* begin resource learning section */
27293+enum {
27294+ GR_RLIM_CPU_BUMP = 60,
27295+ GR_RLIM_FSIZE_BUMP = 50000,
27296+ GR_RLIM_DATA_BUMP = 10000,
27297+ GR_RLIM_STACK_BUMP = 1000,
27298+ GR_RLIM_CORE_BUMP = 10000,
27299+ GR_RLIM_RSS_BUMP = 500000,
27300+ GR_RLIM_NPROC_BUMP = 1,
27301+ GR_RLIM_NOFILE_BUMP = 5,
27302+ GR_RLIM_MEMLOCK_BUMP = 50000,
27303+ GR_RLIM_AS_BUMP = 500000,
27304+ GR_RLIM_LOCKS_BUMP = 2
27305+};
27306+
27307+#endif
27308diff -urNp linux-2.6.22.1/include/linux/grinternal.h linux-2.6.22.1/include/linux/grinternal.h
27309--- linux-2.6.22.1/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
27310+++ linux-2.6.22.1/include/linux/grinternal.h 2007-08-02 11:09:16.000000000 -0400
27311@@ -0,0 +1,210 @@
27312+#ifndef __GRINTERNAL_H
27313+#define __GRINTERNAL_H
27314+
27315+#ifdef CONFIG_GRKERNSEC
27316+
27317+#include <linux/fs.h>
27318+#include <linux/gracl.h>
27319+#include <linux/grdefs.h>
27320+#include <linux/grmsg.h>
27321+
27322+void gr_add_learn_entry(const char *fmt, ...);
27323+__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
27324+ const struct vfsmount *mnt);
27325+__u32 gr_check_create(const struct dentry *new_dentry,
27326+ const struct dentry *parent,
27327+ const struct vfsmount *mnt, const __u32 mode);
27328+int gr_check_protected_task(const struct task_struct *task);
27329+__u32 to_gr_audit(const __u32 reqmode);
27330+int gr_set_acls(const int type);
27331+
27332+int gr_acl_is_enabled(void);
27333+char gr_roletype_to_char(void);
27334+
27335+void gr_handle_alertkill(struct task_struct *task);
27336+char *gr_to_filename(const struct dentry *dentry,
27337+ const struct vfsmount *mnt);
27338+char *gr_to_filename1(const struct dentry *dentry,
27339+ const struct vfsmount *mnt);
27340+char *gr_to_filename2(const struct dentry *dentry,
27341+ const struct vfsmount *mnt);
27342+char *gr_to_filename3(const struct dentry *dentry,
27343+ const struct vfsmount *mnt);
27344+
27345+extern int grsec_enable_link;
27346+extern int grsec_enable_fifo;
27347+extern int grsec_enable_execve;
27348+extern int grsec_enable_shm;
27349+extern int grsec_enable_execlog;
27350+extern int grsec_enable_signal;
27351+extern int grsec_enable_forkfail;
27352+extern int grsec_enable_time;
27353+extern int grsec_enable_chroot_shmat;
27354+extern int grsec_enable_chroot_findtask;
27355+extern int grsec_enable_chroot_mount;
27356+extern int grsec_enable_chroot_double;
27357+extern int grsec_enable_chroot_pivot;
27358+extern int grsec_enable_chroot_chdir;
27359+extern int grsec_enable_chroot_chmod;
27360+extern int grsec_enable_chroot_mknod;
27361+extern int grsec_enable_chroot_fchdir;
27362+extern int grsec_enable_chroot_nice;
27363+extern int grsec_enable_chroot_execlog;
27364+extern int grsec_enable_chroot_caps;
27365+extern int grsec_enable_chroot_sysctl;
27366+extern int grsec_enable_chroot_unix;
27367+extern int grsec_enable_tpe;
27368+extern int grsec_tpe_gid;
27369+extern int grsec_enable_tpe_all;
27370+extern int grsec_enable_sidcaps;
27371+extern int grsec_enable_socket_all;
27372+extern int grsec_socket_all_gid;
27373+extern int grsec_enable_socket_client;
27374+extern int grsec_socket_client_gid;
27375+extern int grsec_enable_socket_server;
27376+extern int grsec_socket_server_gid;
27377+extern int grsec_audit_gid;
27378+extern int grsec_enable_group;
27379+extern int grsec_enable_audit_ipc;
27380+extern int grsec_enable_audit_textrel;
27381+extern int grsec_enable_mount;
27382+extern int grsec_enable_chdir;
27383+extern int grsec_resource_logging;
27384+extern int grsec_lock;
27385+
27386+extern spinlock_t grsec_alert_lock;
27387+extern unsigned long grsec_alert_wtime;
27388+extern unsigned long grsec_alert_fyet;
27389+
27390+extern spinlock_t grsec_audit_lock;
27391+
27392+extern rwlock_t grsec_exec_file_lock;
27393+
27394+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
27395+ gr_to_filename2(tsk->exec_file->f_dentry, \
27396+ tsk->exec_file->f_vfsmnt) : "/")
27397+
27398+#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
27399+ gr_to_filename3(tsk->parent->exec_file->f_dentry, \
27400+ tsk->parent->exec_file->f_vfsmnt) : "/")
27401+
27402+#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
27403+ gr_to_filename(tsk->exec_file->f_dentry, \
27404+ tsk->exec_file->f_vfsmnt) : "/")
27405+
27406+#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
27407+ gr_to_filename1(tsk->parent->exec_file->f_dentry, \
27408+ tsk->parent->exec_file->f_vfsmnt) : "/")
27409+
27410+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
27411+ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
27412+ child_reaper(tsk_a)->fs->root->d_inode->i_sb->s_dev) || \
27413+ (tsk_a->fs->root->d_inode->i_ino != \
27414+ child_reaper(tsk_a)->fs->root->d_inode->i_ino)))
27415+
27416+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
27417+ (tsk_a->fs->root->d_inode->i_sb->s_dev == \
27418+ tsk_b->fs->root->d_inode->i_sb->s_dev) && \
27419+ (tsk_a->fs->root->d_inode->i_ino == \
27420+ tsk_b->fs->root->d_inode->i_ino))
27421+
27422+#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
27423+ task->pid, task->uid, \
27424+ task->euid, task->gid, task->egid, \
27425+ gr_parent_task_fullpath(task), \
27426+ task->parent->comm, task->parent->pid, \
27427+ task->parent->uid, task->parent->euid, \
27428+ task->parent->gid, task->parent->egid
27429+
27430+#define GR_CHROOT_CAPS ( \
27431+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
27432+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
27433+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
27434+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
27435+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
27436+ CAP_TO_MASK(CAP_IPC_OWNER))
27437+
27438+#define security_learn(normal_msg,args...) \
27439+({ \
27440+ read_lock(&grsec_exec_file_lock); \
27441+ gr_add_learn_entry(normal_msg "\n", ## args); \
27442+ read_unlock(&grsec_exec_file_lock); \
27443+})
27444+
27445+enum {
27446+ GR_DO_AUDIT,
27447+ GR_DONT_AUDIT,
27448+ GR_DONT_AUDIT_GOOD
27449+};
27450+
27451+enum {
27452+ GR_TTYSNIFF,
27453+ GR_RBAC,
27454+ GR_RBAC_STR,
27455+ GR_STR_RBAC,
27456+ GR_RBAC_MODE2,
27457+ GR_RBAC_MODE3,
27458+ GR_FILENAME,
27459+ GR_SYSCTL_HIDDEN,
27460+ GR_NOARGS,
27461+ GR_ONE_INT,
27462+ GR_ONE_INT_TWO_STR,
27463+ GR_ONE_STR,
27464+ GR_STR_INT,
27465+ GR_TWO_INT,
27466+ GR_THREE_INT,
27467+ GR_FIVE_INT_TWO_STR,
27468+ GR_TWO_STR,
27469+ GR_THREE_STR,
27470+ GR_FOUR_STR,
27471+ GR_STR_FILENAME,
27472+ GR_FILENAME_STR,
27473+ GR_FILENAME_TWO_INT,
27474+ GR_FILENAME_TWO_INT_STR,
27475+ GR_TEXTREL,
27476+ GR_PTRACE,
27477+ GR_RESOURCE,
27478+ GR_CAP,
27479+ GR_SIG,
27480+ GR_CRASH1,
27481+ GR_CRASH2,
27482+ GR_PSACCT
27483+};
27484+
27485+#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
27486+#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
27487+#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
27488+#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
27489+#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
27490+#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
27491+#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)
27492+#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
27493+#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
27494+#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
27495+#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
27496+#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
27497+#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
27498+#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
27499+#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
27500+#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)
27501+#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
27502+#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
27503+#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
27504+#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
27505+#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
27506+#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
27507+#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)
27508+#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
27509+#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
27510+#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
27511+#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
27512+#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
27513+#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
27514+#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
27515+#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)
27516+
27517+void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
27518+
27519+#endif
27520+
27521+#endif
27522diff -urNp linux-2.6.22.1/include/linux/grmsg.h linux-2.6.22.1/include/linux/grmsg.h
27523--- linux-2.6.22.1/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
27524+++ linux-2.6.22.1/include/linux/grmsg.h 2007-08-02 11:09:16.000000000 -0400
27525@@ -0,0 +1,108 @@
27526+#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"
27527+#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"
27528+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
27529+#define GR_STOPMOD_MSG "denied modification of module state by "
27530+#define GR_IOPERM_MSG "denied use of ioperm() by "
27531+#define GR_IOPL_MSG "denied use of iopl() by "
27532+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
27533+#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
27534+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
27535+#define GR_KMEM_MSG "denied write of /dev/kmem by "
27536+#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
27537+#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
27538+#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
27539+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
27540+#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"
27541+#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"
27542+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
27543+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
27544+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
27545+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
27546+#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
27547+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
27548+#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
27549+#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
27550+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
27551+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
27552+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
27553+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
27554+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
27555+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
27556+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
27557+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
27558+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
27559+#define GR_NPROC_MSG "denied overstep of process limit by "
27560+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
27561+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
27562+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
27563+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
27564+#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
27565+#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
27566+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
27567+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
27568+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
27569+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
27570+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
27571+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
27572+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
27573+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
27574+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
27575+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
27576+#define GR_INITF_ACL_MSG "init_variables() failed %s by "
27577+#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"
27578+#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
27579+#define GR_SHUTS_ACL_MSG "shutdown auth success for "
27580+#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
27581+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
27582+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
27583+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
27584+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
27585+#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
27586+#define GR_ENABLEF_ACL_MSG "unable to load %s for "
27587+#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
27588+#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
27589+#define GR_RELOADF_ACL_MSG "failed reload of %s for "
27590+#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
27591+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
27592+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
27593+#define GR_SPROLEF_ACL_MSG "special role %s failure for "
27594+#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
27595+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
27596+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
27597+#define GR_INVMODE_ACL_MSG "invalid mode %d by "
27598+#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
27599+#define GR_FAILFORK_MSG "failed fork with errno %d by "
27600+#define GR_NICE_CHROOT_MSG "denied priority change by "
27601+#define GR_UNISIGLOG_MSG "signal %d sent to "
27602+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
27603+#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
27604+#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
27605+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
27606+#define GR_TIME_MSG "time set by "
27607+#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
27608+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
27609+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
27610+#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
27611+#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
27612+#define GR_BIND_MSG "denied bind() by "
27613+#define GR_CONNECT_MSG "denied connect() by "
27614+#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
27615+#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
27616+#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"
27617+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
27618+#define GR_CAP_ACL_MSG "use of %s denied for "
27619+#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
27620+#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
27621+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
27622+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
27623+#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
27624+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
27625+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
27626+#define GR_MSGQ_AUDIT_MSG "message queue created by "
27627+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
27628+#define GR_SEM_AUDIT_MSG "semaphore created by "
27629+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
27630+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
27631+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
27632+#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
27633+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
27634diff -urNp linux-2.6.22.1/include/linux/grsecurity.h linux-2.6.22.1/include/linux/grsecurity.h
27635--- linux-2.6.22.1/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
27636+++ linux-2.6.22.1/include/linux/grsecurity.h 2007-08-02 12:19:12.000000000 -0400
27637@@ -0,0 +1,193 @@
27638+#ifndef GR_SECURITY_H
27639+#define GR_SECURITY_H
27640+#include <linux/fs.h>
27641+#include <linux/binfmts.h>
27642+#include <linux/gracl.h>
27643+
27644+void gr_handle_brute_attach(struct task_struct *p);
27645+void gr_handle_brute_check(void);
27646+
27647+char gr_roletype_to_char(void);
27648+
27649+int gr_check_user_change(int real, int effective, int fs);
27650+int gr_check_group_change(int real, int effective, int fs);
27651+
27652+void gr_del_task_from_ip_table(struct task_struct *p);
27653+
27654+int gr_pid_is_chrooted(struct task_struct *p);
27655+int gr_handle_chroot_nice(void);
27656+int gr_handle_chroot_sysctl(const int op);
27657+int gr_handle_chroot_setpriority(struct task_struct *p,
27658+ const int niceval);
27659+int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
27660+int gr_handle_chroot_chroot(const struct dentry *dentry,
27661+ const struct vfsmount *mnt);
27662+void gr_handle_chroot_caps(struct task_struct *task);
27663+void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
27664+int gr_handle_chroot_chmod(const struct dentry *dentry,
27665+ const struct vfsmount *mnt, const int mode);
27666+int gr_handle_chroot_mknod(const struct dentry *dentry,
27667+ const struct vfsmount *mnt, const int mode);
27668+int gr_handle_chroot_mount(const struct dentry *dentry,
27669+ const struct vfsmount *mnt,
27670+ const char *dev_name);
27671+int gr_handle_chroot_pivot(void);
27672+int gr_handle_chroot_unix(const pid_t pid);
27673+
27674+int gr_handle_rawio(const struct inode *inode);
27675+int gr_handle_nproc(void);
27676+
27677+void gr_handle_ioperm(void);
27678+void gr_handle_iopl(void);
27679+
27680+int gr_tpe_allow(const struct file *file);
27681+
27682+int gr_random_pid(void);
27683+
27684+void gr_log_forkfail(const int retval);
27685+void gr_log_timechange(void);
27686+void gr_log_signal(const int sig, const struct task_struct *t);
27687+void gr_log_chdir(const struct dentry *dentry,
27688+ const struct vfsmount *mnt);
27689+void gr_log_chroot_exec(const struct dentry *dentry,
27690+ const struct vfsmount *mnt);
27691+void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
27692+void gr_log_remount(const char *devname, const int retval);
27693+void gr_log_unmount(const char *devname, const int retval);
27694+void gr_log_mount(const char *from, const char *to, const int retval);
27695+void gr_log_msgget(const int ret, const int msgflg);
27696+void gr_log_msgrm(const uid_t uid, const uid_t cuid);
27697+void gr_log_semget(const int err, const int semflg);
27698+void gr_log_semrm(const uid_t uid, const uid_t cuid);
27699+void gr_log_shmget(const int err, const int shmflg, const size_t size);
27700+void gr_log_shmrm(const uid_t uid, const uid_t cuid);
27701+void gr_log_textrel(struct vm_area_struct *vma);
27702+
27703+int gr_handle_follow_link(const struct inode *parent,
27704+ const struct inode *inode,
27705+ const struct dentry *dentry,
27706+ const struct vfsmount *mnt);
27707+int gr_handle_fifo(const struct dentry *dentry,
27708+ const struct vfsmount *mnt,
27709+ const struct dentry *dir, const int flag,
27710+ const int acc_mode);
27711+int gr_handle_hardlink(const struct dentry *dentry,
27712+ const struct vfsmount *mnt,
27713+ struct inode *inode,
27714+ const int mode, const char *to);
27715+
27716+int gr_task_is_capable(struct task_struct *task, const int cap);
27717+int gr_is_capable_nolog(const int cap);
27718+void gr_learn_resource(const struct task_struct *task, const int limit,
27719+ const unsigned long wanted, const int gt);
27720+void gr_copy_label(struct task_struct *tsk);
27721+void gr_handle_crash(struct task_struct *task, const int sig);
27722+int gr_handle_signal(const struct task_struct *p, const int sig);
27723+int gr_check_crash_uid(const uid_t uid);
27724+int gr_check_protected_task(const struct task_struct *task);
27725+int gr_acl_handle_mmap(const struct file *file,
27726+ const unsigned long prot);
27727+int gr_acl_handle_mprotect(const struct file *file,
27728+ const unsigned long prot);
27729+int gr_check_hidden_task(const struct task_struct *tsk);
27730+__u32 gr_acl_handle_truncate(const struct dentry *dentry,
27731+ const struct vfsmount *mnt);
27732+__u32 gr_acl_handle_utime(const struct dentry *dentry,
27733+ const struct vfsmount *mnt);
27734+__u32 gr_acl_handle_access(const struct dentry *dentry,
27735+ const struct vfsmount *mnt, const int fmode);
27736+__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
27737+ const struct vfsmount *mnt, mode_t mode);
27738+__u32 gr_acl_handle_chmod(const struct dentry *dentry,
27739+ const struct vfsmount *mnt, mode_t mode);
27740+__u32 gr_acl_handle_chown(const struct dentry *dentry,
27741+ const struct vfsmount *mnt);
27742+int gr_handle_ptrace(struct task_struct *task, const long request);
27743+int gr_handle_proc_ptrace(struct task_struct *task);
27744+__u32 gr_acl_handle_execve(const struct dentry *dentry,
27745+ const struct vfsmount *mnt);
27746+int gr_check_crash_exec(const struct file *filp);
27747+int gr_acl_is_enabled(void);
27748+void gr_set_kernel_label(struct task_struct *task);
27749+void gr_set_role_label(struct task_struct *task, const uid_t uid,
27750+ const gid_t gid);
27751+int gr_set_proc_label(const struct dentry *dentry,
27752+ const struct vfsmount *mnt);
27753+__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
27754+ const struct vfsmount *mnt);
27755+__u32 gr_acl_handle_open(const struct dentry *dentry,
27756+ const struct vfsmount *mnt, const int fmode);
27757+__u32 gr_acl_handle_creat(const struct dentry *dentry,
27758+ const struct dentry *p_dentry,
27759+ const struct vfsmount *p_mnt, const int fmode,
27760+ const int imode);
27761+void gr_handle_create(const struct dentry *dentry,
27762+ const struct vfsmount *mnt);
27763+__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
27764+ const struct dentry *parent_dentry,
27765+ const struct vfsmount *parent_mnt,
27766+ const int mode);
27767+__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
27768+ const struct dentry *parent_dentry,
27769+ const struct vfsmount *parent_mnt);
27770+__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
27771+ const struct vfsmount *mnt);
27772+void gr_handle_delete(const ino_t ino, const dev_t dev);
27773+__u32 gr_acl_handle_unlink(const struct dentry *dentry,
27774+ const struct vfsmount *mnt);
27775+__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
27776+ const struct dentry *parent_dentry,
27777+ const struct vfsmount *parent_mnt,
27778+ const char *from);
27779+__u32 gr_acl_handle_link(const struct dentry *new_dentry,
27780+ const struct dentry *parent_dentry,
27781+ const struct vfsmount *parent_mnt,
27782+ const struct dentry *old_dentry,
27783+ const struct vfsmount *old_mnt, const char *to);
27784+int gr_acl_handle_rename(struct dentry *new_dentry,
27785+ struct dentry *parent_dentry,
27786+ const struct vfsmount *parent_mnt,
27787+ struct dentry *old_dentry,
27788+ struct inode *old_parent_inode,
27789+ struct vfsmount *old_mnt, const char *newname);
27790+void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
27791+ struct dentry *old_dentry,
27792+ struct dentry *new_dentry,
27793+ struct vfsmount *mnt, const __u8 replace);
27794+__u32 gr_check_link(const struct dentry *new_dentry,
27795+ const struct dentry *parent_dentry,
27796+ const struct vfsmount *parent_mnt,
27797+ const struct dentry *old_dentry,
27798+ const struct vfsmount *old_mnt);
27799+int gr_acl_handle_filldir(const struct file *file, const char *name,
27800+ const unsigned int namelen, const ino_t ino);
27801+
27802+__u32 gr_acl_handle_unix(const struct dentry *dentry,
27803+ const struct vfsmount *mnt);
27804+void gr_acl_handle_exit(void);
27805+void gr_acl_handle_psacct(struct task_struct *task, const long code);
27806+int gr_acl_handle_procpidmem(const struct task_struct *task);
27807+__u32 gr_cap_rtnetlink(void);
27808+
27809+#ifdef CONFIG_SYSVIPC
27810+void gr_shm_exit(struct task_struct *task);
27811+#else
27812+static inline void gr_shm_exit(struct task_struct *task)
27813+{
27814+ return;
27815+}
27816+#endif
27817+
27818+#ifdef CONFIG_GRKERNSEC
27819+void gr_handle_mem_write(void);
27820+void gr_handle_kmem_write(void);
27821+void gr_handle_open_port(void);
27822+int gr_handle_mem_mmap(const unsigned long offset,
27823+ struct vm_area_struct *vma);
27824+
27825+extern int grsec_enable_dmesg;
27826+extern int grsec_enable_randsrc;
27827+extern int grsec_enable_shm;
27828+#endif
27829+
27830+#endif
27831diff -urNp linux-2.6.22.1/include/linux/highmem.h linux-2.6.22.1/include/linux/highmem.h
27832--- linux-2.6.22.1/include/linux/highmem.h 2007-07-10 14:56:30.000000000 -0400
27833+++ linux-2.6.22.1/include/linux/highmem.h 2007-08-02 11:38:48.000000000 -0400
27834@@ -92,6 +92,13 @@ static inline void clear_highpage(struct
27835 kunmap_atomic(kaddr, KM_USER0);
27836 }
27837
27838+static inline void sanitize_highpage(struct page *page)
27839+{
27840+ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
27841+ clear_page(kaddr);
27842+ kunmap_atomic(kaddr, KM_CLEARPAGE);
27843+}
27844+
27845 /*
27846 * Same but also flushes aliased cache contents to RAM.
27847 *
27848@@ -100,14 +107,14 @@ static inline void clear_highpage(struct
27849 */
27850 #define zero_user_page(page, offset, size, km_type) \
27851 do { \
27852- void *kaddr; \
27853+ void *__kaddr; \
27854 \
27855 BUG_ON((offset) + (size) > PAGE_SIZE); \
27856 \
27857- kaddr = kmap_atomic(page, km_type); \
27858- memset((char *)kaddr + (offset), 0, (size)); \
27859+ __kaddr = kmap_atomic(page, km_type); \
27860+ memset((char *)__kaddr + (offset), 0, (size)); \
27861 flush_dcache_page(page); \
27862- kunmap_atomic(kaddr, (km_type)); \
27863+ kunmap_atomic(__kaddr, (km_type)); \
27864 } while (0)
27865
27866 static inline void __deprecated memclear_highpage_flush(struct page *page,
27867diff -urNp linux-2.6.22.1/include/linux/irqflags.h linux-2.6.22.1/include/linux/irqflags.h
27868--- linux-2.6.22.1/include/linux/irqflags.h 2007-07-10 14:56:30.000000000 -0400
27869+++ linux-2.6.22.1/include/linux/irqflags.h 2007-08-02 11:38:48.000000000 -0400
27870@@ -84,10 +84,10 @@
27871
27872 #define irqs_disabled() \
27873 ({ \
27874- unsigned long flags; \
27875+ unsigned long __flags; \
27876 \
27877- raw_local_save_flags(flags); \
27878- raw_irqs_disabled_flags(flags); \
27879+ raw_local_save_flags(__flags); \
27880+ raw_irqs_disabled_flags(__flags); \
27881 })
27882
27883 #define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
27884diff -urNp linux-2.6.22.1/include/linux/jbd2.h linux-2.6.22.1/include/linux/jbd2.h
27885--- linux-2.6.22.1/include/linux/jbd2.h 2007-07-10 14:56:30.000000000 -0400
27886+++ linux-2.6.22.1/include/linux/jbd2.h 2007-08-02 11:38:48.000000000 -0400
27887@@ -68,7 +68,7 @@ extern int jbd2_journal_enable_debug;
27888 } \
27889 } while (0)
27890 #else
27891-#define jbd_debug(f, a...) /**/
27892+#define jbd_debug(f, a...) do {} while (0)
27893 #endif
27894
27895 extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
27896diff -urNp linux-2.6.22.1/include/linux/jbd.h linux-2.6.22.1/include/linux/jbd.h
27897--- linux-2.6.22.1/include/linux/jbd.h 2007-07-10 14:56:30.000000000 -0400
27898+++ linux-2.6.22.1/include/linux/jbd.h 2007-08-02 11:38:48.000000000 -0400
27899@@ -68,7 +68,7 @@ extern int journal_enable_debug;
27900 } \
27901 } while (0)
27902 #else
27903-#define jbd_debug(f, a...) /**/
27904+#define jbd_debug(f, a...) do {} while (0)
27905 #endif
27906
27907 extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
27908diff -urNp linux-2.6.22.1/include/linux/libata.h linux-2.6.22.1/include/linux/libata.h
27909--- linux-2.6.22.1/include/linux/libata.h 2007-07-10 14:56:30.000000000 -0400
27910+++ linux-2.6.22.1/include/linux/libata.h 2007-08-02 11:38:48.000000000 -0400
27911@@ -63,11 +63,11 @@
27912 #ifdef ATA_VERBOSE_DEBUG
27913 #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
27914 #else
27915-#define VPRINTK(fmt, args...)
27916+#define VPRINTK(fmt, args...) do {} while (0)
27917 #endif /* ATA_VERBOSE_DEBUG */
27918 #else
27919-#define DPRINTK(fmt, args...)
27920-#define VPRINTK(fmt, args...)
27921+#define DPRINTK(fmt, args...) do {} while (0)
27922+#define VPRINTK(fmt, args...) do {} while (0)
27923 #endif /* ATA_DEBUG */
27924
27925 #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
27926diff -urNp linux-2.6.22.1/include/linux/mm.h linux-2.6.22.1/include/linux/mm.h
27927--- linux-2.6.22.1/include/linux/mm.h 2007-07-10 14:56:30.000000000 -0400
27928+++ linux-2.6.22.1/include/linux/mm.h 2007-08-02 11:38:48.000000000 -0400
27929@@ -39,6 +39,7 @@ extern int sysctl_legacy_va_layout;
27930 #include <asm/page.h>
27931 #include <asm/pgtable.h>
27932 #include <asm/processor.h>
27933+#include <asm/mman.h>
27934
27935 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
27936
27937@@ -112,6 +113,8 @@ struct vm_area_struct {
27938 #ifdef CONFIG_NUMA
27939 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
27940 #endif
27941+
27942+ struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
27943 };
27944
27945 extern struct kmem_cache *vm_area_cachep;
27946@@ -170,6 +173,14 @@ extern unsigned int kobjsize(const void
27947 #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
27948 #define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */
27949
27950+#ifdef CONFIG_PAX_PAGEEXEC
27951+#define VM_PAGEEXEC 0x08000000 /* vma->vm_page_prot needs special handling */
27952+#endif
27953+
27954+#ifdef CONFIG_PAX_MPROTECT
27955+#define VM_MAYNOTWRITE 0x10000000 /* vma cannot be granted VM_WRITE any more */
27956+#endif
27957+
27958 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
27959 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
27960 #endif
27961@@ -790,7 +805,7 @@ static inline int handle_mm_fault(struct
27962
27963 extern int make_pages_present(unsigned long addr, unsigned long end);
27964 extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
27965-void install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
27966+int install_arg_page(struct vm_area_struct *, struct page *, unsigned long);
27967
27968 int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start,
27969 int len, int write, int force, struct page **pages, struct vm_area_struct **vmas);
27970@@ -834,6 +849,8 @@ struct shrinker;
27971 extern struct shrinker *set_shrinker(int, shrinker_t);
27972 extern void remove_shrinker(struct shrinker *shrinker);
27973
27974+pgprot_t vm_get_page_prot(unsigned long vm_flags);
27975+
27976 /*
27977 * Some shared mappigns will want the pages marked read-only
27978 * to track write events. If so, we'll downgrade vm_page_prot
27979@@ -842,10 +859,10 @@ extern void remove_shrinker(struct shrin
27980 */
27981 static inline int vma_wants_writenotify(struct vm_area_struct *vma)
27982 {
27983- unsigned int vm_flags = vma->vm_flags;
27984+ unsigned long vm_flags = vma->vm_flags;
27985
27986 /* If it was private or non-writable, the write bit is already clear */
27987- if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
27988+ if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
27989 return 0;
27990
27991 /* The backer wishes to know when pages are first written to? */
27992@@ -854,8 +871,7 @@ static inline int vma_wants_writenotify(
27993
27994 /* The open routine did something to the protections already? */
27995 if (pgprot_val(vma->vm_page_prot) !=
27996- pgprot_val(protection_map[vm_flags &
27997- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]))
27998+ pgprot_val(vm_get_page_prot(vm_flags)))
27999 return 0;
28000
28001 /* Specialty mapping? */
28002@@ -1087,6 +1103,7 @@ out:
28003 }
28004
28005 extern int do_munmap(struct mm_struct *, unsigned long, size_t);
28006+extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
28007
28008 extern unsigned long do_brk(unsigned long, unsigned long);
28009
28010@@ -1134,6 +1151,10 @@ extern struct vm_area_struct * find_vma(
28011 extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
28012 struct vm_area_struct **pprev);
28013
28014+extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
28015+extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
28016+extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
28017+
28018 /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
28019 NULL if none. Assume start_addr < end_addr. */
28020 static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
28021@@ -1150,8 +1171,6 @@ static inline unsigned long vma_pages(st
28022 return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
28023 }
28024
28025-pgprot_t vm_get_page_prot(unsigned long vm_flags);
28026-struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
28027 struct page *vmalloc_to_page(void *addr);
28028 unsigned long vmalloc_to_pfn(void *addr);
28029 int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
28030@@ -1210,5 +1229,11 @@ extern int randomize_va_space;
28031
28032 __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma);
28033
28034+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
28035+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
28036+#else
28037+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
28038+#endif
28039+
28040 #endif /* __KERNEL__ */
28041 #endif /* _LINUX_MM_H */
28042diff -urNp linux-2.6.22.1/include/linux/module.h linux-2.6.22.1/include/linux/module.h
28043--- linux-2.6.22.1/include/linux/module.h 2007-07-10 14:56:30.000000000 -0400
28044+++ linux-2.6.22.1/include/linux/module.h 2007-08-02 11:38:48.000000000 -0400
28045@@ -296,16 +296,16 @@ struct module
28046 int (*init)(void);
28047
28048 /* If this is non-NULL, vfree after init() returns */
28049- void *module_init;
28050+ void *module_init_rx, *module_init_rw;
28051
28052 /* Here is the actual code + data, vfree'd on unload. */
28053- void *module_core;
28054+ void *module_core_rx, *module_core_rw;
28055
28056 /* Here are the sizes of the init and core sections */
28057- unsigned long init_size, core_size;
28058+ unsigned long init_size_rw, core_size_rw;
28059
28060 /* The size of the executable code in each section. */
28061- unsigned long init_text_size, core_text_size;
28062+ unsigned long init_size_rx, core_size_rx;
28063
28064 /* The handle returned from unwind_add_table. */
28065 void *unwind_info;
28066diff -urNp linux-2.6.22.1/include/linux/moduleloader.h linux-2.6.22.1/include/linux/moduleloader.h
28067--- linux-2.6.22.1/include/linux/moduleloader.h 2007-07-10 14:56:30.000000000 -0400
28068+++ linux-2.6.22.1/include/linux/moduleloader.h 2007-08-02 11:38:48.000000000 -0400
28069@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
28070 sections. Returns NULL on failure. */
28071 void *module_alloc(unsigned long size);
28072
28073+#ifdef CONFIG_PAX_KERNEXEC
28074+void *module_alloc_exec(unsigned long size);
28075+#else
28076+#define module_alloc_exec(x) module_alloc(x)
28077+#endif
28078+
28079 /* Free memory returned from module_alloc. */
28080 void module_free(struct module *mod, void *module_region);
28081
28082+#ifdef CONFIG_PAX_KERNEXEC
28083+void module_free_exec(struct module *mod, void *module_region);
28084+#else
28085+#define module_free_exec(x, y) module_free(x, y)
28086+#endif
28087+
28088 /* Apply the given relocation to the (simplified) ELF. Return -error
28089 or 0. */
28090 int apply_relocate(Elf_Shdr *sechdrs,
28091diff -urNp linux-2.6.22.1/include/linux/percpu.h linux-2.6.22.1/include/linux/percpu.h
28092--- linux-2.6.22.1/include/linux/percpu.h 2007-07-10 14:56:30.000000000 -0400
28093+++ linux-2.6.22.1/include/linux/percpu.h 2007-08-02 11:38:48.000000000 -0400
28094@@ -18,7 +18,7 @@
28095 #endif
28096
28097 #define PERCPU_ENOUGH_ROOM \
28098- (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
28099+ ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
28100 #endif /* PERCPU_ENOUGH_ROOM */
28101
28102 /*
28103diff -urNp linux-2.6.22.1/include/linux/random.h linux-2.6.22.1/include/linux/random.h
28104--- linux-2.6.22.1/include/linux/random.h 2007-07-10 14:56:30.000000000 -0400
28105+++ linux-2.6.22.1/include/linux/random.h 2007-08-02 11:38:48.000000000 -0400
28106@@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
28107 u32 random32(void);
28108 void srandom32(u32 seed);
28109
28110+static inline unsigned long pax_get_random_long(void)
28111+{
28112+ return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
28113+}
28114+
28115 #endif /* __KERNEL___ */
28116
28117 #endif /* _LINUX_RANDOM_H */
28118diff -urNp linux-2.6.22.1/include/linux/sched.h linux-2.6.22.1/include/linux/sched.h
28119--- linux-2.6.22.1/include/linux/sched.h 2007-07-10 14:56:30.000000000 -0400
28120+++ linux-2.6.22.1/include/linux/sched.h 2007-08-02 11:38:48.000000000 -0400
28121@@ -89,6 +89,7 @@ struct sched_param {
28122 struct exec_domain;
28123 struct futex_pi_state;
28124 struct bio;
28125+struct linux_binprm;
28126
28127 /*
28128 * List of flags we want to share for kernel threads,
28129@@ -386,6 +387,24 @@ struct mm_struct {
28130 /* aio bits */
28131 rwlock_t ioctx_list_lock;
28132 struct kioctx *ioctx_list;
28133+
28134+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
28135+ unsigned long pax_flags;
28136+#endif
28137+
28138+#ifdef CONFIG_PAX_DLRESOLVE
28139+ unsigned long call_dl_resolve;
28140+#endif
28141+
28142+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
28143+ unsigned long call_syscall;
28144+#endif
28145+
28146+#ifdef CONFIG_PAX_ASLR
28147+ unsigned long delta_mmap; /* randomized offset */
28148+ unsigned long delta_stack; /* randomized offset */
28149+#endif
28150+
28151 };
28152
28153 struct sighand_struct {
28154@@ -506,6 +525,15 @@ struct signal_struct {
28155 #ifdef CONFIG_TASKSTATS
28156 struct taskstats *stats;
28157 #endif
28158+
28159+#ifdef CONFIG_GRKERNSEC
28160+ u32 curr_ip;
28161+ u32 gr_saddr;
28162+ u32 gr_daddr;
28163+ u16 gr_sport;
28164+ u16 gr_dport;
28165+ u8 used_accept:1;
28166+#endif
28167 };
28168
28169 /* Context switch must be unlocked if interrupts are to be enabled */
28170@@ -899,8 +927,8 @@ struct task_struct {
28171 struct list_head thread_group;
28172
28173 struct completion *vfork_done; /* for vfork() */
28174- int __user *set_child_tid; /* CLONE_CHILD_SETTID */
28175- int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
28176+ pid_t __user *set_child_tid; /* CLONE_CHILD_SETTID */
28177+ pid_t __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
28178
28179 unsigned int rt_priority;
28180 cputime_t utime, stime;
28181@@ -1063,6 +1091,17 @@ struct task_struct {
28182 struct list_head pi_state_list;
28183 struct futex_pi_state *pi_state_cache;
28184
28185+#ifdef CONFIG_GRKERNSEC
28186+ /* grsecurity */
28187+ struct acl_subject_label *acl;
28188+ struct acl_role_label *role;
28189+ struct file *exec_file;
28190+ u16 acl_role_id;
28191+ u8 acl_sp_role:1;
28192+ u8 is_writable:1;
28193+ u8 brute:1;
28194+#endif
28195+
28196 atomic_t fs_excl; /* holding fs exclusive resources */
28197 struct rcu_head rcu;
28198
28199@@ -1078,6 +1117,46 @@ struct task_struct {
28200 #endif
28201 };
28202
28203+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
28204+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
28205+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
28206+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
28207+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
28208+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
28209+
28210+#ifdef CONFIG_PAX_SOFTMODE
28211+extern unsigned int pax_softmode;
28212+#endif
28213+
28214+extern int pax_check_flags(unsigned long *);
28215+
28216+/* if tsk != current then task_lock must be held on it */
28217+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
28218+static inline unsigned long pax_get_flags(struct task_struct *tsk)
28219+{
28220+ if (likely(tsk->mm))
28221+ return tsk->mm->pax_flags;
28222+ else
28223+ return 0UL;
28224+}
28225+
28226+/* if tsk != current then task_lock must be held on it */
28227+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
28228+{
28229+ if (likely(tsk->mm)) {
28230+ tsk->mm->pax_flags = flags;
28231+ return 0;
28232+ }
28233+ return -EINVAL;
28234+}
28235+#endif
28236+
28237+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
28238+extern void pax_set_initial_flags(struct linux_binprm *bprm);
28239+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
28240+extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
28241+#endif
28242+
28243 static inline pid_t process_group(struct task_struct *tsk)
28244 {
28245 return tsk->signal->pgrp;
28246@@ -1662,6 +1741,12 @@ extern void arch_pick_mmap_layout(struct
28247 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
28248 {
28249 mm->mmap_base = TASK_UNMAPPED_BASE;
28250+
28251+#ifdef CONFIG_PAX_RANDMMAP
28252+ if (mm->pax_flags & MF_PAX_RANDMMAP)
28253+ mm->mmap_base += mm->delta_mmap;
28254+#endif
28255+
28256 mm->get_unmapped_area = arch_get_unmapped_area;
28257 mm->unmap_area = arch_unmap_area;
28258 }
28259diff -urNp linux-2.6.22/include/linux/screen_info.h linux-2.6.22/include/linux/screen_info.h
28260--- linux-2.6.22/include/linux/screen_info.h 2007-07-10 14:56:30.000000000 -0400
28261+++ linux-2.6.22/include/linux/screen_info.h 2007-07-10 14:56:30.000000000 -0400
28262@@ -42,9 +42,9 @@ struct screen_info {
28263 u16 pages; /* 0x32 */
28264 u16 vesa_attributes; /* 0x34 */
28265 u32 capabilities; /* 0x36 */
28266- /* 0x3a -- 0x3b reserved for future expansion */
28267- /* 0x3c -- 0x3f micro stack for relocatable kernels */
28268-};
28269+ u16 vesapm_size; /* 0x3a -- 0x3b reserved for future expansion */
28270+ u8 _reserved[4]; /* 0x3c -- 0x3f micro stack for relocatable kernels */
28271+} __attribute__((packed));
28272
28273 extern struct screen_info screen_info;
28274
28275diff -urNp linux-2.6.22.1/include/linux/security.h linux-2.6.22.1/include/linux/security.h
28276--- linux-2.6.22.1/include/linux/security.h 2007-07-10 14:56:30.000000000 -0400
28277+++ linux-2.6.22.1/include/linux/security.h 2007-08-02 11:38:48.000000000 -0400
28278@@ -2779,7 +2779,7 @@ static inline struct dentry *securityfs_
28279 mode_t mode,
28280 struct dentry *parent,
28281 void *data,
28282- struct file_operations *fops)
28283+ const struct file_operations *fops)
28284 {
28285 return ERR_PTR(-ENODEV);
28286 }
28287diff -urNp linux-2.6.22.1/include/linux/shm.h linux-2.6.22.1/include/linux/shm.h
28288--- linux-2.6.22.1/include/linux/shm.h 2007-07-10 14:56:30.000000000 -0400
28289+++ linux-2.6.22.1/include/linux/shm.h 2007-08-02 11:09:16.000000000 -0400
28290@@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
28291 pid_t shm_cprid;
28292 pid_t shm_lprid;
28293 struct user_struct *mlock_user;
28294+#ifdef CONFIG_GRKERNSEC
28295+ time_t shm_createtime;
28296+ pid_t shm_lapid;
28297+#endif
28298 };
28299
28300 /* shm_mode upper byte flags */
28301diff -urNp linux-2.6.22.1/include/linux/skbuff.h linux-2.6.22.1/include/linux/skbuff.h
28302--- linux-2.6.22.1/include/linux/skbuff.h 2007-07-10 14:56:30.000000000 -0400
28303+++ linux-2.6.22.1/include/linux/skbuff.h 2007-08-02 11:38:48.000000000 -0400
28304@@ -369,7 +369,7 @@ extern void skb_truesize_bug(struc
28305
28306 static inline void skb_truesize_check(struct sk_buff *skb)
28307 {
28308- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
28309+ if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
28310 skb_truesize_bug(skb);
28311 }
28312
28313diff -urNp linux-2.6.22.1/include/linux/sysctl.h linux-2.6.22.1/include/linux/sysctl.h
28314--- linux-2.6.22.1/include/linux/sysctl.h 2007-07-10 14:56:30.000000000 -0400
28315+++ linux-2.6.22.1/include/linux/sysctl.h 2007-08-02 11:47:35.000000000 -0400
28316@@ -165,9 +165,21 @@ enum
28317 KERN_MAX_LOCK_DEPTH=74,
28318 KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
28319 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
28320-};
28321+#ifdef CONFIG_GRKERNSEC
28322+ KERN_GRSECURITY=98, /* grsecurity */
28323+#endif
28324+
28325+#ifdef CONFIG_PAX_SOFTMODE
28326+ KERN_PAX=99, /* PaX control */
28327+#endif
28328
28329+};
28330
28331+#ifdef CONFIG_PAX_SOFTMODE
28332+enum {
28333+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
28334+};
28335+#endif
28336
28337 /* CTL_VM names: */
28338 enum
28339diff -urNp linux-2.6.22.1/include/linux/uaccess.h linux-2.6.22.1/include/linux/uaccess.h
28340--- linux-2.6.22.1/include/linux/uaccess.h 2007-07-10 14:56:30.000000000 -0400
28341+++ linux-2.6.22.1/include/linux/uaccess.h 2007-08-02 11:38:48.000000000 -0400
28342@@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
28343 long ret; \
28344 mm_segment_t old_fs = get_fs(); \
28345 \
28346- set_fs(KERNEL_DS); \
28347 pagefault_disable(); \
28348+ set_fs(KERNEL_DS); \
28349 ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \
28350- pagefault_enable(); \
28351 set_fs(old_fs); \
28352+ pagefault_enable(); \
28353 ret; \
28354 })
28355
28356diff -urNp linux-2.6.22.1/include/linux/udf_fs.h linux-2.6.22.1/include/linux/udf_fs.h
28357--- linux-2.6.22.1/include/linux/udf_fs.h 2007-07-10 14:56:30.000000000 -0400
28358+++ linux-2.6.22.1/include/linux/udf_fs.h 2007-08-02 11:38:48.000000000 -0400
28359@@ -45,7 +45,7 @@
28360 printk (f, ##a); \
28361 }
28362 #else
28363-#define udf_debug(f, a...) /**/
28364+#define udf_debug(f, a...) do {} while (0)
28365 #endif
28366
28367 #define udf_info(f, a...) \
28368diff -urNp linux-2.6.22.1/include/net/sctp/sctp.h linux-2.6.22.1/include/net/sctp/sctp.h
28369--- linux-2.6.22.1/include/net/sctp/sctp.h 2007-07-10 14:56:30.000000000 -0400
28370+++ linux-2.6.22.1/include/net/sctp/sctp.h 2007-08-02 11:38:48.000000000 -0400
28371@@ -306,8 +306,8 @@ extern int sctp_debug_flag;
28372
28373 #else /* SCTP_DEBUG */
28374
28375-#define SCTP_DEBUG_PRINTK(whatever...)
28376-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
28377+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
28378+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
28379 #define SCTP_ENABLE_DEBUG
28380 #define SCTP_DISABLE_DEBUG
28381 #define SCTP_ASSERT(expr, str, func)
28382diff -urNp linux-2.6.22.1/include/sound/core.h linux-2.6.22.1/include/sound/core.h
28383--- linux-2.6.22.1/include/sound/core.h 2007-07-10 14:56:30.000000000 -0400
28384+++ linux-2.6.22.1/include/sound/core.h 2007-08-02 11:38:48.000000000 -0400
28385@@ -396,9 +396,9 @@ void snd_verbose_printd(const char *file
28386
28387 #else /* !CONFIG_SND_DEBUG */
28388
28389-#define snd_printd(fmt, args...) /* nothing */
28390+#define snd_printd(fmt, args...) do {} while (0)
28391 #define snd_assert(expr, args...) (void)(expr)
28392-#define snd_BUG() /* nothing */
28393+#define snd_BUG() do {} while (0)
28394
28395 #endif /* CONFIG_SND_DEBUG */
28396
28397@@ -412,7 +412,7 @@ void snd_verbose_printd(const char *file
28398 */
28399 #define snd_printdd(format, args...) snd_printk(format, ##args)
28400 #else
28401-#define snd_printdd(format, args...) /* nothing */
28402+#define snd_printdd(format, args...) do {} while (0)
28403 #endif
28404
28405
28406diff -urNp linux-2.6.22.1/init/do_mounts.c linux-2.6.22.1/init/do_mounts.c
28407--- linux-2.6.22.1/init/do_mounts.c 2007-07-10 14:56:30.000000000 -0400
28408+++ linux-2.6.22.1/init/do_mounts.c 2007-08-02 11:38:48.000000000 -0400
28409@@ -67,11 +67,12 @@ static dev_t try_name(char *name, int pa
28410
28411 /* read device number from .../dev */
28412
28413- sprintf(path, "/sys/block/%s/dev", name);
28414- fd = sys_open(path, 0, 0);
28415+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
28416+ goto fail;
28417+ fd = sys_open((char __user *)path, 0, 0);
28418 if (fd < 0)
28419 goto fail;
28420- len = sys_read(fd, buf, 32);
28421+ len = sys_read(fd, (char __user *)buf, 32);
28422 sys_close(fd);
28423 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
28424 goto fail;
28425@@ -97,11 +98,12 @@ static dev_t try_name(char *name, int pa
28426 return res;
28427
28428 /* otherwise read range from .../range */
28429- sprintf(path, "/sys/block/%s/range", name);
28430- fd = sys_open(path, 0, 0);
28431+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
28432+ goto fail;
28433+ fd = sys_open((char __user *)path, 0, 0);
28434 if (fd < 0)
28435 goto fail;
28436- len = sys_read(fd, buf, 32);
28437+ len = sys_read(fd, (char __user *)buf, 32);
28438 sys_close(fd);
28439 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
28440 goto fail;
28441@@ -144,12 +146,12 @@ dev_t name_to_dev_t(char *name)
28442 int part, mount_result;
28443
28444 #ifdef CONFIG_SYSFS
28445- int mkdir_err = sys_mkdir("/sys", 0700);
28446+ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
28447 /*
28448 * When changing resume2 parameter for Software Suspend, sysfs may
28449 * already be mounted.
28450 */
28451- mount_result = sys_mount("sysfs", "/sys", "sysfs", 0, NULL);
28452+ mount_result = sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL);
28453 if (mount_result < 0 && mount_result != -EBUSY)
28454 goto out;
28455 #endif
28456@@ -203,10 +205,10 @@ dev_t name_to_dev_t(char *name)
28457 done:
28458 #ifdef CONFIG_SYSFS
28459 if (mount_result >= 0)
28460- sys_umount("/sys", 0);
28461+ sys_umount((char __user *)"/sys", 0);
28462 out:
28463 if (!mkdir_err)
28464- sys_rmdir("/sys");
28465+ sys_rmdir((char __user *)"/sys");
28466 #endif
28467 return res;
28468 fail:
28469@@ -276,11 +278,11 @@ static void __init get_fs_names(char *pa
28470
28471 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
28472 {
28473- int err = sys_mount(name, "/root", fs, flags, data);
28474+ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
28475 if (err)
28476 return err;
28477
28478- sys_chdir("/root");
28479+ sys_chdir((char __user *)"/root");
28480 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
28481 printk("VFS: Mounted root (%s filesystem)%s.\n",
28482 current->fs->pwdmnt->mnt_sb->s_type->name,
28483@@ -366,18 +368,18 @@ void __init change_floppy(char *fmt, ...
28484 va_start(args, fmt);
28485 vsprintf(buf, fmt, args);
28486 va_end(args);
28487- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
28488+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
28489 if (fd >= 0) {
28490 sys_ioctl(fd, FDEJECT, 0);
28491 sys_close(fd);
28492 }
28493 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
28494- fd = sys_open("/dev/console", O_RDWR, 0);
28495+ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
28496 if (fd >= 0) {
28497 sys_ioctl(fd, TCGETS, (long)&termios);
28498 termios.c_lflag &= ~ICANON;
28499 sys_ioctl(fd, TCSETSF, (long)&termios);
28500- sys_read(fd, &c, 1);
28501+ sys_read(fd, (char __user *)&c, 1);
28502 termios.c_lflag |= ICANON;
28503 sys_ioctl(fd, TCSETSF, (long)&termios);
28504 sys_close(fd);
28505@@ -469,8 +471,8 @@ void __init prepare_namespace(void)
28506
28507 mount_root();
28508 out:
28509- sys_mount(".", "/", NULL, MS_MOVE, NULL);
28510- sys_chroot(".");
28511+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
28512+ sys_chroot((char __user *)".");
28513 security_sb_post_mountroot();
28514 }
28515
28516diff -urNp linux-2.6.22.1/init/do_mounts.h linux-2.6.22.1/init/do_mounts.h
28517--- linux-2.6.22.1/init/do_mounts.h 2007-07-10 14:56:30.000000000 -0400
28518+++ linux-2.6.22.1/init/do_mounts.h 2007-08-02 11:38:48.000000000 -0400
28519@@ -15,15 +15,15 @@ extern char *root_device_name;
28520
28521 static inline int create_dev(char *name, dev_t dev)
28522 {
28523- sys_unlink(name);
28524- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
28525+ sys_unlink((char __user *)name);
28526+ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
28527 }
28528
28529 #if BITS_PER_LONG == 32
28530 static inline u32 bstat(char *name)
28531 {
28532 struct stat64 stat;
28533- if (sys_stat64(name, &stat) != 0)
28534+ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
28535 return 0;
28536 if (!S_ISBLK(stat.st_mode))
28537 return 0;
28538diff -urNp linux-2.6.22.1/init/do_mounts_md.c linux-2.6.22.1/init/do_mounts_md.c
28539--- linux-2.6.22.1/init/do_mounts_md.c 2007-07-10 14:56:30.000000000 -0400
28540+++ linux-2.6.22.1/init/do_mounts_md.c 2007-08-02 11:38:48.000000000 -0400
28541@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
28542 partitioned ? "_d" : "", minor,
28543 md_setup_args[ent].device_names);
28544
28545- fd = sys_open(name, 0, 0);
28546+ fd = sys_open((char __user *)name, 0, 0);
28547 if (fd < 0) {
28548 printk(KERN_ERR "md: open failed - cannot start "
28549 "array %s\n", name);
28550@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
28551 * array without it
28552 */
28553 sys_close(fd);
28554- fd = sys_open(name, 0, 0);
28555+ fd = sys_open((char __user *)name, 0, 0);
28556 sys_ioctl(fd, BLKRRPART, 0);
28557 }
28558 sys_close(fd);
28559@@ -271,7 +271,7 @@ void __init md_run_setup(void)
28560 if (raid_noautodetect)
28561 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
28562 else {
28563- int fd = sys_open("/dev/md0", 0, 0);
28564+ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
28565 if (fd >= 0) {
28566 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
28567 sys_close(fd);
28568diff -urNp linux-2.6.22.1/init/initramfs.c linux-2.6.22.1/init/initramfs.c
28569--- linux-2.6.22.1/init/initramfs.c 2007-07-10 14:56:30.000000000 -0400
28570+++ linux-2.6.22.1/init/initramfs.c 2007-08-02 11:38:48.000000000 -0400
28571@@ -240,7 +240,7 @@ static int __init maybe_link(void)
28572 if (nlink >= 2) {
28573 char *old = find_link(major, minor, ino, mode, collected);
28574 if (old)
28575- return (sys_link(old, collected) < 0) ? -1 : 1;
28576+ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
28577 }
28578 return 0;
28579 }
28580@@ -249,11 +249,11 @@ static void __init clean_path(char *path
28581 {
28582 struct stat st;
28583
28584- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
28585+ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
28586 if (S_ISDIR(st.st_mode))
28587- sys_rmdir(path);
28588+ sys_rmdir((char __user *)path);
28589 else
28590- sys_unlink(path);
28591+ sys_unlink((char __user *)path);
28592 }
28593 }
28594
28595@@ -276,7 +276,7 @@ static int __init do_name(void)
28596 int openflags = O_WRONLY|O_CREAT;
28597 if (ml != 1)
28598 openflags |= O_TRUNC;
28599- wfd = sys_open(collected, openflags, mode);
28600+ wfd = sys_open((char __user *)collected, openflags, mode);
28601
28602 if (wfd >= 0) {
28603 sys_fchown(wfd, uid, gid);
28604@@ -285,15 +285,15 @@ static int __init do_name(void)
28605 }
28606 }
28607 } else if (S_ISDIR(mode)) {
28608- sys_mkdir(collected, mode);
28609- sys_chown(collected, uid, gid);
28610- sys_chmod(collected, mode);
28611+ sys_mkdir((char __user *)collected, mode);
28612+ sys_chown((char __user *)collected, uid, gid);
28613+ sys_chmod((char __user *)collected, mode);
28614 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
28615 S_ISFIFO(mode) || S_ISSOCK(mode)) {
28616 if (maybe_link() == 0) {
28617- sys_mknod(collected, mode, rdev);
28618- sys_chown(collected, uid, gid);
28619- sys_chmod(collected, mode);
28620+ sys_mknod((char __user *)collected, mode, rdev);
28621+ sys_chown((char __user *)collected, uid, gid);
28622+ sys_chmod((char __user *)collected, mode);
28623 }
28624 }
28625 return 0;
28626@@ -302,13 +302,13 @@ static int __init do_name(void)
28627 static int __init do_copy(void)
28628 {
28629 if (count >= body_len) {
28630- sys_write(wfd, victim, body_len);
28631+ sys_write(wfd, (char __user *)victim, body_len);
28632 sys_close(wfd);
28633 eat(body_len);
28634 state = SkipIt;
28635 return 0;
28636 } else {
28637- sys_write(wfd, victim, count);
28638+ sys_write(wfd, (char __user *)victim, count);
28639 body_len -= count;
28640 eat(count);
28641 return 1;
28642@@ -319,8 +319,8 @@ static int __init do_symlink(void)
28643 {
28644 collected[N_ALIGN(name_len) + body_len] = '\0';
28645 clean_path(collected, 0);
28646- sys_symlink(collected + N_ALIGN(name_len), collected);
28647- sys_lchown(collected, uid, gid);
28648+ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
28649+ sys_lchown((char __user *)collected, uid, gid);
28650 state = SkipIt;
28651 next_state = Reset;
28652 return 0;
28653diff -urNp linux-2.6.22.1/init/Kconfig linux-2.6.22.1/init/Kconfig
28654--- linux-2.6.22.1/init/Kconfig 2007-07-10 14:56:30.000000000 -0400
28655+++ linux-2.6.22.1/init/Kconfig 2007-08-02 11:09:16.000000000 -0400
28656@@ -395,6 +395,7 @@ config SYSCTL_SYSCALL
28657 config KALLSYMS
28658 bool "Load all symbols for debugging/ksymoops" if EMBEDDED
28659 default y
28660+ depends on !GRKERNSEC_HIDESYM
28661 help
28662 Say Y here to let the kernel print out symbolic crash information and
28663 symbolic stack backtraces. This increases the size of the kernel
28664diff -urNp linux-2.6.22.1/init/main.c linux-2.6.22.1/init/main.c
28665--- linux-2.6.22.1/init/main.c 2007-07-10 14:56:30.000000000 -0400
28666+++ linux-2.6.22.1/init/main.c 2007-08-02 11:38:48.000000000 -0400
28667@@ -107,6 +107,7 @@ static inline void mark_rodata_ro(void)
28668 #ifdef CONFIG_TC
28669 extern void tc_init(void);
28670 #endif
28671+extern void grsecurity_init(void);
28672
28673 enum system_states system_state;
28674 EXPORT_SYMBOL(system_state);
28675@@ -181,6 +182,17 @@ static int __init set_reset_devices(char
28676
28677 __setup("reset_devices", set_reset_devices);
28678
28679+#ifdef CONFIG_PAX_SOFTMODE
28680+unsigned int pax_softmode;
28681+
28682+static int __init setup_pax_softmode(char *str)
28683+{
28684+ get_option(&str, &pax_softmode);
28685+ return 1;
28686+}
28687+__setup("pax_softmode=", setup_pax_softmode);
28688+#endif
28689+
28690 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
28691 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
28692 static const char *panic_later, *panic_param;
28693@@ -828,6 +838,8 @@ static int __init kernel_init(void * unu
28694 prepare_namespace();
28695 }
28696
28697+ grsecurity_init();
28698+
28699 /*
28700 * Ok, we have completed the initial bootup, and
28701 * we're essentially up and running. Get rid of the
28702diff -urNp linux-2.6.22.1/init/noinitramfs.c linux-2.6.22.1/init/noinitramfs.c
28703--- linux-2.6.22.1/init/noinitramfs.c 2007-07-10 14:56:30.000000000 -0400
28704+++ linux-2.6.22.1/init/noinitramfs.c 2007-08-02 11:38:48.000000000 -0400
28705@@ -29,7 +29,7 @@ static int __init default_rootfs(void)
28706 {
28707 int err;
28708
28709- err = sys_mkdir("/dev", 0755);
28710+ err = sys_mkdir((const char __user *)"/dev", 0755);
28711 if (err < 0)
28712 goto out;
28713
28714@@ -39,7 +39,7 @@ static int __init default_rootfs(void)
28715 if (err < 0)
28716 goto out;
28717
28718- err = sys_mkdir("/root", 0700);
28719+ err = sys_mkdir((const char __user *)"/root", 0700);
28720 if (err < 0)
28721 goto out;
28722
28723diff -urNp linux-2.6.22.1/ipc/msg.c linux-2.6.22.1/ipc/msg.c
28724--- linux-2.6.22.1/ipc/msg.c 2007-07-10 14:56:30.000000000 -0400
28725+++ linux-2.6.22.1/ipc/msg.c 2007-08-02 11:09:16.000000000 -0400
28726@@ -36,6 +36,7 @@
28727 #include <linux/mutex.h>
28728 #include <linux/nsproxy.h>
28729 #include <linux/vs_base.h>
28730+#include <linux/grsecurity.h>
28731
28732 #include <asm/current.h>
28733 #include <asm/uaccess.h>
28734@@ -288,6 +289,8 @@ asmlinkage long sys_msgget(key_t key, in
28735 }
28736 mutex_unlock(&msg_ids(ns).mutex);
28737
28738+ gr_log_msgget(ret, msgflg);
28739+
28740 return ret;
28741 }
28742
28743@@ -554,6 +557,7 @@ asmlinkage long sys_msgctl(int msqid, in
28744 break;
28745 }
28746 case IPC_RMID:
28747+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
28748 freeque(ns, msq, msqid);
28749 break;
28750 }
28751diff -urNp linux-2.6.22.1/ipc/sem.c linux-2.6.22.1/ipc/sem.c
28752--- linux-2.6.22.1/ipc/sem.c 2007-07-10 14:56:30.000000000 -0400
28753+++ linux-2.6.22.1/ipc/sem.c 2007-08-02 11:09:16.000000000 -0400
28754@@ -82,6 +82,7 @@
28755 #include <linux/nsproxy.h>
28756 #include <linux/vs_base.h>
28757 #include <linux/vs_limit.h>
28758+#include <linux/grsecurity.h>
28759
28760 #include <asm/uaccess.h>
28761 #include "util.h"
28762@@ -295,6 +296,9 @@ asmlinkage long sys_semget (key_t key, i
28763 }
28764
28765 mutex_unlock(&sem_ids(ns).mutex);
28766+
28767+ gr_log_semget(err, semflg);
28768+
28769 return err;
28770 }
28771
28772@@ -896,6 +900,7 @@ static int semctl_down(struct ipc_namesp
28773
28774 switch(cmd){
28775 case IPC_RMID:
28776+ gr_log_semrm(ipcp->uid, ipcp->cuid);
28777 freeary(ns, sma, semid);
28778 err = 0;
28779 break;
28780diff -urNp linux-2.6.22.1/ipc/shm.c linux-2.6.22.1/ipc/shm.c
28781--- linux-2.6.22.1/ipc/shm.c 2007-07-10 14:56:30.000000000 -0400
28782+++ linux-2.6.22.1/ipc/shm.c 2007-08-02 11:09:16.000000000 -0400
28783@@ -38,6 +38,7 @@
28784 #include <linux/mount.h>
28785 #include <linux/vs_context.h>
28786 #include <linux/vs_limit.h>
28787+#include <linux/grsecurity.h>
28788
28789 #include <asm/uaccess.h>
28790
28791@@ -77,6 +78,14 @@ static void shm_destroy (struct ipc_name
28792 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
28793 #endif
28794
28795+#ifdef CONFIG_GRKERNSEC
28796+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
28797+ const time_t shm_createtime, const uid_t cuid,
28798+ const int shmid);
28799+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
28800+ const time_t shm_createtime);
28801+#endif
28802+
28803 static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
28804 {
28805 ns->ids[IPC_SHM_IDS] = ids;
28806@@ -89,6 +98,8 @@ static void __ipc_init __shm_init_ns(str
28807
28808 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
28809 {
28810+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
28811+
28812 if (shp->shm_nattch){
28813 shp->shm_perm.mode |= SHM_DEST;
28814 /* Do not find it any more */
28815@@ -218,6 +229,17 @@ static void shm_close(struct vm_area_str
28816 shp->shm_lprid = current->tgid;
28817 shp->shm_dtim = get_seconds();
28818 shp->shm_nattch--;
28819+#ifdef CONFIG_GRKERNSEC_SHM
28820+ if (grsec_enable_shm) {
28821+ if (shp->shm_nattch == 0) {
28822+ shp->shm_perm.mode |= SHM_DEST;
28823+ shm_destroy(ns, shp);
28824+ } else
28825+ shm_unlock(shp);
28826+ mutex_unlock(&shm_ids(ns).mutex);
28827+ return;
28828+ }
28829+#endif
28830 if(shp->shm_nattch == 0 &&
28831 shp->shm_perm.mode & SHM_DEST)
28832 shm_destroy(ns, shp);
28833@@ -395,6 +417,9 @@ static int newseg (struct ipc_namespace
28834 shp->shm_lprid = 0;
28835 shp->shm_atim = shp->shm_dtim = 0;
28836 shp->shm_ctim = get_seconds();
28837+#ifdef CONFIG_GRKERNSEC
28838+ shp->shm_createtime = get_seconds();
28839+#endif
28840 shp->shm_segsz = size;
28841 shp->shm_nattch = 0;
28842 shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
28843@@ -452,6 +477,8 @@ asmlinkage long sys_shmget (key_t key, s
28844 }
28845 mutex_unlock(&shm_ids(ns).mutex);
28846
28847+ gr_log_shmget(err, shmflg, size);
28848+
28849 return err;
28850 }
28851
28852@@ -905,9 +932,21 @@ long do_shmat(int shmid, char __user *sh
28853 if (err)
28854 goto out_unlock;
28855
28856+#ifdef CONFIG_GRKERNSEC
28857+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
28858+ shp->shm_perm.cuid, shmid) ||
28859+ !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
28860+ err = -EACCES;
28861+ goto out_unlock;
28862+ }
28863+#endif
28864+
28865 path.dentry = dget(shp->shm_file->f_path.dentry);
28866 path.mnt = mntget(shp->shm_file->f_path.mnt);
28867 shp->shm_nattch++;
28868+#ifdef CONFIG_GRKERNSEC
28869+ shp->shm_lapid = current->pid;
28870+#endif
28871 size = i_size_read(path.dentry->d_inode);
28872 shm_unlock(shp);
28873
28874@@ -1111,3 +1150,27 @@ static int sysvipc_shm_proc_show(struct
28875 shp->shm_ctim);
28876 }
28877 #endif
28878+
28879+void gr_shm_exit(struct task_struct *task)
28880+{
28881+#ifdef CONFIG_GRKERNSEC_SHM
28882+ int i;
28883+ struct shmid_kernel *shp;
28884+ struct ipc_namespace *ns;
28885+
28886+ ns = current->nsproxy->ipc_ns;
28887+
28888+ if (!grsec_enable_shm)
28889+ return;
28890+
28891+ for (i = 0; i <= shm_ids(ns).max_id; i++) {
28892+ shp = shm_get(ns, i);
28893+ if (shp && (shp->shm_cprid == task->pid) &&
28894+ (shp->shm_nattch <= 0)) {
28895+ shp->shm_perm.mode |= SHM_DEST;
28896+ shm_destroy(ns, shp);
28897+ }
28898+ }
28899+#endif
28900+ return;
28901+}
28902diff -urNp linux-2.6.22.1/kernel/acct.c linux-2.6.22.1/kernel/acct.c
28903--- linux-2.6.22.1/kernel/acct.c 2007-07-10 14:56:30.000000000 -0400
28904+++ linux-2.6.22.1/kernel/acct.c 2007-08-02 11:38:48.000000000 -0400
28905@@ -511,7 +511,7 @@ static void do_acct_process(struct file
28906 */
28907 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
28908 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
28909- file->f_op->write(file, (char *)&ac,
28910+ file->f_op->write(file, (char __user *)&ac,
28911 sizeof(acct_t), &file->f_pos);
28912 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
28913 set_fs(fs);
28914diff -urNp linux-2.6.22.1/kernel/capability.c linux-2.6.22.1/kernel/capability.c
28915--- linux-2.6.22.1/kernel/capability.c 2007-07-10 14:56:30.000000000 -0400
28916+++ linux-2.6.22.1/kernel/capability.c 2007-08-02 11:09:16.000000000 -0400
28917@@ -12,6 +12,7 @@
28918 #include <linux/security.h>
28919 #include <linux/syscalls.h>
28920 #include <linux/vs_context.h>
28921+#include <linux/grsecurity.h>
28922 #include <asm/uaccess.h>
28923
28924 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
28925@@ -239,14 +240,25 @@ out:
28926 return ret;
28927 }
28928
28929+extern int gr_task_is_capable(struct task_struct *task, const int cap);
28930+extern int gr_is_capable_nolog(const int cap);
28931+
28932 int __capable(struct task_struct *t, int cap)
28933 {
28934- if (security_capable(t, cap) == 0) {
28935+ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
28936 t->flags |= PF_SUPERPRIV;
28937 return 1;
28938 }
28939 return 0;
28940 }
28941+int capable_nolog(int cap)
28942+{
28943+ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
28944+ current->flags |= PF_SUPERPRIV;
28945+ return 1;
28946+ }
28947+ return 0;
28948+}
28949 EXPORT_SYMBOL(__capable);
28950
28951 #include <linux/vserver/base.h>
28952@@ -258,3 +270,4 @@ int capable(int cap)
28953 return __capable(current, cap);
28954 }
28955 EXPORT_SYMBOL(capable);
28956+EXPORT_SYMBOL(capable_nolog);
28957diff -urNp linux-2.6.22.1/kernel/configs.c linux-2.6.22.1/kernel/configs.c
28958--- linux-2.6.22.1/kernel/configs.c 2007-07-10 14:56:30.000000000 -0400
28959+++ linux-2.6.22.1/kernel/configs.c 2007-08-02 11:09:16.000000000 -0400
28960@@ -79,8 +79,16 @@ static int __init ikconfig_init(void)
28961 struct proc_dir_entry *entry;
28962
28963 /* create the current config file */
28964+#ifdef CONFIG_GRKERNSEC_PROC_ADD
28965+#ifdef CONFIG_GRKERNSEC_PROC_USER
28966+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
28967+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
28968+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
28969+#endif
28970+#else
28971 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
28972 &proc_root);
28973+#endif
28974 if (!entry)
28975 return -ENOMEM;
28976
28977diff -urNp linux-2.6.22.1/kernel/exit.c linux-2.6.22.1/kernel/exit.c
28978--- linux-2.6.22.1/kernel/exit.c 2007-07-10 14:56:30.000000000 -0400
28979+++ linux-2.6.22.1/kernel/exit.c 2007-08-02 11:38:48.000000000 -0400
28980@@ -44,6 +44,11 @@
28981 #include <linux/vs_network.h>
28982 #include <linux/vs_pid.h>
28983 #include <linux/vserver/global.h>
28984+#include <linux/grsecurity.h>
28985+
28986+#ifdef CONFIG_GRKERNSEC
28987+extern rwlock_t grsec_exec_file_lock;
28988+#endif
28989
28990 #include <asm/uaccess.h>
28991 #include <asm/unistd.h>
28992@@ -130,6 +135,7 @@ static void __exit_signal(struct task_st
28993
28994 __unhash_process(tsk);
28995
28996+ gr_del_task_from_ip_table(tsk);
28997 tsk->signal = NULL;
28998 tsk->sighand = NULL;
28999 spin_unlock(&sighand->siglock);
29000@@ -282,12 +288,23 @@ static void reparent_to_kthreadd(void)
29001 {
29002 write_lock_irq(&tasklist_lock);
29003
29004+#ifdef CONFIG_GRKERNSEC
29005+ write_lock(&grsec_exec_file_lock);
29006+ if (current->exec_file) {
29007+ fput(current->exec_file);
29008+ current->exec_file = NULL;
29009+ }
29010+ write_unlock(&grsec_exec_file_lock);
29011+#endif
29012+
29013 ptrace_unlink(current);
29014 /* Reparent to init */
29015 remove_parent(current);
29016 current->real_parent = current->parent = kthreadd_task;
29017 add_parent(current);
29018
29019+ gr_set_kernel_label(current);
29020+
29021 /* Set the exit signal to SIGCHLD so we signal init on exit */
29022 current->exit_signal = SIGCHLD;
29023
29024@@ -382,6 +399,17 @@ void daemonize(const char *name, ...)
29025 vsnprintf(current->comm, sizeof(current->comm), name, args);
29026 va_end(args);
29027
29028+#ifdef CONFIG_GRKERNSEC
29029+ write_lock(&grsec_exec_file_lock);
29030+ if (current->exec_file) {
29031+ fput(current->exec_file);
29032+ current->exec_file = NULL;
29033+ }
29034+ write_unlock(&grsec_exec_file_lock);
29035+#endif
29036+
29037+ gr_set_kernel_label(current);
29038+
29039 /*
29040 * If we were started as result of loading a module, close all of the
29041 * user space pages. We don't need them, and if we didn't close them
29042@@ -943,11 +971,15 @@ fastcall NORET_TYPE void do_exit(long co
29043
29044 taskstats_exit(tsk, group_dead);
29045
29046+ gr_acl_handle_psacct(tsk, code);
29047+ gr_acl_handle_exit();
29048+
29049 exit_mm(tsk);
29050
29051 if (group_dead)
29052 acct_process();
29053 exit_sem(tsk);
29054+ gr_shm_exit(tsk);
29055 __exit_files(tsk);
29056 __exit_fs(tsk);
29057 exit_thread();
29058@@ -1148,7 +1180,7 @@ static int wait_task_zombie(struct task_
29059 pid_t pid = p->pid;
29060 uid_t uid = p->uid;
29061 int exit_code = p->exit_code;
29062- int why, status;
29063+ int why;
29064
29065 if (unlikely(p->exit_state != EXIT_ZOMBIE))
29066 return 0;
29067diff -urNp linux-2.6.22.1/kernel/fork.c linux-2.6.22.1/kernel/fork.c
29068--- linux-2.6.22.1/kernel/fork.c 2007-07-10 14:56:30.000000000 -0400
29069+++ linux-2.6.22.1/kernel/fork.c 2007-08-02 11:38:48.000000000 -0400
29070@@ -49,6 +49,7 @@
29071 #include <linux/vs_limit.h>
29072 #include <linux/vs_memory.h>
29073 #include <linux/vserver/global.h>
29074+#include <linux/grsecurity.h>
29075
29076 #include <asm/pgtable.h>
29077 #include <asm/pgalloc.h>
29078@@ -180,7 +181,7 @@ static struct task_struct *dup_task_stru
29079 setup_thread_stack(tsk, orig);
29080
29081 #ifdef CONFIG_CC_STACKPROTECTOR
29082- tsk->stack_canary = get_random_int();
29083+ tsk->stack_canary = pax_get_random_long();
29084 #endif
29085
29086 /* One for us, one for whoever does the "release_task()" (usually parent) */
29087@@ -202,6 +203,10 @@ static inline int dup_mmap(struct mm_str
29088 unsigned long charge;
29089 struct mempolicy *pol;
29090
29091+#ifdef CONFIG_PAX_SEGMEXEC
29092+ struct vm_area_struct *mpnt_m;
29093+#endif
29094+
29095 down_write(&oldmm->mmap_sem);
29096 flush_cache_dup_mm(oldmm);
29097 /*
29098@@ -212,8 +217,8 @@ static inline int dup_mmap(struct mm_str
29099 mm->locked_vm = 0;
29100 mm->mmap = NULL;
29101 mm->mmap_cache = NULL;
29102- mm->free_area_cache = oldmm->mmap_base;
29103- mm->cached_hole_size = ~0UL;
29104+ mm->free_area_cache = oldmm->free_area_cache;
29105+ mm->cached_hole_size = oldmm->cached_hole_size;
29106 mm->map_count = 0;
29107 __set_mm_counter(mm, file_rss, 0);
29108 __set_mm_counter(mm, anon_rss, 0);
29109@@ -232,6 +237,7 @@ static inline int dup_mmap(struct mm_str
29110 continue;
29111 }
29112 charge = 0;
29113+
29114 if (mpnt->vm_flags & VM_ACCOUNT) {
29115 unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
29116 if (security_vm_enough_memory(len))
29117@@ -250,6 +256,7 @@ static inline int dup_mmap(struct mm_str
29118 tmp->vm_flags &= ~VM_LOCKED;
29119 tmp->vm_mm = mm;
29120 tmp->vm_next = NULL;
29121+ tmp->vm_mirror = NULL;
29122 anon_vma_link(tmp);
29123 file = tmp->vm_file;
29124 if (file) {
29125@@ -286,6 +293,29 @@ static inline int dup_mmap(struct mm_str
29126 if (retval)
29127 goto out;
29128 }
29129+
29130+#ifdef CONFIG_PAX_SEGMEXEC
29131+ if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
29132+ for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
29133+ BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
29134+
29135+ if (!mpnt->vm_mirror)
29136+ continue;
29137+
29138+ if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
29139+ BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
29140+ mpnt->vm_mirror = mpnt_m;
29141+ } else {
29142+ BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
29143+ mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
29144+ mpnt_m->vm_mirror->vm_mirror = mpnt_m;
29145+ mpnt->vm_mirror->vm_mirror = mpnt;
29146+ }
29147+ }
29148+ BUG_ON(mpnt_m);
29149+ }
29150+#endif
29151+
29152 /* a new mm has just been created */
29153 arch_dup_mmap(oldmm, mm);
29154 retval = 0;
29155@@ -461,7 +491,7 @@ void mm_release(struct task_struct *tsk,
29156 if (tsk->clear_child_tid
29157 && !(tsk->flags & PF_SIGNALED)
29158 && atomic_read(&mm->mm_users) > 1) {
29159- u32 __user * tidptr = tsk->clear_child_tid;
29160+ pid_t __user * tidptr = tsk->clear_child_tid;
29161 tsk->clear_child_tid = NULL;
29162
29163 /*
29164@@ -480,7 +510,7 @@ void mm_release(struct task_struct *tsk,
29165 * not set up a proper pointer then tough luck.
29166 */
29167 put_user(0, tidptr);
29168- sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
29169+ sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
29170 }
29171 }
29172
29173@@ -996,6 +1026,9 @@ static struct task_struct *copy_process(
29174 }
29175
29176 retval = -EAGAIN;
29177+
29178+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
29179+
29180 if (!vx_nproc_avail(1))
29181 goto bad_fork_cleanup_vm;
29182
29183@@ -1131,6 +1164,8 @@ static struct task_struct *copy_process(
29184 if (retval)
29185 goto bad_fork_cleanup_namespaces;
29186
29187+ gr_copy_label(p);
29188+
29189 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
29190 /*
29191 * Clear TID on mm_release()?
29192@@ -1309,6 +1344,8 @@ bad_fork_cleanup_count:
29193 bad_fork_free:
29194 free_task(p);
29195 fork_out:
29196+ gr_log_forkfail(retval);
29197+
29198 return ERR_PTR(retval);
29199 }
29200
29201@@ -1382,6 +1419,8 @@ long do_fork(unsigned long clone_flags,
29202 if (!IS_ERR(p)) {
29203 struct completion vfork;
29204
29205+ gr_handle_brute_check();
29206+
29207 if (clone_flags & CLONE_VFORK) {
29208 p->vfork_done = &vfork;
29209 init_completion(&vfork);
29210diff -urNp linux-2.6.22.1/kernel/futex.c linux-2.6.22.1/kernel/futex.c
29211--- linux-2.6.22.1/kernel/futex.c 2007-07-10 14:56:30.000000000 -0400
29212+++ linux-2.6.22.1/kernel/futex.c 2007-08-02 11:38:48.000000000 -0400
29213@@ -168,6 +168,11 @@ int get_futex_key(u32 __user *uaddr, str
29214 struct page *page;
29215 int err;
29216
29217+#ifdef CONFIG_PAX_SEGMEXEC
29218+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
29219+ return -EFAULT;
29220+#endif
29221+
29222 /*
29223 * The futex address must be "naturally" aligned.
29224 */
29225@@ -194,8 +199,8 @@ int get_futex_key(u32 __user *uaddr, str
29226 * The futex is hashed differently depending on whether
29227 * it's in a shared or private mapping. So check vma first.
29228 */
29229- vma = find_extend_vma(mm, address);
29230- if (unlikely(!vma))
29231+ vma = find_vma(mm, address);
29232+ if (unlikely(!vma || address < vma->vm_start))
29233 return -EFAULT;
29234
29235 /*
29236@@ -1921,7 +1926,7 @@ retry:
29237 */
29238 static inline int fetch_robust_entry(struct robust_list __user **entry,
29239 struct robust_list __user * __user *head,
29240- int *pi)
29241+ unsigned int *pi)
29242 {
29243 unsigned long uentry;
29244
29245diff -urNp linux-2.6.22.1/kernel/irq/handle.c linux-2.6.22.1/kernel/irq/handle.c
29246--- linux-2.6.22.1/kernel/irq/handle.c 2007-07-10 14:56:30.000000000 -0400
29247+++ linux-2.6.22.1/kernel/irq/handle.c 2007-08-02 11:38:48.000000000 -0400
29248@@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
29249 .depth = 1,
29250 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
29251 #ifdef CONFIG_SMP
29252- .affinity = CPU_MASK_ALL
29253+ .affinity = CPU_MASK_ALL,
29254+ .cpu = 0,
29255 #endif
29256 }
29257 };
29258diff -urNp linux-2.6.22.1/kernel/kallsyms.c linux-2.6.22.1/kernel/kallsyms.c
29259--- linux-2.6.22.1/kernel/kallsyms.c 2007-07-10 14:56:30.000000000 -0400
29260+++ linux-2.6.22.1/kernel/kallsyms.c 2007-08-02 11:38:48.000000000 -0400
29261@@ -65,6 +65,19 @@ static inline int is_kernel_text(unsigne
29262
29263 static inline int is_kernel(unsigned long addr)
29264 {
29265+
29266+#ifdef CONFIG_PAX_KERNEXEC
29267+
29268+#ifdef CONFIG_MODULES
29269+ if ((unsigned long)MODULES_VADDR <= addr + __KERNEL_TEXT_OFFSET &&
29270+ addr + __KERNEL_TEXT_OFFSET < (unsigned long)MODULES_END)
29271+ return 0;
29272+#endif
29273+
29274+ if (is_kernel_inittext(addr))
29275+ return 1;
29276+#endif
29277+
29278 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
29279 return 1;
29280 return in_gate_area_no_task(addr);
29281@@ -374,7 +383,6 @@ static unsigned long get_ksymbol_core(st
29282
29283 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
29284 {
29285- iter->name[0] = '\0';
29286 iter->nameoff = get_symbol_offset(new_pos);
29287 iter->pos = new_pos;
29288 }
29289@@ -458,7 +466,7 @@ static int kallsyms_open(struct inode *i
29290 struct kallsym_iter *iter;
29291 int ret;
29292
29293- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
29294+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
29295 if (!iter)
29296 return -ENOMEM;
29297 reset_iter(iter, 0);
29298@@ -482,7 +490,15 @@ static int __init kallsyms_init(void)
29299 {
29300 struct proc_dir_entry *entry;
29301
29302+#ifdef CONFIG_GRKERNSEC_PROC_ADD
29303+#ifdef CONFIG_GRKERNSEC_PROC_USER
29304+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
29305+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
29306+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
29307+#endif
29308+#else
29309 entry = create_proc_entry("kallsyms", 0444, NULL);
29310+#endif
29311 if (entry)
29312 entry->proc_fops = &kallsyms_operations;
29313 return 0;
29314diff -urNp linux-2.6.22.1/kernel/kprobes.c linux-2.6.22.1/kernel/kprobes.c
29315--- linux-2.6.22.1/kernel/kprobes.c 2007-07-10 14:56:30.000000000 -0400
29316+++ linux-2.6.22.1/kernel/kprobes.c 2007-08-02 11:38:48.000000000 -0400
29317@@ -168,7 +168,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
29318 * kernel image and loaded module images reside. This is required
29319 * so x86_64 can correctly handle the %rip-relative fixups.
29320 */
29321- kip->insns = module_alloc(PAGE_SIZE);
29322+ kip->insns = module_alloc_exec(PAGE_SIZE);
29323 if (!kip->insns) {
29324 kfree(kip);
29325 return NULL;
29326@@ -200,7 +200,7 @@ static int __kprobes collect_one_slot(st
29327 hlist_add_head(&kip->hlist,
29328 &kprobe_insn_pages);
29329 } else {
29330- module_free(NULL, kip->insns);
29331+ module_free_exec(NULL, kip->insns);
29332 kfree(kip);
29333 }
29334 return 1;
29335diff -urNp linux-2.6.22.1/kernel/module.c linux-2.6.22.1/kernel/module.c
29336--- linux-2.6.22.1/kernel/module.c 2007-07-10 14:56:30.000000000 -0400
29337+++ linux-2.6.22.1/kernel/module.c 2007-08-02 11:38:48.000000000 -0400
29338@@ -44,6 +44,11 @@
29339 #include <asm/uaccess.h>
29340 #include <asm/semaphore.h>
29341 #include <asm/cacheflush.h>
29342+
29343+#ifdef CONFIG_PAX_KERNEXEC
29344+#include <asm/desc.h>
29345+#endif
29346+
29347 #include <linux/license.h>
29348
29349 extern int module_sysfs_initialized;
29350@@ -70,6 +75,8 @@ static LIST_HEAD(modules);
29351
29352 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
29353
29354+extern int gr_check_modstop(void);
29355+
29356 int register_module_notifier(struct notifier_block * nb)
29357 {
29358 return blocking_notifier_chain_register(&module_notify_list, nb);
29359@@ -349,7 +356,7 @@ static void *percpu_modalloc(unsigned lo
29360 unsigned int i;
29361 void *ptr;
29362
29363- if (align > PAGE_SIZE) {
29364+ if (align-1 >= PAGE_SIZE) {
29365 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
29366 name, align, PAGE_SIZE);
29367 align = PAGE_SIZE;
29368@@ -663,6 +670,9 @@ sys_delete_module(const char __user *nam
29369 char name[MODULE_NAME_LEN];
29370 int ret, forced = 0;
29371
29372+ if (gr_check_modstop())
29373+ return -EPERM;
29374+
29375 if (!capable(CAP_SYS_MODULE))
29376 return -EPERM;
29377
29378@@ -1216,16 +1226,19 @@ static void free_module(struct module *m
29379 module_unload_free(mod);
29380
29381 /* This may be NULL, but that's OK */
29382- module_free(mod, mod->module_init);
29383+ module_free(mod, mod->module_init_rw);
29384+ module_free_exec(mod, mod->module_init_rx);
29385 kfree(mod->args);
29386 if (mod->percpu)
29387 percpu_modfree(mod->percpu);
29388
29389 /* Free lock-classes: */
29390- lockdep_free_key_range(mod->module_core, mod->core_size);
29391+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
29392+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
29393
29394 /* Finally, free the core (containing the module structure) */
29395- module_free(mod, mod->module_core);
29396+ module_free_exec(mod, mod->module_core_rx);
29397+ module_free(mod, mod->module_core_rw);
29398 }
29399
29400 void *__symbol_get(const char *symbol)
29401@@ -1290,6 +1303,10 @@ static int simplify_symbols(Elf_Shdr *se
29402 unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
29403 int ret = 0;
29404
29405+#ifdef CONFIG_PAX_KERNEXEC
29406+ unsigned long cr0;
29407+#endif
29408+
29409 for (i = 1; i < n; i++) {
29410 switch (sym[i].st_shndx) {
29411 case SHN_COMMON:
29412@@ -1308,10 +1325,19 @@ static int simplify_symbols(Elf_Shdr *se
29413 break;
29414
29415 case SHN_UNDEF:
29416+
29417+#ifdef CONFIG_PAX_KERNEXEC
29418+ pax_open_kernel(cr0);
29419+#endif
29420+
29421 sym[i].st_value
29422 = resolve_symbol(sechdrs, versindex,
29423 strtab + sym[i].st_name, mod);
29424
29425+#ifdef CONFIG_PAX_KERNEXEC
29426+ pax_close_kernel(cr0);
29427+#endif
29428+
29429 /* Ok if resolved. */
29430 if (sym[i].st_value != 0)
29431 break;
29432@@ -1326,11 +1352,27 @@ static int simplify_symbols(Elf_Shdr *se
29433
29434 default:
29435 /* Divert to percpu allocation if a percpu var. */
29436- if (sym[i].st_shndx == pcpuindex)
29437+ if (sym[i].st_shndx == pcpuindex) {
29438+
29439+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
29440+ secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
29441+#else
29442 secbase = (unsigned long)mod->percpu;
29443- else
29444+#endif
29445+
29446+ } else
29447 secbase = sechdrs[sym[i].st_shndx].sh_addr;
29448+
29449+#ifdef CONFIG_PAX_KERNEXEC
29450+ pax_open_kernel(cr0);
29451+#endif
29452+
29453 sym[i].st_value += secbase;
29454+
29455+#ifdef CONFIG_PAX_KERNEXEC
29456+ pax_close_kernel(cr0);
29457+#endif
29458+
29459 break;
29460 }
29461 }
29462@@ -1382,11 +1424,14 @@ static void layout_sections(struct modul
29463 || strncmp(secstrings + s->sh_name,
29464 ".init", 5) == 0)
29465 continue;
29466- s->sh_entsize = get_offset(&mod->core_size, s);
29467+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
29468+ s->sh_entsize = get_offset(&mod->core_size_rw, s);
29469+ else
29470+ s->sh_entsize = get_offset(&mod->core_size_rx, s);
29471 DEBUGP("\t%s\n", secstrings + s->sh_name);
29472 }
29473 if (m == 0)
29474- mod->core_text_size = mod->core_size;
29475+ mod->core_size_rx = mod->core_size_rx;
29476 }
29477
29478 DEBUGP("Init section allocation order:\n");
29479@@ -1400,12 +1445,15 @@ static void layout_sections(struct modul
29480 || strncmp(secstrings + s->sh_name,
29481 ".init", 5) != 0)
29482 continue;
29483- s->sh_entsize = (get_offset(&mod->init_size, s)
29484- | INIT_OFFSET_MASK);
29485+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
29486+ s->sh_entsize = get_offset(&mod->init_size_rw, s);
29487+ else
29488+ s->sh_entsize = get_offset(&mod->init_size_rx, s);
29489+ s->sh_entsize |= INIT_OFFSET_MASK;
29490 DEBUGP("\t%s\n", secstrings + s->sh_name);
29491 }
29492 if (m == 0)
29493- mod->init_text_size = mod->init_size;
29494+ mod->init_size_rx = mod->init_size_rx;
29495 }
29496 }
29497
29498@@ -1532,14 +1580,28 @@ static void add_kallsyms(struct module *
29499 {
29500 unsigned int i;
29501
29502+#ifdef CONFIG_PAX_KERNEXEC
29503+ unsigned long cr0;
29504+#endif
29505+
29506 mod->symtab = (void *)sechdrs[symindex].sh_addr;
29507 mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
29508 mod->strtab = (void *)sechdrs[strindex].sh_addr;
29509
29510 /* Set types up while we still have access to sections. */
29511+
29512+#ifdef CONFIG_PAX_KERNEXEC
29513+ pax_open_kernel(cr0);
29514+#endif
29515+
29516 for (i = 0; i < mod->num_symtab; i++)
29517 mod->symtab[i].st_info
29518 = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
29519+
29520+#ifdef CONFIG_PAX_KERNEXEC
29521+ pax_close_kernel(cr0);
29522+#endif
29523+
29524 }
29525 #else
29526 static inline void add_kallsyms(struct module *mod,
29527@@ -1587,6 +1649,10 @@ static struct module *load_module(void _
29528 struct exception_table_entry *extable;
29529 mm_segment_t old_fs;
29530
29531+#ifdef CONFIG_PAX_KERNEXEC
29532+ unsigned long cr0;
29533+#endif
29534+
29535 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
29536 umod, len, uargs);
29537 if (len < sizeof(*hdr))
29538@@ -1745,21 +1811,57 @@ static struct module *load_module(void _
29539 layout_sections(mod, hdr, sechdrs, secstrings);
29540
29541 /* Do the allocs. */
29542- ptr = module_alloc(mod->core_size);
29543+ ptr = module_alloc(mod->core_size_rw);
29544 if (!ptr) {
29545 err = -ENOMEM;
29546 goto free_percpu;
29547 }
29548- memset(ptr, 0, mod->core_size);
29549- mod->module_core = ptr;
29550+ memset(ptr, 0, mod->core_size_rw);
29551+ mod->module_core_rw = ptr;
29552+
29553+ ptr = module_alloc(mod->init_size_rw);
29554+ if (!ptr && mod->init_size_rw) {
29555+ err = -ENOMEM;
29556+ goto free_core_rw;
29557+ }
29558+ memset(ptr, 0, mod->init_size_rw);
29559+ mod->module_init_rw = ptr;
29560+
29561+ ptr = module_alloc_exec(mod->core_size_rx);
29562+ if (!ptr) {
29563+ err = -ENOMEM;
29564+ goto free_init_rw;
29565+ }
29566+
29567+#ifdef CONFIG_PAX_KERNEXEC
29568+ pax_open_kernel(cr0);
29569+#endif
29570+
29571+ memset(ptr, 0, mod->core_size_rx);
29572
29573- ptr = module_alloc(mod->init_size);
29574- if (!ptr && mod->init_size) {
29575+#ifdef CONFIG_PAX_KERNEXEC
29576+ pax_close_kernel(cr0);
29577+#endif
29578+
29579+ mod->module_core_rx = ptr;
29580+
29581+ ptr = module_alloc_exec(mod->init_size_rx);
29582+ if (!ptr && mod->init_size_rx) {
29583 err = -ENOMEM;
29584- goto free_core;
29585+ goto free_core_rx;
29586 }
29587- memset(ptr, 0, mod->init_size);
29588- mod->module_init = ptr;
29589+
29590+#ifdef CONFIG_PAX_KERNEXEC
29591+ pax_open_kernel(cr0);
29592+#endif
29593+
29594+ memset(ptr, 0, mod->init_size_rx);
29595+
29596+#ifdef CONFIG_PAX_KERNEXEC
29597+ pax_close_kernel(cr0);
29598+#endif
29599+
29600+ mod->module_init_rx = ptr;
29601
29602 /* Transfer each section which specifies SHF_ALLOC */
29603 DEBUGP("final section addresses:\n");
29604@@ -1769,17 +1871,44 @@ static struct module *load_module(void _
29605 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
29606 continue;
29607
29608- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
29609- dest = mod->module_init
29610- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
29611- else
29612- dest = mod->module_core + sechdrs[i].sh_entsize;
29613+ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
29614+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
29615+ dest = mod->module_init_rw
29616+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
29617+ else
29618+ dest = mod->module_init_rx
29619+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
29620+ } else {
29621+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
29622+ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
29623+ else
29624+ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
29625+ }
29626+
29627+ if (sechdrs[i].sh_type != SHT_NOBITS) {
29628+
29629+#ifdef CONFIG_PAX_KERNEXEC
29630+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
29631+ pax_open_kernel(cr0);
29632+#endif
29633
29634- if (sechdrs[i].sh_type != SHT_NOBITS)
29635- memcpy(dest, (void *)sechdrs[i].sh_addr,
29636- sechdrs[i].sh_size);
29637+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
29638+
29639+#ifdef CONFIG_PAX_KERNEXEC
29640+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
29641+ pax_close_kernel(cr0);
29642+#endif
29643+
29644+ }
29645 /* Update sh_addr to point to copy in image. */
29646- sechdrs[i].sh_addr = (unsigned long)dest;
29647+
29648+#ifdef CONFIG_PAX_KERNEXEC
29649+ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
29650+ sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
29651+ else
29652+#endif
29653+
29654+ sechdrs[i].sh_addr = (unsigned long)dest;
29655 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
29656 }
29657 /* Module has been moved. */
29658@@ -1860,11 +1989,20 @@ static struct module *load_module(void _
29659 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
29660 continue;
29661
29662+#ifdef CONFIG_PAX_KERNEXEC
29663+ pax_open_kernel(cr0);
29664+#endif
29665+
29666 if (sechdrs[i].sh_type == SHT_REL)
29667 err = apply_relocate(sechdrs, strtab, symindex, i,mod);
29668 else if (sechdrs[i].sh_type == SHT_RELA)
29669 err = apply_relocate_add(sechdrs, strtab, symindex, i,
29670 mod);
29671+
29672+#ifdef CONFIG_PAX_KERNEXEC
29673+ pax_close_kernel(cr0);
29674+#endif
29675+
29676 if (err < 0)
29677 goto cleanup;
29678 }
29679@@ -1899,12 +2037,12 @@ static struct module *load_module(void _
29680 * Do it before processing of module parameters, so the module
29681 * can provide parameter accessor functions of its own.
29682 */
29683- if (mod->module_init)
29684- flush_icache_range((unsigned long)mod->module_init,
29685- (unsigned long)mod->module_init
29686- + mod->init_size);
29687- flush_icache_range((unsigned long)mod->module_core,
29688- (unsigned long)mod->module_core + mod->core_size);
29689+ if (mod->module_init_rx)
29690+ flush_icache_range((unsigned long)mod->module_init_rx,
29691+ (unsigned long)mod->module_init_rx
29692+ + mod->init_size_rx);
29693+ flush_icache_range((unsigned long)mod->module_core_rx,
29694+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
29695
29696 set_fs(old_fs);
29697
29698@@ -1947,9 +2085,13 @@ static struct module *load_module(void _
29699 module_arch_cleanup(mod);
29700 cleanup:
29701 module_unload_free(mod);
29702- module_free(mod, mod->module_init);
29703- free_core:
29704- module_free(mod, mod->module_core);
29705+ module_free_exec(mod, mod->module_init_rx);
29706+ free_core_rx:
29707+ module_free_exec(mod, mod->module_core_rx);
29708+ free_init_rw:
29709+ module_free(mod, mod->module_init_rw);
29710+ free_core_rw:
29711+ module_free(mod, mod->module_core_rw);
29712 free_percpu:
29713 if (percpu)
29714 percpu_modfree(percpu);
29715@@ -1985,6 +2127,9 @@ sys_init_module(void __user *umod,
29716 struct module *mod;
29717 int ret = 0;
29718
29719+ if (gr_check_modstop())
29720+ return -EPERM;
29721+
29722 /* Must have permission */
29723 if (!capable(CAP_SYS_MODULE))
29724 return -EPERM;
29725@@ -2036,10 +2181,12 @@ sys_init_module(void __user *umod,
29726 /* Drop initial reference. */
29727 module_put(mod);
29728 unwind_remove_table(mod->unwind_info, 1);
29729- module_free(mod, mod->module_init);
29730- mod->module_init = NULL;
29731- mod->init_size = 0;
29732- mod->init_text_size = 0;
29733+ module_free(mod, mod->module_init_rw);
29734+ module_free_exec(mod, mod->module_init_rx);
29735+ mod->module_init_rw = NULL;
29736+ mod->module_init_rx = NULL;
29737+ mod->init_size_rw = 0;
29738+ mod->init_size_rx = 0;
29739 mutex_unlock(&module_mutex);
29740
29741 return 0;
29742@@ -2047,6 +2194,13 @@ sys_init_module(void __user *umod,
29743
29744 static inline int within(unsigned long addr, void *start, unsigned long size)
29745 {
29746+
29747+#ifdef CONFIG_PAX_KERNEXEC
29748+ if (addr + __KERNEL_TEXT_OFFSET >= (unsigned long)start &&
29749+ addr + __KERNEL_TEXT_OFFSET < (unsigned long)start + size)
29750+ return 1;
29751+#endif
29752+
29753 return ((void *)addr >= start && (void *)addr < start + size);
29754 }
29755
29756@@ -2070,10 +2224,14 @@ static const char *get_ksymbol(struct mo
29757 unsigned long nextval;
29758
29759 /* At worse, next value is at end of module */
29760- if (within(addr, mod->module_init, mod->init_size))
29761- nextval = (unsigned long)mod->module_init+mod->init_text_size;
29762- else
29763- nextval = (unsigned long)mod->module_core+mod->core_text_size;
29764+ if (within(addr, mod->module_init_rx, mod->init_size_rx))
29765+ nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
29766+ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
29767+ nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
29768+ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
29769+ nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
29770+ else
29771+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
29772
29773 /* Scan for closest preceeding symbol, and next symbol. (ELF
29774 starts real symbols at 1). */
29775@@ -2116,8 +2274,10 @@ const char *module_address_lookup(unsign
29776 struct module *mod;
29777
29778 list_for_each_entry(mod, &modules, list) {
29779- if (within(addr, mod->module_init, mod->init_size)
29780- || within(addr, mod->module_core, mod->core_size)) {
29781+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
29782+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
29783+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
29784+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
29785 if (modname)
29786 *modname = mod->name;
29787 return get_ksymbol(mod, addr, size, offset);
29788@@ -2132,8 +2292,10 @@ int lookup_module_symbol_name(unsigned l
29789
29790 mutex_lock(&module_mutex);
29791 list_for_each_entry(mod, &modules, list) {
29792- if (within(addr, mod->module_init, mod->init_size) ||
29793- within(addr, mod->module_core, mod->core_size)) {
29794+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
29795+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
29796+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
29797+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
29798 const char *sym;
29799
29800 sym = get_ksymbol(mod, addr, NULL, NULL);
29801@@ -2156,8 +2318,10 @@ int lookup_module_symbol_attrs(unsigned
29802
29803 mutex_lock(&module_mutex);
29804 list_for_each_entry(mod, &modules, list) {
29805- if (within(addr, mod->module_init, mod->init_size) ||
29806- within(addr, mod->module_core, mod->core_size)) {
29807+ if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
29808+ within(addr, mod->module_init_rw, mod->init_size_rw) ||
29809+ within(addr, mod->module_core_rx, mod->core_size_rx) ||
29810+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
29811 const char *sym;
29812
29813 sym = get_ksymbol(mod, addr, size, offset);
29814@@ -2290,7 +2454,7 @@ static int m_show(struct seq_file *m, vo
29815 char buf[8];
29816
29817 seq_printf(m, "%s %lu",
29818- mod->name, mod->init_size + mod->core_size);
29819+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
29820 print_unload_info(m, mod);
29821
29822 /* Informative for users. */
29823@@ -2299,7 +2463,7 @@ static int m_show(struct seq_file *m, vo
29824 mod->state == MODULE_STATE_COMING ? "Loading":
29825 "Live");
29826 /* Used by oprofile and other similar tools. */
29827- seq_printf(m, " 0x%p", mod->module_core);
29828+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
29829
29830 /* Taints info */
29831 if (mod->taints)
29832@@ -2357,7 +2521,8 @@ int is_module_address(unsigned long addr
29833 spin_lock_irqsave(&modlist_lock, flags);
29834
29835 list_for_each_entry(mod, &modules, list) {
29836- if (within(addr, mod->module_core, mod->core_size)) {
29837+ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
29838+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
29839 spin_unlock_irqrestore(&modlist_lock, flags);
29840 return 1;
29841 }
29842@@ -2375,8 +2540,8 @@ struct module *__module_text_address(uns
29843 struct module *mod;
29844
29845 list_for_each_entry(mod, &modules, list)
29846- if (within(addr, mod->module_init, mod->init_text_size)
29847- || within(addr, mod->module_core, mod->core_text_size))
29848+ if (within(addr, mod->module_init_rx, mod->init_size_rx)
29849+ || within(addr, mod->module_core_rx, mod->core_size_rx))
29850 return mod;
29851 return NULL;
29852 }
29853diff -urNp linux-2.6.22.1/kernel/mutex.c linux-2.6.22.1/kernel/mutex.c
29854--- linux-2.6.22.1/kernel/mutex.c 2007-07-10 14:56:30.000000000 -0400
29855+++ linux-2.6.22.1/kernel/mutex.c 2007-08-02 11:38:48.000000000 -0400
29856@@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
29857 *
29858 * This function is similar to (but not equivalent to) down().
29859 */
29860-void inline fastcall __sched mutex_lock(struct mutex *lock)
29861+inline void fastcall __sched mutex_lock(struct mutex *lock)
29862 {
29863 might_sleep();
29864 /*
29865diff -urNp linux-2.6.22.1/kernel/params.c linux-2.6.22.1/kernel/params.c
29866--- linux-2.6.22.1/kernel/params.c 2007-07-10 14:56:30.000000000 -0400
29867+++ linux-2.6.22.1/kernel/params.c 2007-08-02 11:38:48.000000000 -0400
29868@@ -275,7 +275,7 @@ static int param_array(const char *name,
29869 unsigned int min, unsigned int max,
29870 void *elem, int elemsize,
29871 int (*set)(const char *, struct kernel_param *kp),
29872- int *num)
29873+ unsigned int *num)
29874 {
29875 int ret;
29876 struct kernel_param kp;
29877diff -urNp linux-2.6.22.1/kernel/pid.c linux-2.6.22.1/kernel/pid.c
29878--- linux-2.6.22.1/kernel/pid.c 2007-07-10 14:56:30.000000000 -0400
29879+++ linux-2.6.22.1/kernel/pid.c 2007-08-02 11:38:48.000000000 -0400
29880@@ -29,6 +29,7 @@
29881 #include <linux/pid_namespace.h>
29882 #include <linux/init_task.h>
29883 #include <linux/vs_pid.h>
29884+#include <linux/grsecurity.h>
29885
29886 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
29887 static struct hlist_head *pid_hash;
29888@@ -38,7 +39,7 @@ struct pid init_struct_pid = INIT_STRUCT
29889
29890 int pid_max = PID_MAX_DEFAULT;
29891
29892-#define RESERVED_PIDS 300
29893+#define RESERVED_PIDS 500
29894
29895 int pid_max_min = RESERVED_PIDS + 1;
29896 int pid_max_max = PID_MAX_LIMIT;
29897@@ -319,6 +320,10 @@ struct task_struct *find_task_by_pid_typ
29898 nr = vx_rmap_pid(nr);
29899
29900 task = pid_task(find_pid(nr), type);
29901+
29902+ if (gr_pid_is_chrooted(task))
29903+ return NULL;
29904+
29905 if (task && (type != PIDTYPE_REALPID) &&
29906 /* maybe VS_WATCH_P in the future? */
29907 !vx_check(task->xid, VS_WATCH|VS_IDENT))
29908diff -urNp linux-2.6.22.1/kernel/posix-cpu-timers.c linux-2.6.22.1/kernel/posix-cpu-timers.c
29909--- linux-2.6.22.1/kernel/posix-cpu-timers.c 2007-07-10 14:56:30.000000000 -0400
29910+++ linux-2.6.22.1/kernel/posix-cpu-timers.c 2007-08-02 11:09:16.000000000 -0400
29911@@ -6,6 +6,7 @@
29912 #include <linux/posix-timers.h>
29913 #include <asm/uaccess.h>
29914 #include <linux/errno.h>
29915+#include <linux/grsecurity.h>
29916
29917 static int check_clock(const clockid_t which_clock)
29918 {
29919@@ -1144,6 +1145,7 @@ static void check_process_timers(struct
29920 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
29921 return;
29922 }
29923+ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
29924 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
29925 /*
29926 * At the soft limit, send a SIGXCPU every second.
29927diff -urNp linux-2.6.22.1/kernel/power/poweroff.c linux-2.6.22.1/kernel/power/poweroff.c
29928--- linux-2.6.22.1/kernel/power/poweroff.c 2007-07-10 14:56:30.000000000 -0400
29929+++ linux-2.6.22.1/kernel/power/poweroff.c 2007-08-02 11:38:48.000000000 -0400
29930@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
29931 .enable_mask = SYSRQ_ENABLE_BOOT,
29932 };
29933
29934-static int pm_sysrq_init(void)
29935+static int __init pm_sysrq_init(void)
29936 {
29937 register_sysrq_key('o', &sysrq_poweroff_op);
29938 return 0;
29939diff -urNp linux-2.6.22.1/kernel/printk.c linux-2.6.22.1/kernel/printk.c
29940--- linux-2.6.22.1/kernel/printk.c 2007-07-10 14:56:30.000000000 -0400
29941+++ linux-2.6.22.1/kernel/printk.c 2007-08-02 11:09:16.000000000 -0400
29942@@ -31,6 +31,7 @@
29943 #include <linux/jiffies.h>
29944 #include <linux/suspend.h>
29945 #include <linux/vs_cvirt.h>
29946+#include <linux/grsecurity.h>
29947
29948 #include <asm/uaccess.h>
29949
29950@@ -186,6 +187,11 @@ int do_syslog(int type, char __user *buf
29951 char c;
29952 int error;
29953
29954+#ifdef CONFIG_GRKERNSEC_DMESG
29955+ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
29956+ return -EPERM;
29957+#endif
29958+
29959 error = security_syslog(type);
29960 if (error)
29961 return error;
29962diff -urNp linux-2.6.22.1/kernel/ptrace.c linux-2.6.22.1/kernel/ptrace.c
29963--- linux-2.6.22.1/kernel/ptrace.c 2007-07-10 14:56:30.000000000 -0400
29964+++ linux-2.6.22.1/kernel/ptrace.c 2007-08-02 11:11:54.000000000 -0400
29965@@ -19,6 +19,7 @@
29966 #include <linux/signal.h>
29967 #include <linux/audit.h>
29968 #include <linux/vs_context.h>
29969+#include <linux/grsecurity.h>
29970
29971 #include <asm/pgtable.h>
29972 #include <asm/uaccess.h>
29973@@ -139,12 +140,12 @@ static int may_attach(struct task_struct
29974 (current->uid != task->uid) ||
29975 (current->gid != task->egid) ||
29976 (current->gid != task->sgid) ||
29977- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
29978+ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
29979 return -EPERM;
29980 smp_rmb();
29981 if (task->mm)
29982 dumpable = task->mm->dumpable;
29983- if (!dumpable && !capable(CAP_SYS_PTRACE))
29984+ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
29985 return -EPERM;
29986 if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
29987 return -EPERM;
29988@@ -490,6 +491,11 @@ asmlinkage long sys_ptrace(long request,
29989 if (ret < 0)
29990 goto out_put_task_struct;
29991
29992+ if (gr_handle_ptrace(child, request)) {
29993+ ret = -EPERM;
29994+ goto out_put_task_struct;
29995+ }
29996+
29997 ret = arch_ptrace(child, request, addr, data);
29998 if (ret < 0)
29999 goto out_put_task_struct;
30000diff -urNp linux-2.6.22.1/kernel/rcupdate.c linux-2.6.22.1/kernel/rcupdate.c
30001--- linux-2.6.22.1/kernel/rcupdate.c 2007-07-10 14:56:30.000000000 -0400
30002+++ linux-2.6.22.1/kernel/rcupdate.c 2007-08-02 11:38:48.000000000 -0400
30003@@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
30004 .cpumask = CPU_MASK_NONE,
30005 };
30006
30007-DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
30008-DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
30009+DEFINE_PER_CPU(struct rcu_data, rcu_data);
30010+DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
30011
30012 /* Fake initialization required by compiler */
30013-static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
30014+static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
30015 static int blimit = 10;
30016 static int qhimark = 10000;
30017 static int qlowmark = 100;
30018diff -urNp linux-2.6.22.1/kernel/resource.c linux-2.6.22.1/kernel/resource.c
30019--- linux-2.6.22.1/kernel/resource.c 2007-07-10 14:56:30.000000000 -0400
30020+++ linux-2.6.22.1/kernel/resource.c 2007-08-02 11:09:16.000000000 -0400
30021@@ -133,10 +133,27 @@ static int __init ioresources_init(void)
30022 {
30023 struct proc_dir_entry *entry;
30024
30025+#ifdef CONFIG_GRKERNSEC_PROC_ADD
30026+#ifdef CONFIG_GRKERNSEC_PROC_USER
30027+ entry = create_proc_entry("ioports", S_IRUSR, NULL);
30028+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
30029+ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
30030+#endif
30031+#else
30032 entry = create_proc_entry("ioports", 0, NULL);
30033+#endif
30034 if (entry)
30035 entry->proc_fops = &proc_ioports_operations;
30036+
30037+#ifdef CONFIG_GRKERNSEC_PROC_ADD
30038+#ifdef CONFIG_GRKERNSEC_PROC_USER
30039+ entry = create_proc_entry("iomem", S_IRUSR, NULL);
30040+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
30041+ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
30042+#endif
30043+#else
30044 entry = create_proc_entry("iomem", 0, NULL);
30045+#endif
30046 if (entry)
30047 entry->proc_fops = &proc_iomem_operations;
30048 return 0;
30049diff -urNp linux-2.6.22.1/kernel/sched.c linux-2.6.22.1/kernel/sched.c
30050--- linux-2.6.22.1/kernel/sched.c 2007-07-10 14:56:30.000000000 -0400
30051+++ linux-2.6.22.1/kernel/sched.c 2007-08-02 11:38:48.000000000 -0400
30052@@ -53,6 +53,7 @@
30053 #include <linux/kprobes.h>
30054 #include <linux/delayacct.h>
30055 #include <linux/reciprocal_div.h>
30056+#include <linux/grsecurity.h>
30057
30058 #include <asm/tlb.h>
30059 #include <asm/unistd.h>
30060@@ -3571,7 +3572,7 @@ asmlinkage void __sched schedule(void)
30061 unsigned long long now;
30062 unsigned long run_time;
30063 int cpu, idx, new_prio;
30064- long *switch_count;
30065+ unsigned long *switch_count;
30066 struct rq *rq;
30067
30068 /*
30069@@ -4262,7 +4263,8 @@ asmlinkage long sys_nice(int increment)
30070 if (nice > 19)
30071 nice = 19;
30072
30073- if (increment < 0 && !can_nice(current, nice))
30074+ if (increment < 0 && (!can_nice(current, nice) ||
30075+ gr_handle_chroot_nice()))
30076 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
30077
30078 retval = security_task_setnice(current, nice);
30079diff -urNp linux-2.6.22.1/kernel/signal.c linux-2.6.22.1/kernel/signal.c
30080--- linux-2.6.22.1/kernel/signal.c 2007-07-10 14:56:30.000000000 -0400
30081+++ linux-2.6.22.1/kernel/signal.c 2007-08-02 11:13:50.000000000 -0400
30082@@ -25,6 +25,7 @@
30083 #include <linux/capability.h>
30084 #include <linux/freezer.h>
30085 #include <linux/pid_namespace.h>
30086+#include <linux/grsecurity.h>
30087 #include <linux/nsproxy.h>
30088 #include <linux/vs_context.h>
30089 #include <linux/vs_pid.h>
30090@@ -538,11 +539,11 @@ static int check_kill_permission(int sig
30091 return error;
30092
30093 error = -EPERM;
30094- if (((sig != SIGCONT) ||
30095+ if ((((sig != SIGCONT) ||
30096 (process_session(current) != process_session(t)))
30097 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
30098 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
30099- && !capable(CAP_KILL))
30100+ && !capable(CAP_KILL)) || gr_handle_signal(t, sig))
30101 return error;
30102
30103 error = -ESRCH;
30104@@ -736,7 +737,7 @@ out_set:
30105 (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
30106
30107
30108-static int
30109+int
30110 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
30111 {
30112 int ret = 0;
30113@@ -773,6 +774,10 @@ force_sig_info(int sig, struct siginfo *
30114 }
30115 }
30116 ret = specific_send_sig_info(sig, info, t);
30117+
30118+ gr_log_signal(sig, t);
30119+ gr_handle_crash(t, sig);
30120+
30121 spin_unlock_irqrestore(&t->sighand->siglock, flags);
30122
30123 return ret;
30124diff -urNp linux-2.6.22.1/kernel/softirq.c linux-2.6.22.1/kernel/softirq.c
30125--- linux-2.6.22.1/kernel/softirq.c 2007-07-10 14:56:30.000000000 -0400
30126+++ linux-2.6.22.1/kernel/softirq.c 2007-08-02 11:38:48.000000000 -0400
30127@@ -470,9 +470,9 @@ void tasklet_kill(struct tasklet_struct
30128 printk("Attempt to kill tasklet from interrupt\n");
30129
30130 while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
30131- do
30132+ do {
30133 yield();
30134- while (test_bit(TASKLET_STATE_SCHED, &t->state));
30135+ } while (test_bit(TASKLET_STATE_SCHED, &t->state));
30136 }
30137 tasklet_unlock_wait(t);
30138 clear_bit(TASKLET_STATE_SCHED, &t->state);
30139diff -urNp linux-2.6.22.1/kernel/sys.c linux-2.6.22.1/kernel/sys.c
30140--- linux-2.6.22.1/kernel/sys.c 2007-07-10 14:56:30.000000000 -0400
30141+++ linux-2.6.22.1/kernel/sys.c 2007-08-02 11:38:48.000000000 -0400
30142@@ -31,6 +31,7 @@
dc0c7929 30143 #include <linux/cn_proc.h>
3ba9fddb 30144 #include <linux/getcpu.h>
30145 #include <linux/task_io_accounting_ops.h>
30146+#include <linux/grsecurity.h>
30147
30148 #include <linux/compat.h>
30149 #include <linux/syscalls.h>
30150@@ -641,6 +642,12 @@ static int set_one_prio(struct task_stru
30151 error = -EACCES;
30152 goto out;
30153 }
30154+
30155+ if (gr_handle_chroot_setpriority(p, niceval)) {
30156+ error = -EACCES;
30157+ goto out;
30158+ }
30159+
30160 no_nice = security_task_setnice(p, niceval);
30161 if (no_nice) {
30162 error = no_nice;
30163@@ -697,10 +704,10 @@ asmlinkage long sys_setpriority(int whic
30164 !(user = find_user(vx_current_xid(), who)))
30165 goto out_unlock; /* No processes for this user */
30166
30167- do_each_thread(g, p)
30168+ do_each_thread(g, p) {
30169 if (p->uid == who)
30170 error = set_one_prio(p, niceval, error);
30171- while_each_thread(g, p);
30172+ } while_each_thread(g, p);
30173 if (who != current->uid)
30174 free_uid(user); /* For find_user() */
30175 break;
30176@@ -759,13 +766,13 @@ asmlinkage long sys_getpriority(int whic
30177 !(user = find_user(vx_current_xid(), who)))
30178 goto out_unlock; /* No processes for this user */
30179
30180- do_each_thread(g, p)
30181+ do_each_thread(g, p) {
30182 if (p->uid == who) {
30183 niceval = 20 - task_nice(p);
30184 if (niceval > retval)
30185 retval = niceval;
30186 }
30187- while_each_thread(g, p);
30188+ } while_each_thread(g, p);
30189 if (who != current->uid)
30190 free_uid(user); /* for find_user() */
30191 break;
30192@@ -1031,6 +1038,9 @@ asmlinkage long sys_setregid(gid_t rgid,
30193 if (rgid != (gid_t) -1 ||
30194 (egid != (gid_t) -1 && egid != old_rgid))
30195 current->sgid = new_egid;
30196+
30197+ gr_set_role_label(current, current->uid, new_rgid);
30198+
30199 current->fsgid = new_egid;
30200 current->egid = new_egid;
30201 current->gid = new_rgid;
30202@@ -1058,6 +1068,9 @@ asmlinkage long sys_setgid(gid_t gid)
30203 current->mm->dumpable = suid_dumpable;
30204 smp_wmb();
30205 }
30206+
30207+ gr_set_role_label(current, current->uid, gid);
30208+
30209 current->gid = current->egid = current->sgid = current->fsgid = gid;
30210 } else if ((gid == current->gid) || (gid == current->sgid)) {
30211 if (old_egid != gid) {
30212@@ -1095,6 +1108,9 @@ static int set_user(uid_t new_ruid, int
30213 current->mm->dumpable = suid_dumpable;
30214 smp_wmb();
30215 }
30216+
30217+ gr_set_role_label(current, new_ruid, current->gid);
30218+
30219 current->uid = new_ruid;
30220 return 0;
30221 }
30222@@ -1197,6 +1213,9 @@ asmlinkage long sys_setuid(uid_t uid)
30223 } else if ((uid != current->uid) && (uid != new_suid))
30224 return -EPERM;
30225
30226+ if (gr_check_crash_uid(uid))
30227+ return -EPERM;
30228+
30229 if (old_euid != uid) {
30230 current->mm->dumpable = suid_dumpable;
30231 smp_wmb();
30232@@ -1299,8 +1318,10 @@ asmlinkage long sys_setresgid(gid_t rgid
30233 current->egid = egid;
30234 }
30235 current->fsgid = current->egid;
30236- if (rgid != (gid_t) -1)
30237+ if (rgid != (gid_t) -1) {
30238+ gr_set_role_label(current, current->uid, rgid);
30239 current->gid = rgid;
30240+ }
30241 if (sgid != (gid_t) -1)
30242 current->sgid = sgid;
30243
30244@@ -1448,7 +1469,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
30245 write_lock_irq(&tasklist_lock);
30246
30247 err = -ESRCH;
30248- p = find_task_by_pid(pid);
30249+ /* grsec: replaced find_task_by_pid with equivalent call
30250+ which lacks the chroot restriction
30251+ */
30252+ p = pid_task(find_pid(pid), PIDTYPE_PID);
30253 if (!p)
30254 goto out;
30255
30256@@ -2168,7 +2192,7 @@ asmlinkage long sys_prctl(int option, un
30257 error = current->mm->dumpable;
30258 break;
30259 case PR_SET_DUMPABLE:
30260- if (arg2 < 0 || arg2 > 1) {
30261+ if (arg2 > 1) {
30262 error = -EINVAL;
30263 break;
30264 }
30265diff -urNp linux-2.6.22.1/kernel/sysctl.c linux-2.6.22.1/kernel/sysctl.c
30266--- linux-2.6.22.1/kernel/sysctl.c 2007-07-10 14:56:30.000000000 -0400
30267+++ linux-2.6.22.1/kernel/sysctl.c 2007-08-02 11:38:48.000000000 -0400
30268@@ -58,6 +58,13 @@ extern int proc_nr_files(ctl_table *tabl
30269 #endif
30270
30271 #if defined(CONFIG_SYSCTL)
30272+#include <linux/grsecurity.h>
30273+#include <linux/grinternal.h>
30274+
30275+extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
30276+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
30277+ const int op);
30278+extern int gr_handle_chroot_sysctl(const int op);
30279
30280 /* External variables not in a header file. */
30281 extern int C_A_D;
30282@@ -141,7 +148,7 @@ static int proc_dointvec_taint(ctl_table
30283
30284 static ctl_table root_table[];
30285 static struct ctl_table_header root_table_header =
30286- { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
30287+ { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
30288
30289 static ctl_table kern_table[];
30290 static ctl_table vm_table[];
30291@@ -155,11 +162,26 @@ extern ctl_table pty_table[];
30292 #ifdef CONFIG_INOTIFY_USER
30293 extern ctl_table inotify_table[];
30294 #endif
30295+extern ctl_table grsecurity_table[];
30296
30297 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
30298 int sysctl_legacy_va_layout;
30299 #endif
30300
30301+#ifdef CONFIG_PAX_SOFTMODE
30302+static ctl_table pax_table[] = {
30303+ {
30304+ .ctl_name = PAX_SOFTMODE,
30305+ .procname = "softmode",
30306+ .data = &pax_softmode,
30307+ .maxlen = sizeof(unsigned int),
30308+ .mode = 0600,
30309+ .proc_handler = &proc_dointvec,
30310+ },
30311+
30312+ { .ctl_name = 0 }
30313+};
30314+#endif
30315
30316 /* The default sysctl tables: */
30317
30318@@ -202,7 +224,6 @@ static ctl_table root_table[] = {
30319 .mode = 0555,
30320 .child = dev_table,
30321 },
30322-
30323 { .ctl_name = 0 }
30324 };
30325
30326@@ -616,6 +637,24 @@ static ctl_table kern_table[] = {
30327 },
30328 #endif
30329
30330+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
30331+ {
30332+ .ctl_name = KERN_GRSECURITY,
30333+ .procname = "grsecurity",
30334+ .mode = 0500,
30335+ .child = grsecurity_table,
30336+ },
30337+#endif
30338+
30339+#ifdef CONFIG_PAX_SOFTMODE
30340+ {
30341+ .ctl_name = KERN_PAX,
30342+ .procname = "pax",
30343+ .mode = 0500,
30344+ .child = pax_table,
30345+ },
30346+#endif
30347+
30348 { .ctl_name = 0 }
30349 };
30350
30351@@ -1172,6 +1211,25 @@ static int test_perm(int mode, int op)
30352 int sysctl_perm(ctl_table *table, int op)
30353 {
30354 int error;
30355+ if (table->parent != NULL && table->parent->procname != NULL &&
30356+ table->procname != NULL &&
30357+ gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
30358+ return -EACCES;
30359+ if (gr_handle_chroot_sysctl(op))
30360+ return -EACCES;
30361+ error = gr_handle_sysctl(table, op);
30362+ if (error)
30363+ return error;
30364+ error = security_sysctl(table, op);
30365+ if (error)
30366+ return error;
30367+ return test_perm(table->mode, op);
30368+}
30369+
30370+int sysctl_perm_nochk(ctl_table *table, int op)
30371+{
30372+ int error;
30373+
30374 error = security_sysctl(table, op);
30375 if (error)
30376 return error;
30377@@ -1196,13 +1254,14 @@ repeat:
30378 if (n == table->ctl_name) {
30379 int error;
30380 if (table->child) {
30381- if (sysctl_perm(table, 001))
30382+ if (sysctl_perm_nochk(table, 001))
30383 return -EPERM;
30384 name++;
30385 nlen--;
30386 table = table->child;
30387 goto repeat;
30388 }
30389+
30390 error = do_sysctl_strategy(table, name, nlen,
30391 oldval, oldlenp,
30392 newval, newlen);
30393diff -urNp linux-2.6.22.1/kernel/time.c linux-2.6.22.1/kernel/time.c
30394--- linux-2.6.22.1/kernel/time.c 2007-07-10 14:56:30.000000000 -0400
30395+++ linux-2.6.22.1/kernel/time.c 2007-08-02 11:38:48.000000000 -0400
30396@@ -35,6 +35,7 @@
30397 #include <linux/security.h>
30398 #include <linux/fs.h>
30399 #include <linux/module.h>
30400+#include <linux/grsecurity.h>
30401
30402 #include <asm/uaccess.h>
30403 #include <asm/unistd.h>
30404@@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user
30405 return err;
30406
30407 vx_settimeofday(&tv);
30408+
30409+ gr_log_timechange();
30410+
30411 return 0;
30412 }
30413
30414@@ -198,6 +202,8 @@ asmlinkage long sys_settimeofday(struct
30415 return -EFAULT;
30416 }
30417
30418+ gr_log_timechange();
30419+
30420 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
30421 }
30422
30423@@ -252,7 +258,7 @@ EXPORT_SYMBOL(current_fs_time);
30424 * Avoid unnecessary multiplications/divisions in the
30425 * two most common HZ cases:
30426 */
30427-unsigned int inline jiffies_to_msecs(const unsigned long j)
30428+inline unsigned int jiffies_to_msecs(const unsigned long j)
30429 {
30430 #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
30431 return (MSEC_PER_SEC / HZ) * j;
30432@@ -264,7 +270,7 @@ unsigned int inline jiffies_to_msecs(con
30433 }
30434 EXPORT_SYMBOL(jiffies_to_msecs);
30435
30436-unsigned int inline jiffies_to_usecs(const unsigned long j)
30437+inline unsigned int jiffies_to_usecs(const unsigned long j)
30438 {
30439 #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
30440 return (USEC_PER_SEC / HZ) * j;
30441diff -urNp linux-2.6.22.1/lib/extable.c linux-2.6.22.1/lib/extable.c
30442--- linux-2.6.22.1/lib/extable.c 2007-07-10 14:56:30.000000000 -0400
30443+++ linux-2.6.22.1/lib/extable.c 2007-08-02 11:38:48.000000000 -0400
30444@@ -36,8 +36,20 @@ static int cmp_ex(const void *a, const v
30445 void sort_extable(struct exception_table_entry *start,
30446 struct exception_table_entry *finish)
30447 {
30448+
30449+#ifdef CONFIG_PAX_KERNEXEC
30450+ unsigned long cr0;
30451+
30452+ pax_open_kernel(cr0);
30453+#endif
30454+
30455 sort(start, finish - start, sizeof(struct exception_table_entry),
30456 cmp_ex, NULL);
30457+
30458+#ifdef CONFIG_PAX_KERNEXEC
30459+ pax_close_kernel(cr0);
30460+#endif
30461+
30462 }
30463 #endif
30464
30465diff -urNp linux-2.6.22.1/lib/radix-tree.c linux-2.6.22.1/lib/radix-tree.c
30466--- linux-2.6.22.1/lib/radix-tree.c 2007-07-10 14:56:30.000000000 -0400
30467+++ linux-2.6.22.1/lib/radix-tree.c 2007-08-02 11:38:48.000000000 -0400
30468@@ -76,7 +76,7 @@ struct radix_tree_preload {
30469 int nr;
30470 struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
30471 };
30472-DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
30473+DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
30474
30475 static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
30476 {
30477diff -urNp linux-2.6.22.1/localversion-grsec linux-2.6.22.1/localversion-grsec
30478--- linux-2.6.22.1/localversion-grsec 1969-12-31 19:00:00.000000000 -0500
30479+++ linux-2.6.22.1/localversion-grsec 2007-08-02 11:09:16.000000000 -0400
30480@@ -0,0 +1 @@
30481+-grsec
30482diff -urNp linux-2.6.22.1/Makefile linux-2.6.22.1/Makefile
30483--- linux-2.6.22.1/Makefile 2007-07-10 14:56:30.000000000 -0400
30484+++ linux-2.6.22.1/Makefile 2007-08-02 11:38:45.000000000 -0400
30485@@ -312,7 +312,7 @@ LINUXINCLUDE := -Iinclude \
30486
30487 CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
30488
30489-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
30490+CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
30491 -fno-strict-aliasing -fno-common
30492 AFLAGS := -D__ASSEMBLY__
30493
30494@@ -553,7 +553,7 @@ export mod_strip_cmd
30495
30496
30497 ifeq ($(KBUILD_EXTMOD),)
30498-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
30499+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
30500
30501 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
30502 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
30503diff -urNp linux-2.6.22.1/mm/filemap.c linux-2.6.22.1/mm/filemap.c
30504--- linux-2.6.22.1/mm/filemap.c 2007-07-10 14:56:30.000000000 -0400
30505+++ linux-2.6.22.1/mm/filemap.c 2007-08-02 11:38:48.000000000 -0400
30506@@ -30,6 +30,7 @@
e22ecf05 30507 #include <linux/security.h>
3ba9fddb 30508 #include <linux/syscalls.h>
30509 #include <linux/cpuset.h>
30510+#include <linux/grsecurity.h>
30511 #include "filemap.h"
30512 #include "internal.h"
30513
30514@@ -1704,7 +1705,7 @@ int generic_file_mmap(struct file * file
30515 struct address_space *mapping = file->f_mapping;
30516
30517 if (!mapping->a_ops->readpage)
30518- return -ENOEXEC;
30519+ return -ENODEV;
30520 file_accessed(file);
30521 vma->vm_ops = &generic_file_vm_ops;
30522 return 0;
30523@@ -1968,6 +1969,7 @@ inline int generic_write_checks(struct f
30524 *pos = i_size_read(inode);
30525
30526 if (limit != RLIM_INFINITY) {
30527+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
30528 if (*pos >= limit) {
30529 send_sig(SIGXFSZ, current, 0);
30530 return -EFBIG;
30531diff -urNp linux-2.6.22.1/mm/fremap.c linux-2.6.22.1/mm/fremap.c
30532--- linux-2.6.22.1/mm/fremap.c 2007-07-10 14:56:30.000000000 -0400
30533+++ linux-2.6.22.1/mm/fremap.c 2007-08-02 11:38:48.000000000 -0400
30534@@ -84,6 +84,11 @@ int install_page(struct mm_struct *mm, s
30535 page_add_file_rmap(page);
30536 update_mmu_cache(vma, addr, pte_val);
30537 lazy_mmu_prot_update(pte_val);
30538+
30539+#ifdef CONFIG_PAX_SEGMEXEC
30540+ pax_mirror_file_pte(vma, addr, page, ptl);
30541+#endif
30542+
30543 err = 0;
30544 unlock:
30545 pte_unmap_unlock(pte, ptl);
30546@@ -177,6 +182,13 @@ asmlinkage long sys_remap_file_pages(uns
30547 retry:
30548 vma = find_vma(mm, start);
30549
30550+#ifdef CONFIG_PAX_SEGMEXEC
30551+ if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
30552+ up_read(&mm->mmap_sem);
30553+ return err;
30554+ }
30555+#endif
30556+
30557 /*
30558 * Make sure the vma is shared, that it supports prefaulting,
30559 * and that the remapped range is valid and fully within
30560diff -urNp linux-2.6.22.1/mm/hugetlb.c linux-2.6.22.1/mm/hugetlb.c
30561--- linux-2.6.22.1/mm/hugetlb.c 2007-07-10 14:56:30.000000000 -0400
30562+++ linux-2.6.22.1/mm/hugetlb.c 2007-08-02 11:38:48.000000000 -0400
30563@@ -433,6 +433,26 @@ void unmap_hugepage_range(struct vm_area
30564 }
30565 }
30566
30567+#ifdef CONFIG_PAX_SEGMEXEC
30568+static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
30569+{
30570+ struct mm_struct *mm = vma->vm_mm;
30571+ struct vm_area_struct *vma_m;
30572+ unsigned long address_m;
30573+ pte_t *ptep_m;
30574+
30575+ vma_m = pax_find_mirror_vma(vma);
30576+ if (!vma_m)
30577+ return;
30578+
30579+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
30580+ address_m = address + SEGMEXEC_TASK_SIZE;
30581+ ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
30582+ get_page(page_m);
30583+ set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
30584+}
30585+#endif
30586+
30587 static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
30588 unsigned long address, pte_t *ptep, pte_t pte)
30589 {
30590@@ -466,6 +486,11 @@ static int hugetlb_cow(struct mm_struct
30591 /* Break COW */
30592 set_huge_pte_at(mm, address, ptep,
30593 make_huge_pte(vma, new_page, 1));
30594+
30595+#ifdef CONFIG_PAX_SEGMEXEC
30596+ pax_mirror_huge_pte(vma, address, new_page);
30597+#endif
30598+
30599 /* Make the old page be freed below */
30600 new_page = old_page;
30601 }
30602@@ -474,7 +499,7 @@ static int hugetlb_cow(struct mm_struct
30603 return VM_FAULT_MINOR;
30604 }
30605
30606-int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
30607+static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
30608 unsigned long address, pte_t *ptep, int write_access)
30609 {
30610 int ret = VM_FAULT_SIGBUS;
30611@@ -536,6 +561,10 @@ retry:
30612 && (vma->vm_flags & VM_SHARED)));
30613 set_huge_pte_at(mm, address, ptep, new_pte);
30614
30615+#ifdef CONFIG_PAX_SEGMEXEC
30616+ pax_mirror_huge_pte(vma, address, page);
30617+#endif
30618+
30619 if (write_access && !(vma->vm_flags & VM_SHARED)) {
30620 /* Optimization, do the COW without a second fault */
30621 ret = hugetlb_cow(mm, vma, address, ptep, new_pte);
30622@@ -562,6 +591,27 @@ int hugetlb_fault(struct mm_struct *mm,
30623 int ret;
30624 static DEFINE_MUTEX(hugetlb_instantiation_mutex);
30625
30626+#ifdef CONFIG_PAX_SEGMEXEC
30627+ struct vm_area_struct *vma_m;
30628+
30629+ vma_m = pax_find_mirror_vma(vma);
30630+ if (vma_m) {
30631+ unsigned long address_m;
30632+
30633+ if (vma->vm_start > vma_m->vm_start) {
30634+ address_m = address;
30635+ address -= SEGMEXEC_TASK_SIZE;
30636+ vma = vma_m;
30637+ } else
30638+ address_m = address + SEGMEXEC_TASK_SIZE;
30639+
30640+ if (!huge_pte_alloc(mm, address_m))
30641+ return VM_FAULT_OOM;
30642+ address_m &= HPAGE_MASK;
30643+ unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE);
30644+ }
30645+#endif
30646+
30647 ptep = huge_pte_alloc(mm, address);
30648 if (!ptep)
30649 return VM_FAULT_OOM;
30650diff -urNp linux-2.6.22.1/mm/madvise.c linux-2.6.22.1/mm/madvise.c
30651--- linux-2.6.22.1/mm/madvise.c 2007-07-10 14:56:30.000000000 -0400
30652+++ linux-2.6.22.1/mm/madvise.c 2007-08-02 11:38:48.000000000 -0400
30653@@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
30654 pgoff_t pgoff;
30655 int new_flags = vma->vm_flags;
30656
30657+#ifdef CONFIG_PAX_SEGMEXEC
30658+ struct vm_area_struct *vma_m;
30659+#endif
30660+
30661 switch (behavior) {
30662 case MADV_NORMAL:
30663 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
30664@@ -92,6 +96,13 @@ success:
30665 /*
30666 * vm_flags is protected by the mmap_sem held in write mode.
30667 */
30668+
30669+#ifdef CONFIG_PAX_SEGMEXEC
30670+ vma_m = pax_find_mirror_vma(vma);
30671+ if (vma_m)
30672+ vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
30673+#endif
30674+
30675 vma->vm_flags = new_flags;
30676
30677 out:
30678@@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma,
30679
30680 case MADV_DONTNEED:
30681 error = madvise_dontneed(vma, prev, start, end);
30682+
30683+#ifdef CONFIG_PAX_SEGMEXEC
30684+ if (!error) {
30685+ struct vm_area_struct *vma_m, *prev_m;
30686+
30687+ vma_m = pax_find_mirror_vma(vma);
30688+ if (vma_m)
30689+ error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
30690+ }
30691+#endif
30692+
30693 break;
30694
30695 default:
30696@@ -306,6 +328,16 @@ asmlinkage long sys_madvise(unsigned lon
30697 if (end < start)
30698 goto out;
30699
30700+#ifdef CONFIG_PAX_SEGMEXEC
30701+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
30702+ if (end > SEGMEXEC_TASK_SIZE)
30703+ goto out;
30704+ } else
30705+#endif
30706+
30707+ if (end > TASK_SIZE)
30708+ goto out;
30709+
30710 error = 0;
30711 if (end == start)
30712 goto out;
30713diff -urNp linux-2.6.22.1/mm/memory.c linux-2.6.22.1/mm/memory.c
30714--- linux-2.6.22.1/mm/memory.c 2007-07-10 14:56:30.000000000 -0400
30715+++ linux-2.6.22.1/mm/memory.c 2007-08-02 11:38:48.000000000 -0400
30716@@ -50,6 +50,7 @@
30717 #include <linux/delayacct.h>
30718 #include <linux/init.h>
30719 #include <linux/writeback.h>
30720+#include <linux/grsecurity.h>
30721
30722 #include <asm/pgalloc.h>
30723 #include <asm/uaccess.h>
30724@@ -322,6 +323,11 @@ int __pte_alloc(struct mm_struct *mm, pm
30725
30726 int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
30727 {
30728+
30729+#ifdef CONFIG_PAX_KERNEXEC
30730+ unsigned long cr0;
30731+#endif
30732+
30733 pte_t *new = pte_alloc_one_kernel(&init_mm, address);
30734 if (!new)
30735 return -ENOMEM;
30736@@ -329,8 +335,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
30737 spin_lock(&init_mm.page_table_lock);
30738 if (pmd_present(*pmd)) /* Another has populated it */
30739 pte_free_kernel(new);
30740- else
30741+ else {
30742+
30743+#ifdef CONFIG_PAX_KERNEXEC
30744+ pax_open_kernel(cr0);
30745+#endif
30746+
30747 pmd_populate_kernel(&init_mm, pmd, new);
30748+
30749+#ifdef CONFIG_PAX_KERNEXEC
30750+ pax_close_kernel(cr0);
30751+#endif
30752+
30753+ }
30754 spin_unlock(&init_mm.page_table_lock);
30755 return 0;
30756 }
30757@@ -995,7 +1012,7 @@ int get_user_pages(struct task_struct *t
30758 struct vm_area_struct *vma;
30759 unsigned int foll_flags;
30760
30761- vma = find_extend_vma(mm, start);
30762+ vma = find_vma(mm, start);
30763 if (!vma && in_gate_area(tsk, start)) {
30764 unsigned long pg = start & PAGE_MASK;
30765 struct vm_area_struct *gate_vma = get_gate_vma(tsk);
30766@@ -1035,7 +1052,7 @@ int get_user_pages(struct task_struct *t
30767 continue;
30768 }
30769
30770- if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
30771+ if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
30772 || !(vm_flags & vma->vm_flags))
30773 return i ? : -EFAULT;
30774
30775@@ -1608,6 +1625,193 @@ static inline void cow_user_page(struct
30776 copy_user_highpage(dst, src, va, vma);
30777 }
30778
30779+#ifdef CONFIG_PAX_SEGMEXEC
30780+static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
30781+{
30782+ struct mm_struct *mm = vma->vm_mm;
30783+ spinlock_t *ptl;
30784+ pte_t *pte, entry;
30785+
30786+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
30787+ entry = *pte;
30788+ if (!pte_present(entry)) {
30789+ if (!pte_none(entry)) {
30790+ BUG_ON(pte_file(entry));
30791+ free_swap_and_cache(pte_to_swp_entry(entry));
30792+ pte_clear_not_present_full(mm, address, pte, 0);
30793+ }
30794+ } else {
30795+ struct page *page;
30796+
30797+ page = vm_normal_page(vma, address, entry);
30798+ if (page) {
30799+ flush_cache_page(vma, address, pte_pfn(entry));
30800+ flush_icache_page(vma, page);
30801+ }
30802+ ptep_clear_flush(vma, address, pte);
30803+ BUG_ON(pte_dirty(entry));
30804+ if (page) {
30805+ update_hiwater_rss(mm);
30806+ if (PageAnon(page))
30807+ dec_mm_counter(mm, anon_rss);
30808+ else
30809+ dec_mm_counter(mm, file_rss);
30810+ page_remove_rmap(page, vma);
30811+ page_cache_release(page);
30812+ }
30813+ }
30814+ pte_unmap_unlock(pte, ptl);
30815+}
30816+
30817+/* PaX: if vma is mirrored, synchronize the mirror's PTE
30818+ *
30819+ * the ptl of the lower mapped page is held on entry and is not released on exit
30820+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
30821+ */
30822+static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
30823+{
30824+ struct mm_struct *mm = vma->vm_mm;
30825+ unsigned long address_m;
30826+ spinlock_t *ptl_m;
30827+ struct vm_area_struct *vma_m;
30828+ pmd_t *pmd_m;
30829+ pte_t *pte_m, entry_m;
30830+
30831+ BUG_ON(!page_m || !PageAnon(page_m));
30832+
30833+ vma_m = pax_find_mirror_vma(vma);
30834+ if (!vma_m)
30835+ return;
30836+
30837+ BUG_ON(!PageLocked(page_m));
30838+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
30839+ address_m = address + SEGMEXEC_TASK_SIZE;
30840+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
30841+ pte_m = pte_offset_map_nested(pmd_m, address_m);
30842+ ptl_m = pte_lockptr(mm, pmd_m);
30843+ if (ptl != ptl_m) {
30844+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
30845+ if (!pte_none(*pte_m)) {
30846+ spin_unlock(ptl_m);
30847+ pte_unmap_nested(pte_m);
30848+ unlock_page(page_m);
30849+ return;
30850+ }
30851+ }
30852+
30853+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
30854+ page_cache_get(page_m);
30855+ page_add_anon_rmap(page_m, vma_m, address_m);
30856+ inc_mm_counter(mm, anon_rss);
30857+ set_pte_at(mm, address_m, pte_m, entry_m);
30858+ update_mmu_cache(vma_m, address_m, entry_m);
30859+ lazy_mmu_prot_update(entry_m);
30860+ if (ptl != ptl_m)
30861+ spin_unlock(ptl_m);
30862+ pte_unmap_nested(pte_m);
30863+ unlock_page(page_m);
30864+}
30865+
30866+void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
30867+{
30868+ struct mm_struct *mm = vma->vm_mm;
30869+ unsigned long address_m, pfn_m;
30870+ spinlock_t *ptl_m;
30871+ struct vm_area_struct *vma_m;
30872+ pmd_t *pmd_m;
30873+ pte_t *pte_m, entry_m;
30874+
30875+ BUG_ON(!page_m || PageAnon(page_m));
30876+
30877+ vma_m = pax_find_mirror_vma(vma);
30878+ if (!vma_m)
30879+ return;
30880+
30881+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
30882+ address_m = address + SEGMEXEC_TASK_SIZE;
30883+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
30884+ pte_m = pte_offset_map_nested(pmd_m, address_m);
30885+ ptl_m = pte_lockptr(mm, pmd_m);
30886+ if (ptl != ptl_m) {
30887+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
30888+ if (!pte_none(*pte_m)) {
30889+ spin_unlock(ptl_m);
30890+ pte_unmap_nested(pte_m);
30891+ return;
30892+ }
30893+ }
30894+
30895+ entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
30896+ page_cache_get(page_m);
30897+ page_add_file_rmap(page_m);
30898+ inc_mm_counter(mm, file_rss);
30899+ set_pte_at(mm, address_m, pte_m, entry_m);
30900+ update_mmu_cache(vma_m, address_m, entry_m);
30901+ lazy_mmu_prot_update(entry_m);
30902+ if (ptl != ptl_m)
30903+ spin_unlock(ptl_m);
30904+ pte_unmap_nested(pte_m);
30905+}
30906+
30907+static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
30908+{
30909+ struct mm_struct *mm = vma->vm_mm;
30910+ unsigned long address_m;
30911+ spinlock_t *ptl_m;
30912+ struct vm_area_struct *vma_m;
30913+ pmd_t *pmd_m;
30914+ pte_t *pte_m, entry_m;
30915+
30916+ vma_m = pax_find_mirror_vma(vma);
30917+ if (!vma_m)
30918+ return;
30919+
30920+ BUG_ON(address >= SEGMEXEC_TASK_SIZE);
30921+ address_m = address + SEGMEXEC_TASK_SIZE;
30922+ pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
30923+ pte_m = pte_offset_map_nested(pmd_m, address_m);
30924+ ptl_m = pte_lockptr(mm, pmd_m);
30925+ if (ptl != ptl_m) {
30926+ spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
30927+ if (!pte_none(*pte_m)) {
30928+ spin_unlock(ptl_m);
30929+ pte_unmap_nested(pte_m);
30930+ return;
30931+ }
30932+ }
30933+
30934+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
30935+ set_pte_at(mm, address_m, pte_m, entry_m);
30936+ if (ptl != ptl_m)
30937+ spin_unlock(ptl_m);
30938+ pte_unmap_nested(pte_m);
30939+}
30940+
30941+static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, spinlock_t *ptl)
30942+{
30943+ struct page *page_m;
30944+ pte_t entry;
30945+
30946+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
30947+ return;
30948+
30949+ entry = *pte;
30950+ page_m = vm_normal_page(vma, address, entry);
30951+ if (!page_m)
30952+ pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
30953+ if (PageAnon(page_m)) {
30954+ spin_unlock(ptl);
30955+ lock_page(page_m);
30956+ spin_lock(ptl);
30957+ if (pte_same(entry, *pte))
30958+ pax_mirror_anon_pte(vma, address, page_m, ptl);
30959+ else
30960+ unlock_page(page_m);
30961+ } else
30962+ pax_mirror_file_pte(vma, address, page_m, ptl);
30963+}
30964+#endif
30965+
30966 /*
30967 * This routine handles present pages, when users try to write
30968 * to a shared page. It is done by copying the page to a new address
30969@@ -1724,6 +1928,12 @@ gotten:
30970 */
30971 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
30972 if (likely(pte_same(*page_table, orig_pte))) {
30973+
30974+#ifdef CONFIG_PAX_SEGMEXEC
30975+ if (pax_find_mirror_vma(vma))
30976+ BUG_ON(TestSetPageLocked(new_page));
30977+#endif
30978+
30979 if (old_page) {
30980 page_remove_rmap(old_page, vma);
30981 if (!PageAnon(old_page)) {
30982@@ -1748,6 +1957,10 @@ gotten:
30983 lru_cache_add_active(new_page);
30984 page_add_new_anon_rmap(new_page, vma, address);
30985
30986+#ifdef CONFIG_PAX_SEGMEXEC
30987+ pax_mirror_anon_pte(vma, address, new_page, ptl);
30988+#endif
30989+
30990 /* Free the old page.. */
30991 new_page = old_page;
30992 ret |= VM_FAULT_WRITE;
30993@@ -2008,6 +2221,7 @@ int vmtruncate(struct inode * inode, lof
30994
30995 do_expand:
30996 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
30997+ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
30998 if (limit != RLIM_INFINITY && offset > limit)
30999 goto out_sig;
31000 if (offset > inode->i_sb->s_maxbytes)
31001@@ -2189,6 +2403,11 @@ static int do_swap_page(struct mm_struct
31002 swap_free(entry);
31003 if (vm_swap_full())
31004 remove_exclusive_swap_page(page);
31005+
31006+#ifdef CONFIG_PAX_SEGMEXEC
31007+ if (write_access || !pax_find_mirror_vma(vma))
31008+#endif
31009+
31010 unlock_page(page);
31011
31012 if (write_access) {
31013@@ -2201,6 +2420,11 @@ static int do_swap_page(struct mm_struct
31014 /* No need to invalidate - it was non-present before */
31015 update_mmu_cache(vma, address, pte);
31016 lazy_mmu_prot_update(pte);
31017+
31018+#ifdef CONFIG_PAX_SEGMEXEC
31019+ pax_mirror_anon_pte(vma, address, page, ptl);
31020+#endif
31021+
31022 unlock:
31023 pte_unmap_unlock(page_table, ptl);
31024 out:
31025@@ -2241,6 +2465,12 @@ static int do_anonymous_page(struct mm_s
31026 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
31027 if (!pte_none(*page_table))
31028 goto release;
31029+
31030+#ifdef CONFIG_PAX_SEGMEXEC
31031+ if (pax_find_mirror_vma(vma))
31032+ BUG_ON(TestSetPageLocked(page));
31033+#endif
31034+
31035 inc_mm_counter(mm, anon_rss);
31036 lru_cache_add_active(page);
31037 page_add_new_anon_rmap(page, vma, address);
31038@@ -2263,6 +2493,14 @@ static int do_anonymous_page(struct mm_s
31039 /* No need to invalidate - it was non-present before */
31040 update_mmu_cache(vma, address, entry);
31041 lazy_mmu_prot_update(entry);
31042+
31043+#ifdef CONFIG_PAX_SEGMEXEC
31044+ if (write_access)
31045+ pax_mirror_anon_pte(vma, address, page, ptl);
31046+ else
31047+ pax_mirror_file_pte(vma, address, page, ptl);
31048+#endif
31049+
31050 unlock:
31051 pte_unmap_unlock(page_table, ptl);
31052 return VM_FAULT_MINOR;
31053@@ -2382,6 +2620,12 @@ retry:
31054 */
31055 /* Only go through if we didn't race with anybody else... */
31056 if (pte_none(*page_table)) {
31057+
31058+#ifdef CONFIG_PAX_SEGMEXEC
31059+ if (anon && pax_find_mirror_vma(vma))
31060+ BUG_ON(TestSetPageLocked(new_page));
31061+#endif
31062+
31063 flush_icache_page(vma, new_page);
31064 entry = mk_pte(new_page, vma->vm_page_prot);
31065 if (write_access)
31066@@ -2408,6 +2651,14 @@ retry:
31067 /* no need to invalidate: a not-present page shouldn't be cached */
31068 update_mmu_cache(vma, address, entry);
31069 lazy_mmu_prot_update(entry);
31070+
31071+#ifdef CONFIG_PAX_SEGMEXEC
31072+ if (anon)
31073+ pax_mirror_anon_pte(vma, address, new_page, ptl);
31074+ else
31075+ pax_mirror_file_pte(vma, address, new_page, ptl);
31076+#endif
31077+
31078 unlock:
31079 pte_unmap_unlock(page_table, ptl);
31080 if (dirty_page) {
31081@@ -2465,6 +2716,11 @@ static noinline int do_no_pfn(struct mm_
31082 if (write_access)
31083 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
31084 set_pte_at(mm, address, page_table, entry);
31085+
31086+#ifdef CONFIG_PAX_SEGMEXEC
31087+ pax_mirror_pfn_pte(vma, address, pfn, ptl);
31088+#endif
31089+
31090 }
31091 pte_unmap_unlock(page_table, ptl);
31092 return ret;
31093@@ -2574,6 +2830,11 @@ static inline int handle_pte_fault(struc
31094 if (write_access)
31095 flush_tlb_page(vma, address);
31096 }
31097+
31098+#ifdef CONFIG_PAX_SEGMEXEC
31099+ pax_mirror_pte(vma, address, pte, ptl);
31100+#endif
31101+
31102 unlock:
31103 pte_unmap_unlock(pte, ptl);
31104 return VM_FAULT_MINOR;
31105@@ -2590,6 +2851,10 @@ int __handle_mm_fault(struct mm_struct *
31106 pmd_t *pmd;
31107 pte_t *pte;
31108
31109+#ifdef CONFIG_PAX_SEGMEXEC
31110+ struct vm_area_struct *vma_m;
31111+#endif
31112+
31113 __set_current_state(TASK_RUNNING);
31114
31115 count_vm_event(PGFAULT);
31116@@ -2597,6 +2862,34 @@ int __handle_mm_fault(struct mm_struct *
31117 if (unlikely(is_vm_hugetlb_page(vma)))
31118 return hugetlb_fault(mm, vma, address, write_access);
31119
31120+#ifdef CONFIG_PAX_SEGMEXEC
31121+ vma_m = pax_find_mirror_vma(vma);
31122+ if (vma_m) {
31123+ unsigned long address_m;
31124+ pgd_t *pgd_m;
31125+ pud_t *pud_m;
31126+ pmd_t *pmd_m;
31127+
31128+ if (vma->vm_start > vma_m->vm_start) {
31129+ address_m = address;
31130+ address -= SEGMEXEC_TASK_SIZE;
31131+ vma = vma_m;
31132+ } else
31133+ address_m = address + SEGMEXEC_TASK_SIZE;
31134+
31135+ pgd_m = pgd_offset(mm, address_m);
31136+ pud_m = pud_alloc(mm, pgd_m, address_m);
31137+ if (!pud_m)
31138+ return VM_FAULT_OOM;
31139+ pmd_m = pmd_alloc(mm, pud_m, address_m);
31140+ if (!pmd_m)
31141+ return VM_FAULT_OOM;
31142+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
31143+ return VM_FAULT_OOM;
31144+ pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
31145+ }
31146+#endif
31147+
31148 pgd = pgd_offset(mm, address);
31149 pud = pud_alloc(mm, pgd, address);
31150 if (!pud)
31151@@ -2732,7 +3025,7 @@ static int __init gate_vma_init(void)
31152 gate_vma.vm_start = FIXADDR_USER_START;
31153 gate_vma.vm_end = FIXADDR_USER_END;
31154 gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
31155- gate_vma.vm_page_prot = __P101;
31156+ gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
31157 /*
31158 * Make sure the vDSO gets into every core dump.
31159 * Dumping its contents makes post-mortem fully interpretable later
31160diff -urNp linux-2.6.22.1/mm/mempolicy.c linux-2.6.22.1/mm/mempolicy.c
31161--- linux-2.6.22.1/mm/mempolicy.c 2007-07-10 14:56:30.000000000 -0400
31162+++ linux-2.6.22.1/mm/mempolicy.c 2007-08-02 11:38:48.000000000 -0400
31163@@ -401,6 +401,10 @@ static int mbind_range(struct vm_area_st
31164 struct vm_area_struct *next;
31165 int err;
31166
31167+#ifdef CONFIG_PAX_SEGMEXEC
31168+ struct vm_area_struct *vma_m;
31169+#endif
31170+
31171 err = 0;
31172 for (; vma && vma->vm_start < end; vma = next) {
31173 next = vma->vm_next;
31174@@ -412,6 +416,16 @@ static int mbind_range(struct vm_area_st
31175 err = policy_vma(vma, new);
31176 if (err)
31177 break;
31178+
31179+#ifdef CONFIG_PAX_SEGMEXEC
31180+ vma_m = pax_find_mirror_vma(vma);
31181+ if (vma_m) {
31182+ err = policy_vma(vma_m, new);
31183+ if (err)
31184+ break;
31185+ }
31186+#endif
31187+
31188 }
31189 return err;
31190 }
31191@@ -731,7 +745,7 @@ static struct page *new_vma_page(struct
31192 }
31193 #endif
31194
31195-long do_mbind(unsigned long start, unsigned long len,
31196+static long do_mbind(unsigned long start, unsigned long len,
31197 unsigned long mode, nodemask_t *nmask, unsigned long flags)
31198 {
31199 struct vm_area_struct *vma;
31200@@ -759,6 +773,17 @@ long do_mbind(unsigned long start, unsig
31201
31202 if (end < start)
31203 return -EINVAL;
31204+
31205+#ifdef CONFIG_PAX_SEGMEXEC
31206+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
31207+ if (end > SEGMEXEC_TASK_SIZE)
31208+ return -EINVAL;
31209+ } else
31210+#endif
31211+
31212+ if (end > TASK_SIZE)
31213+ return -EINVAL;
31214+
31215 if (end == start)
31216 return 0;
31217
31218diff -urNp linux-2.6.22.1/mm/mlock.c linux-2.6.22.1/mm/mlock.c
31219--- linux-2.6.22.1/mm/mlock.c 2007-07-10 14:56:30.000000000 -0400
31220+++ linux-2.6.22.1/mm/mlock.c 2007-08-02 11:38:48.000000000 -0400
31221@@ -13,6 +13,7 @@
31222 #include <linux/sched.h>
31223 #include <linux/module.h>
31224 #include <linux/vs_memory.h>
31225+#include <linux/grsecurity.h>
31226
31227 int can_do_mlock(void)
31228 {
31229@@ -95,6 +96,17 @@ static int do_mlock(unsigned long start,
31230 return -EINVAL;
31231 if (end == start)
31232 return 0;
31233+
31234+#ifdef CONFIG_PAX_SEGMEXEC
31235+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
31236+ if (end > SEGMEXEC_TASK_SIZE)
31237+ return -EINVAL;
31238+ } else
31239+#endif
31240+
31241+ if (end > TASK_SIZE)
31242+ return -EINVAL;
31243+
31244 vma = find_vma_prev(current->mm, start, &prev);
31245 if (!vma || vma->vm_start > start)
31246 return -ENOMEM;
31247@@ -155,6 +183,7 @@ asmlinkage long sys_mlock(unsigned long
31248 lock_limit >>= PAGE_SHIFT;
31249
31250 /* check against resource limits */
31251+ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
31252 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
31253 error = do_mlock(start, len, 1);
31254 out:
31255@@ -173,10 +202,10 @@ asmlinkage long sys_munlock(unsigned lon
31256 static int do_mlockall(int flags)
31257 {
31258 struct vm_area_struct * vma, * prev = NULL;
31259- unsigned int def_flags = 0;
31260+ unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
31261
31262 if (flags & MCL_FUTURE)
31263- def_flags = VM_LOCKED;
31264+ def_flags |= VM_LOCKED;
31265 current->mm->def_flags = def_flags;
31266 if (flags == MCL_FUTURE)
31267 goto out;
31268@@ -184,6 +197,12 @@ static int do_mlockall(int flags)
31269 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
31270 unsigned int newflags;
31271
31272+#ifdef CONFIG_PAX_SEGMEXEC
31273+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
31274+ break;
31275+#endif
31276+
31277+ BUG_ON(vma->vm_end > TASK_SIZE);
31278 newflags = vma->vm_flags | VM_LOCKED;
31279 if (!(flags & MCL_CURRENT))
31280 newflags &= ~VM_LOCKED;
31281@@ -213,6 +243,7 @@ asmlinkage long sys_mlockall(int flags)
31282 lock_limit >>= PAGE_SHIFT;
31283
31284 ret = -ENOMEM;
31285+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
31286 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
31287 goto out;
31288 if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
31289diff -urNp linux-2.6.22.1/mm/mmap.c linux-2.6.22.1/mm/mmap.c
31290--- linux-2.6.22.1/mm/mmap.c 2007-07-10 14:56:30.000000000 -0400
31291+++ linux-2.6.22.1/mm/mmap.c 2007-08-02 11:38:48.000000000 -0400
31292@@ -25,6 +25,7 @@
31293 #include <linux/mount.h>
31294 #include <linux/mempolicy.h>
31295 #include <linux/rmap.h>
31296+#include <linux/grsecurity.h>
31297
31298 #include <asm/uaccess.h>
31299 #include <asm/cacheflush.h>
31300@@ -60,15 +61,23 @@ static void unmap_region(struct mm_struc
31301 * x: (no) no x: (no) yes x: (no) yes x: (yes) yes
31302 *
31303 */
31304-pgprot_t protection_map[16] = {
31305+pgprot_t protection_map[16] __read_only = {
31306 __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
31307 __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
31308 };
31309
31310 pgprot_t vm_get_page_prot(unsigned long vm_flags)
31311 {
31312- return protection_map[vm_flags &
31313- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
31314+ pgprot_t prot = protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
31315+
31316+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
31317+ if (!nx_enabled &&
31318+ (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
31319+ (vm_flags & (VM_READ | VM_WRITE)))
31320+ prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
31321+#endif
31322+
31323+ return prot;
31324 }
31325 EXPORT_SYMBOL(vm_get_page_prot);
31326
31327@@ -225,6 +234,7 @@ static struct vm_area_struct *remove_vma
31328 struct vm_area_struct *next = vma->vm_next;
31329
31330 might_sleep();
31331+ BUG_ON(vma->vm_mirror);
31332 if (vma->vm_ops && vma->vm_ops->close)
31333 vma->vm_ops->close(vma);
31334 if (vma->vm_file)
31335@@ -252,6 +262,7 @@ asmlinkage unsigned long sys_brk(unsigne
31336 * not page aligned -Ram Gupta
31337 */
31338 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
31339+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
31340 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
31341 goto out;
31342
31343@@ -352,8 +363,12 @@ find_vma_prepare(struct mm_struct *mm, u
31344
31345 if (vma_tmp->vm_end > addr) {
31346 vma = vma_tmp;
31347- if (vma_tmp->vm_start <= addr)
31348- return vma;
31349+ if (vma_tmp->vm_start <= addr) {
31350+//printk("PAX: prep: %08lx-%08lx %08lx pr:%p l:%p pa:%p ",
31351+//vma->vm_start, vma->vm_end, addr, *pprev, *rb_link, *rb_parent);
31352+//__print_symbol("%s\n", __builtin_extract_return_addr(__builtin_return_address(0)));
31353+ break;
31354+ }
31355 __rb_link = &__rb_parent->rb_left;
31356 } else {
31357 rb_prev = __rb_parent;
31358@@ -677,6 +692,12 @@ static int
31359 can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
31360 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
31361 {
31362+
31363+#ifdef CONFIG_PAX_SEGMEXEC
31364+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
31365+ return 0;
31366+#endif
31367+
31368 if (is_mergeable_vma(vma, file, vm_flags) &&
31369 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
31370 if (vma->vm_pgoff == vm_pgoff)
31371@@ -696,6 +717,12 @@ static int
31372 can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
31373 struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
31374 {
31375+
31376+#ifdef CONFIG_PAX_SEGMEXEC
31377+ if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
31378+ return 0;
31379+#endif
31380+
31381 if (is_mergeable_vma(vma, file, vm_flags) &&
31382 is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
31383 pgoff_t vm_pglen;
31384@@ -738,12 +765,19 @@ can_vma_merge_after(struct vm_area_struc
31385 struct vm_area_struct *vma_merge(struct mm_struct *mm,
31386 struct vm_area_struct *prev, unsigned long addr,
31387 unsigned long end, unsigned long vm_flags,
31388- struct anon_vma *anon_vma, struct file *file,
31389+ struct anon_vma *anon_vma, struct file *file,
31390 pgoff_t pgoff, struct mempolicy *policy)
31391 {
31392 pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
31393 struct vm_area_struct *area, *next;
31394
31395+#ifdef CONFIG_PAX_SEGMEXEC
31396+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
31397+ struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
31398+
31399+ BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
31400+#endif
31401+
31402 /*
31403 * We later require that vma->vm_flags == vm_flags,
31404 * so this tests vma->vm_flags & VM_SPECIAL, too.
31405@@ -759,6 +793,15 @@ struct vm_area_struct *vma_merge(struct
31406 if (next && next->vm_end == end) /* cases 6, 7, 8 */
31407 next = next->vm_next;
31408
31409+#ifdef CONFIG_PAX_SEGMEXEC
31410+ if (prev)
31411+ prev_m = pax_find_mirror_vma(prev);
31412+ if (area)
31413+ area_m = pax_find_mirror_vma(area);
31414+ if (next)
31415+ next_m = pax_find_mirror_vma(next);
31416+#endif
31417+
31418 /*
31419 * Can it merge with the predecessor?
31420 */
31421@@ -778,9 +825,24 @@ struct vm_area_struct *vma_merge(struct
31422 /* cases 1, 6 */
31423 vma_adjust(prev, prev->vm_start,
31424 next->vm_end, prev->vm_pgoff, NULL);
31425- } else /* cases 2, 5, 7 */
31426+
31427+#ifdef CONFIG_PAX_SEGMEXEC
31428+ if (prev_m)
31429+ vma_adjust(prev_m, prev_m->vm_start,
31430+ next_m->vm_end, prev_m->vm_pgoff, NULL);
31431+#endif
31432+
31433+ } else { /* cases 2, 5, 7 */
31434 vma_adjust(prev, prev->vm_start,
31435 end, prev->vm_pgoff, NULL);
31436+
31437+#ifdef CONFIG_PAX_SEGMEXEC
31438+ if (prev_m)
31439+ vma_adjust(prev_m, prev_m->vm_start,
31440+ end_m, prev_m->vm_pgoff, NULL);
31441+#endif
31442+
31443+ }
31444 return prev;
31445 }
31446
31447@@ -791,12 +853,27 @@ struct vm_area_struct *vma_merge(struct
31448 mpol_equal(policy, vma_policy(next)) &&
31449 can_vma_merge_before(next, vm_flags,
31450 anon_vma, file, pgoff+pglen)) {
31451- if (prev && addr < prev->vm_end) /* case 4 */
31452+ if (prev && addr < prev->vm_end) { /* case 4 */
31453 vma_adjust(prev, prev->vm_start,
31454 addr, prev->vm_pgoff, NULL);
31455- else /* cases 3, 8 */
31456+
31457+#ifdef CONFIG_PAX_SEGMEXEC
31458+ if (prev_m)
31459+ vma_adjust(prev_m, prev_m->vm_start,
31460+ addr_m, prev_m->vm_pgoff, NULL);
31461+#endif
31462+
31463+ } else { /* cases 3, 8 */
31464 vma_adjust(area, addr, next->vm_end,
31465 next->vm_pgoff - pglen, NULL);
31466+
31467+#ifdef CONFIG_PAX_SEGMEXEC
31468+ if (area_m)
31469+ vma_adjust(area_m, addr_m, next_m->vm_end,
31470+ next_m->vm_pgoff - pglen, NULL);
31471+#endif
31472+
31473+ }
31474 return area;
31475 }
31476
31477@@ -871,14 +948,11 @@ none:
31478 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
31479 struct file *file, long pages)
31480 {
31481- const unsigned long stack_flags
31482- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
31483-
31484 if (file) {
31485 mm->shared_vm += pages;
31486 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
31487 mm->exec_vm += pages;
31488- } else if (flags & stack_flags)
31489+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
31490 mm->stack_vm += pages;
31491 if (flags & (VM_RESERVED|VM_IO))
31492 mm->reserved_vm += pages;
31493@@ -903,28 +977,32 @@ unsigned long do_mmap_pgoff(struct file
31494 int accountable = 1;
31495 unsigned long charged = 0, reqprot = prot;
31496
31497+#ifdef CONFIG_PAX_SEGMEXEC
31498+ struct vm_area_struct *vma_m = NULL, *prev_m;
31499+#endif
31500+
31501 /*
31502 * Does the application expect PROT_READ to imply PROT_EXEC?
31503 *
31504 * (the exception is when the underlying filesystem is noexec
31505 * mounted, in which case we dont add PROT_EXEC.)
31506 */
31507- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
31508+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
31509 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
31510 prot |= PROT_EXEC;
31511
31512 if (!len)
31513 return -EINVAL;
31514
31515- error = arch_mmap_check(addr, len, flags);
31516- if (error)
31517- return error;
31518-
31519 /* Careful about overflows.. */
31520 len = PAGE_ALIGN(len);
31521 if (!len || len > TASK_SIZE)
31522 return -ENOMEM;
31523
31524+ error = arch_mmap_check(addr, len, flags);
31525+ if (error)
31526+ return error;
31527+
31528 /* offset overflow? */
31529 if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
31530 return -EOVERFLOW;
31531@@ -936,7 +1015,7 @@ unsigned long do_mmap_pgoff(struct file
31532 /* Obtain the address to map to. we verify (or select) it and ensure
31533 * that it represents a valid section of the address space.
31534 */
31535- addr = get_unmapped_area(file, addr, len, pgoff, flags);
31536+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
31537 if (addr & ~PAGE_MASK)
31538 return addr;
31539
31540@@ -947,6 +1026,26 @@ unsigned long do_mmap_pgoff(struct file
31541 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
31542 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
31543
31544+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
31545+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
31546+
31547+#ifdef CONFIG_PAX_MPROTECT
31548+ if (mm->pax_flags & MF_PAX_MPROTECT) {
31549+ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
31550+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
31551+ else
31552+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
31553+ }
31554+#endif
31555+
31556+ }
31557+#endif
31558+
31559+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
31560+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
31561+ vm_flags &= ~VM_PAGEEXEC;
31562+#endif
31563+
31564 if (flags & MAP_LOCKED) {
31565 if (!can_do_mlock())
31566 return -EPERM;
31567@@ -959,6 +1058,7 @@ unsigned long do_mmap_pgoff(struct file
31568 locked += mm->locked_vm;
31569 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
31570 lock_limit >>= PAGE_SHIFT;
31571+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
31572 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
31573 return -EAGAIN;
31574 }
31575@@ -1027,14 +1127,17 @@ unsigned long do_mmap_pgoff(struct file
31576 if (error)
31577 return error;
31578
31579+ if (!gr_acl_handle_mmap(file, prot))
31580+ return -EACCES;
31581+
31582 /* Clear old maps */
31583 error = -ENOMEM;
31584-munmap_back:
31585 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
31586 if (vma && vma->vm_start < addr + len) {
31587 if (do_munmap(mm, addr, len))
31588 return -ENOMEM;
31589- goto munmap_back;
31590+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
31591+ BUG_ON(vma && vma->vm_start < addr + len);
31592 }
31593
31594 /* Check against address space limit. */
31595@@ -1078,12 +1181,22 @@ munmap_back:
31596 goto unacct_error;
31597 }
31598
31599+#ifdef CONFIG_PAX_SEGMEXEC
31600+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
31601+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
31602+ if (!vma_m) {
31603+ kmem_cache_free(vm_area_cachep, vma);
31604+ error = -ENOMEM;
31605+ goto unacct_error;
31606+ }
31607+ }
31608+#endif
31609+
31610 vma->vm_mm = mm;
31611 vma->vm_start = addr;
31612 vma->vm_end = addr + len;
31613 vma->vm_flags = vm_flags;
31614- vma->vm_page_prot = protection_map[vm_flags &
31615- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
31616+ vma->vm_page_prot = vm_get_page_prot(vm_flags);
31617 vma->vm_pgoff = pgoff;
31618
31619 if (file) {
31620@@ -1101,6 +1214,14 @@ munmap_back:
31621 error = file->f_op->mmap(file, vma);
31622 if (error)
31623 goto unmap_and_free_vma;
31624+
31625+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
31626+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
31627+ vma->vm_flags |= VM_PAGEEXEC;
31628+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
31629+ }
31630+#endif
31631+
31632 } else if (vm_flags & VM_SHARED) {
31633 error = shmem_zero_setup(vma);
31634 if (error)
31635@@ -1125,13 +1246,18 @@ munmap_back:
31636 vm_flags = vma->vm_flags;
31637
31638 if (vma_wants_writenotify(vma))
31639- vma->vm_page_prot =
31640- protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
31641+ vma->vm_page_prot = vm_get_page_prot(vm_flags & ~VM_SHARED);
31642
31643 if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
31644 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
31645 file = vma->vm_file;
31646 vma_link(mm, vma, prev, rb_link, rb_parent);
31647+
31648+#ifdef CONFIG_PAX_SEGMEXEC
31649+ if (vma_m)
31650+ pax_mirror_vma(vma_m, vma);
31651+#endif
31652+
31653 if (correct_wcount)
31654 atomic_inc(&inode->i_writecount);
31655 } else {
31656@@ -1142,10 +1268,12 @@ munmap_back:
31657 }
31658 mpol_free(vma_policy(vma));
31659 kmem_cache_free(vm_area_cachep, vma);
31660+ vma = NULL;
31661 }
31662 out:
31663 vx_vmpages_add(mm, len >> PAGE_SHIFT);
31664 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
31665+ track_exec_limit(mm, addr, addr + len, vm_flags);
31666 if (vm_flags & VM_LOCKED) {
31667 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
31668 make_pages_present(addr, addr + len);
31669@@ -1168,6 +1296,12 @@ unmap_and_free_vma:
31670 unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
31671 charged = 0;
31672 free_vma:
31673+
31674+#ifdef CONFIG_PAX_SEGMEXEC
31675+ if (vma_m)
31676+ kmem_cache_free(vm_area_cachep, vma_m);
31677+#endif
31678+
31679 kmem_cache_free(vm_area_cachep, vma);
31680 unacct_error:
31681 if (charged)
31682@@ -1203,6 +1337,10 @@ arch_get_unmapped_area(struct file *filp
31683 if (flags & MAP_FIXED)
31684 return addr;
31685
31686+#ifdef CONFIG_PAX_RANDMMAP
31687+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
31688+#endif
31689+
31690 if (addr) {
31691 addr = PAGE_ALIGN(addr);
31692 vma = find_vma(mm, addr);
31693@@ -1211,10 +1349,10 @@ arch_get_unmapped_area(struct file *filp
31694 return addr;
31695 }
31696 if (len > mm->cached_hole_size) {
31697- start_addr = addr = mm->free_area_cache;
31698+ start_addr = addr = mm->free_area_cache;
31699 } else {
31700- start_addr = addr = TASK_UNMAPPED_BASE;
31701- mm->cached_hole_size = 0;
31702+ start_addr = addr = mm->mmap_base;
31703+ mm->cached_hole_size = 0;
31704 }
31705
31706 full_search:
31707@@ -1225,9 +1363,8 @@ full_search:
31708 * Start a new search - just in case we missed
31709 * some holes.
31710 */
31711- if (start_addr != TASK_UNMAPPED_BASE) {
31712- addr = TASK_UNMAPPED_BASE;
31713- start_addr = addr;
31714+ if (start_addr != mm->mmap_base) {
31715+ start_addr = addr = mm->mmap_base;
31716 mm->cached_hole_size = 0;
31717 goto full_search;
31718 }
31719@@ -1249,10 +1386,16 @@ full_search:
31720
31721 void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
31722 {
31723+
31724+#ifdef CONFIG_PAX_SEGMEXEC
31725+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
31726+ return;
31727+#endif
31728+
31729 /*
31730 * Is this a new hole at the lowest possible address?
31731 */
31732- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
31733+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
31734 mm->free_area_cache = addr;
31735 mm->cached_hole_size = ~0UL;
31736 }
31737@@ -1270,7 +1413,7 @@ arch_get_unmapped_area_topdown(struct fi
31738 {
31739 struct vm_area_struct *vma;
31740 struct mm_struct *mm = current->mm;
31741- unsigned long addr = addr0;
31742+ unsigned long base = mm->mmap_base, addr = addr0;
31743
31744 /* requested length too big for entire address space */
31745 if (len > TASK_SIZE)
31746@@ -1279,6 +1422,10 @@ arch_get_unmapped_area_topdown(struct fi
31747 if (flags & MAP_FIXED)
31748 return addr;
31749
31750+#ifdef CONFIG_PAX_RANDMMAP
31751+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
31752+#endif
31753+
31754 /* requesting a specific address */
31755 if (addr) {
31756 addr = PAGE_ALIGN(addr);
31757@@ -1336,13 +1483,21 @@ bottomup:
31758 * can happen with large stack limits and large mmap()
31759 * allocations.
31760 */
31761+ mm->mmap_base = TASK_UNMAPPED_BASE;
31762+
31763+#ifdef CONFIG_PAX_RANDMMAP
31764+ if (mm->pax_flags & MF_PAX_RANDMMAP)
31765+ mm->mmap_base += mm->delta_mmap;
31766+#endif
31767+
31768+ mm->free_area_cache = mm->mmap_base;
31769 mm->cached_hole_size = ~0UL;
31770- mm->free_area_cache = TASK_UNMAPPED_BASE;
31771 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
31772 /*
31773 * Restore the topdown base:
31774 */
31775- mm->free_area_cache = mm->mmap_base;
31776+ mm->mmap_base = base;
31777+ mm->free_area_cache = base;
31778 mm->cached_hole_size = ~0UL;
31779
31780 return addr;
31781@@ -1351,6 +1506,12 @@ bottomup:
31782
31783 void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
31784 {
31785+
31786+#ifdef CONFIG_PAX_SEGMEXEC
31787+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
31788+ return;
31789+#endif
31790+
31791 /*
31792 * Is this a new hole at the highest possible address?
31793 */
31794@@ -1358,8 +1519,10 @@ void arch_unmap_area_topdown(struct mm_s
31795 mm->free_area_cache = addr;
31796
31797 /* dont allow allocations above current base */
31798- if (mm->free_area_cache > mm->mmap_base)
31799+ if (mm->free_area_cache > mm->mmap_base) {
31800 mm->free_area_cache = mm->mmap_base;
31801+ mm->cached_hole_size = ~0UL;
31802+ }
31803 }
31804
31805 unsigned long
31806@@ -1459,6 +1622,32 @@ out:
31807 return prev ? prev->vm_next : vma;
31808 }
31809
31810+#ifdef CONFIG_PAX_SEGMEXEC
31811+struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
31812+{
31813+ struct vm_area_struct *vma_m;
31814+
31815+ BUG_ON(!vma || vma->vm_start >= vma->vm_end);
31816+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
31817+ BUG_ON(vma->vm_mirror);
31818+ return NULL;
31819+ }
31820+ BUG_ON(vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < vma->vm_start - SEGMEXEC_TASK_SIZE - 1);
31821+ vma_m = vma->vm_mirror;
31822+ BUG_ON(!vma_m || vma_m->vm_mirror != vma);
31823+ BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
31824+ BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
31825+
31826+#ifdef CONFIG_PAX_MPROTECT
31827+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED | VM_MAYNOTWRITE));
31828+#else
31829+ BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
31830+#endif
31831+
31832+ return vma_m;
31833+}
31834+#endif
31835+
31836 /*
31837 * Verify that the stack growth is acceptable and
31838 * update accounting. This is shared with both the
31839@@ -1475,6 +1658,7 @@ static int acct_stack_growth(struct vm_a
31840 return -ENOMEM;
31841
31842 /* Stack limit test */
31843+ gr_learn_resource(current, RLIMIT_STACK, size, 1);
31844 if (size > rlim[RLIMIT_STACK].rlim_cur)
31845 return -ENOMEM;
31846
31847@@ -1484,6 +1668,7 @@ static int acct_stack_growth(struct vm_a
31848 unsigned long limit;
31849 locked = mm->locked_vm + grow;
31850 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
31851+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
31852 if (locked > limit && !capable(CAP_IPC_LOCK))
31853 return -ENOMEM;
31854 }
31855@@ -1567,23 +1752,6 @@ int expand_stack(struct vm_area_struct *
31856 {
31857 return expand_upwards(vma, address);
31858 }
31859-
31860-struct vm_area_struct *
31861-find_extend_vma(struct mm_struct *mm, unsigned long addr)
31862-{
31863- struct vm_area_struct *vma, *prev;
31864-
31865- addr &= PAGE_MASK;
31866- vma = find_vma_prev(mm, addr, &prev);
31867- if (vma && (vma->vm_start <= addr))
31868- return vma;
31869- if (!prev || expand_stack(prev, addr))
31870- return NULL;
31871- if (prev->vm_flags & VM_LOCKED) {
31872- make_pages_present(addr, prev->vm_end);
31873- }
31874- return prev;
31875-}
31876 #else
31877 /*
31878 * vma is the first one with address < vma->vm_start. Have to extend vma.
31879@@ -1612,6 +1780,12 @@ int expand_stack(struct vm_area_struct *
31880 if (address < vma->vm_start) {
31881 unsigned long size, grow;
31882
31883+#ifdef CONFIG_PAX_SEGMEXEC
31884+ struct vm_area_struct *vma_m;
31885+
31886+ vma_m = pax_find_mirror_vma(vma);
31887+#endif
31888+
31889 size = vma->vm_end - address;
31890 grow = (vma->vm_start - address) >> PAGE_SHIFT;
31891
31892@@ -1619,34 +1794,20 @@ int expand_stack(struct vm_area_struct *
31893 if (!error) {
31894 vma->vm_start = address;
31895 vma->vm_pgoff -= grow;
31896+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
31897+
31898+#ifdef CONFIG_PAX_SEGMEXEC
31899+ if (vma_m) {
31900+ vma_m->vm_start -= grow << PAGE_SHIFT;
31901+ vma_m->vm_pgoff -= grow;
31902+ }
31903+#endif
31904+
31905 }
31906 }
31907 anon_vma_unlock(vma);
31908 return error;
31909 }
31910-
31911-struct vm_area_struct *
31912-find_extend_vma(struct mm_struct * mm, unsigned long addr)
31913-{
31914- struct vm_area_struct * vma;
31915- unsigned long start;
31916-
31917- addr &= PAGE_MASK;
31918- vma = find_vma(mm,addr);
31919- if (!vma)
31920- return NULL;
31921- if (vma->vm_start <= addr)
31922- return vma;
31923- if (!(vma->vm_flags & VM_GROWSDOWN))
31924- return NULL;
31925- start = vma->vm_start;
31926- if (expand_stack(vma, addr))
31927- return NULL;
31928- if (vma->vm_flags & VM_LOCKED) {
31929- make_pages_present(addr, start);
31930- }
31931- return vma;
31932-}
31933 #endif
31934
31935 /*
31936@@ -1662,6 +1827,10 @@ static void remove_vma_list(struct mm_st
31937 do {
31938 long nrpages = vma_pages(vma);
31939
31940+#ifdef CONFIG_PAX_SEGMEXEC
31941+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_end <= SEGMEXEC_TASK_SIZE))
31942+#endif
31943+
31944 vx_vmpages_sub(mm, nrpages);
31945 if (vma->vm_flags & VM_LOCKED)
31946 vx_vmlocked_sub(mm, nrpages);
31947@@ -1708,6 +1869,16 @@ detach_vmas_to_be_unmapped(struct mm_str
31948
31949 insertion_point = (prev ? &prev->vm_next : &mm->mmap);
31950 do {
31951+
31952+#ifdef CONFIG_PAX_SEGMEXEC
31953+ if (vma->vm_mirror) {
31954+ BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
31955+ vma->vm_mirror->vm_mirror = NULL;
31956+ vma->vm_mirror->vm_flags &= ~VM_EXEC;
31957+ vma->vm_mirror = NULL;
31958+ }
31959+#endif
31960+
31961 rb_erase(&vma->vm_rb, &mm->mm_rb);
31962 mm->map_count--;
31963 tail_vma = vma;
31964@@ -1727,6 +1897,112 @@ detach_vmas_to_be_unmapped(struct mm_str
31965 * Split a vma into two pieces at address 'addr', a new vma is allocated
31966 * either for the first part or the tail.
31967 */
31968+
31969+#ifdef CONFIG_PAX_SEGMEXEC
31970+int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
31971+ unsigned long addr, int new_below)
31972+{
31973+ struct mempolicy *pol, *pol_m;
31974+ struct vm_area_struct *new, *vma_m, *new_m = NULL;
31975+ unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
31976+
31977+ if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
31978+ return -EINVAL;
31979+
31980+ vma_m = pax_find_mirror_vma(vma);
31981+ if (vma_m) {
31982+ BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
31983+ if (mm->map_count >= sysctl_max_map_count-1)
31984+ return -ENOMEM;
31985+ } else if (mm->map_count >= sysctl_max_map_count)
31986+ return -ENOMEM;
31987+
31988+ new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
31989+ if (!new)
31990+ return -ENOMEM;
31991+
31992+ if (vma_m) {
31993+ new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
31994+ if (!new_m) {
31995+ kmem_cache_free(vm_area_cachep, new);
31996+ return -ENOMEM;
31997+ }
31998+ }
31999+
32000+ /* most fields are the same, copy all, and then fixup */
32001+ *new = *vma;
32002+
32003+ if (new_below)
32004+ new->vm_end = addr;
32005+ else {
32006+ new->vm_start = addr;
32007+ new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
32008+ }
32009+
32010+ if (vma_m) {
32011+ *new_m = *vma_m;
32012+ new_m->vm_mirror = new;
32013+ new->vm_mirror = new_m;
32014+
32015+ if (new_below)
32016+ new_m->vm_end = addr_m;
32017+ else {
32018+ new_m->vm_start = addr_m;
32019+ new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
32020+ }
32021+ }
32022+
32023+ pol = mpol_copy(vma_policy(vma));
32024+ if (IS_ERR(pol)) {
32025+ if (new_m)
32026+ kmem_cache_free(vm_area_cachep, new_m);
32027+ kmem_cache_free(vm_area_cachep, new);
32028+ return PTR_ERR(pol);
32029+ }
32030+
32031+ if (vma_m) {
32032+ pol_m = mpol_copy(vma_policy(vma_m));
32033+ if (IS_ERR(pol_m)) {
32034+ mpol_free(pol);
32035+ kmem_cache_free(vm_area_cachep, new_m);
32036+ kmem_cache_free(vm_area_cachep, new);
32037+ return PTR_ERR(pol);
32038+ }
32039+ }
32040+
32041+ vma_set_policy(new, pol);
32042+
32043+ if (new->vm_file)
32044+ get_file(new->vm_file);
32045+
32046+ if (new->vm_ops && new->vm_ops->open)
32047+ new->vm_ops->open(new);
32048+
32049+ if (new_below)
32050+ vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
32051+ ((addr - new->vm_start) >> PAGE_SHIFT), new);
32052+ else
32053+ vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
32054+
32055+ if (vma_m) {
32056+ vma_set_policy(new_m, pol_m);
32057+
32058+ if (new_m->vm_file)
32059+ get_file(new_m->vm_file);
32060+
32061+ if (new_m->vm_ops && new_m->vm_ops->open)
32062+ new_m->vm_ops->open(new_m);
32063+
32064+ if (new_below)
32065+ vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
32066+ ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
32067+ else
32068+ vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
32069+ }
32070+
32071+ return 0;
32072+}
32073+#else
32074 int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
32075 unsigned long addr, int new_below)
32076 {
32077@@ -1774,14 +2055,28 @@ int split_vma(struct mm_struct * mm, str
32078
32079 return 0;
32080 }
32081+#endif
32082
32083 /* Munmap is split into 2 main parts -- this part which finds
32084 * what needs doing, and the areas themselves, which do the
32085 * work. This now handles partial unmappings.
32086 * Jeremy Fitzhardinge <jeremy@goop.org>
32087 */
32088+#ifdef CONFIG_PAX_SEGMEXEC
32089 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
32090 {
32091+ int ret = __do_munmap(mm, start, len);
32092+ if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
32093+ return ret;
32094+
32095+ return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
32096+}
32097+
32098+int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
32099+#else
32100+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
32101+#endif
32102+{
32103 unsigned long end;
32104 struct vm_area_struct *vma, *prev, *last;
32105
32106@@ -1834,6 +2124,8 @@ int do_munmap(struct mm_struct *mm, unsi
32107 /* Fix up all other VM information */
32108 remove_vma_list(mm, vma);
32109
32110+ track_exec_limit(mm, start, end, 0UL);
32111+
32112 return 0;
32113 }
32114
32115@@ -1846,6 +2138,12 @@ asmlinkage long sys_munmap(unsigned long
32116
32117 profile_munmap(addr);
32118
32119+#ifdef CONFIG_PAX_SEGMEXEC
32120+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
32121+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
32122+ return -EINVAL;
32123+#endif
32124+
32125 down_write(&mm->mmap_sem);
32126 ret = do_munmap(mm, addr, len);
32127 up_write(&mm->mmap_sem);
32128@@ -1875,6 +2173,11 @@ unsigned long do_brk(unsigned long addr,
32129 struct rb_node ** rb_link, * rb_parent;
32130 pgoff_t pgoff = addr >> PAGE_SHIFT;
32131 int error;
32132+ unsigned long charged;
32133+
32134+#ifdef CONFIG_PAX_SEGMEXEC
32135+ struct vm_area_struct *vma_m = NULL;
32136+#endif
32137
32138 len = PAGE_ALIGN(len);
32139 if (!len)
32140@@ -1888,19 +2191,34 @@ unsigned long do_brk(unsigned long addr,
32141
32142 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
32143
32144+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
32145+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
32146+ flags &= ~VM_EXEC;
32147+
32148+#ifdef CONFIG_PAX_MPROTECT
32149+ if (mm->pax_flags & MF_PAX_MPROTECT)
32150+ flags &= ~VM_MAYEXEC;
32151+#endif
32152+
32153+ }
32154+#endif
32155+
32156 error = arch_mmap_check(addr, len, flags);
32157 if (error)
32158 return error;
32159
32160+ charged = len >> PAGE_SHIFT;
32161+
32162 /*
32163 * mlock MCL_FUTURE?
32164 */
32165 if (mm->def_flags & VM_LOCKED) {
32166 unsigned long locked, lock_limit;
32167- locked = len >> PAGE_SHIFT;
32168+ locked = charged;
32169 locked += mm->locked_vm;
32170 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
32171 lock_limit >>= PAGE_SHIFT;
32172+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
32173 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
32174 return -EAGAIN;
32175 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
32176@@ -1916,23 +2234,23 @@ unsigned long do_brk(unsigned long addr,
32177 /*
32178 * Clear old maps. this also does some error checking for us
32179 */
32180- munmap_back:
32181 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
32182 if (vma && vma->vm_start < addr + len) {
32183 if (do_munmap(mm, addr, len))
32184 return -ENOMEM;
32185- goto munmap_back;
32186+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
32187+ BUG_ON(vma && vma->vm_start < addr + len);
32188 }
32189
32190 /* Check against address space limits *after* clearing old maps... */
32191- if (!may_expand_vm(mm, len >> PAGE_SHIFT))
32192+ if (!may_expand_vm(mm, charged))
32193 return -ENOMEM;
32194
32195 if (mm->map_count > sysctl_max_map_count)
32196 return -ENOMEM;
32197
32198- if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
32199- !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
32200+ if (security_vm_enough_memory(charged) ||
32201+ !vx_vmpages_avail(mm, charged))
32202 return -ENOMEM;
32203
32204 /* Can we just expand an old private anonymous mapping? */
32205@@ -1942,24 +2260,41 @@ unsigned long do_brk(unsigned long addr,
32206 */
32207 vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
32208 if (!vma) {
32209- vm_unacct_memory(len >> PAGE_SHIFT);
32210+ vm_unacct_memory(charged);
32211 return -ENOMEM;
32212 }
32213
32214+#ifdef CONFIG_PAX_SEGMEXEC
32215+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
32216+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
32217+ if (!vma_m) {
32218+ kmem_cache_free(vm_area_cachep, vma);
32219+ vm_unacct_memory(charged);
32220+ return -ENOMEM;
32221+ }
32222+ }
32223+#endif
32224+
32225 vma->vm_mm = mm;
32226 vma->vm_start = addr;
32227 vma->vm_end = addr + len;
32228 vma->vm_pgoff = pgoff;
32229 vma->vm_flags = flags;
32230- vma->vm_page_prot = protection_map[flags &
32231- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
32232+ vma->vm_page_prot = vm_get_page_prot(flags);
32233 vma_link(mm, vma, prev, rb_link, rb_parent);
32234+
32235+#ifdef CONFIG_PAX_SEGMEXEC
32236+ if (vma_m)
32237+ pax_mirror_vma(vma_m, vma);
32238+#endif
32239+
32240 out:
32241- vx_vmpages_add(mm, len >> PAGE_SHIFT);
32242+ vx_vmpages_add(mm, charged);
32243 if (flags & VM_LOCKED) {
32244- vx_vmlocked_add(mm, len >> PAGE_SHIFT);
32245+ vx_vmlocked_add(mm, charged);
32246 make_pages_present(addr, addr + len);
32247 }
32248+ track_exec_limit(mm, addr, addr + len, flags);
32249 return addr;
32250 }
32251
32252@@ -1990,8 +2325,10 @@ void exit_mmap(struct mm_struct *mm)
32253 * Walk the list again, actually closing and freeing it,
32254 * with preemption enabled, without holding any MM locks.
32255 */
32256- while (vma)
32257+ while (vma) {
32258+ vma->vm_mirror = NULL;
32259 vma = remove_vma(vma);
32260+ }
32261
32262 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
32263 }
32264@@ -2005,6 +2342,10 @@ int insert_vm_struct(struct mm_struct *
32265 struct vm_area_struct * __vma, * prev;
32266 struct rb_node ** rb_link, * rb_parent;
32267
32268+#ifdef CONFIG_PAX_SEGMEXEC
32269+ struct vm_area_struct *vma_m = NULL;
32270+#endif
32271+
32272 /*
32273 * The vm_pgoff of a purely anonymous vma should be irrelevant
32274 * until its first write fault, when page's anon_vma and index
32275@@ -2036,7 +2377,22 @@ int insert_vm_struct(struct mm_struct *
32276 (security_vm_enough_memory(vma_pages(vma)) ||
32277 !vx_vmpages_avail(mm, vma_pages(vma))))
32278 return -ENOMEM;
32279+
32280+#ifdef CONFIG_PAX_SEGMEXEC
32281+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
32282+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
32283+ if (!vma_m)
32284+ return -ENOMEM;
32285+ }
32286+#endif
32287+
32288 vma_link(mm, vma, prev, rb_link, rb_parent);
32289+
32290+#ifdef CONFIG_PAX_SEGMEXEC
32291+ if (vma_m)
32292+ pax_mirror_vma(vma_m, vma);
32293+#endif
32294+
32295 return 0;
32296 }
32297
32298@@ -2094,6 +2450,30 @@ struct vm_area_struct *copy_vma(struct v
32299 return new_vma;
32300 }
32301
32302+#ifdef CONFIG_PAX_SEGMEXEC
32303+void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
32304+{
32305+ struct vm_area_struct *prev_m;
32306+ struct rb_node **rb_link_m, *rb_parent_m;
32307+
32308+ BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
32309+ BUG_ON(vma->vm_mirror || vma_m->vm_mirror || vma_policy(vma));
32310+ *vma_m = *vma;
32311+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
32312+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
32313+ vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
32314+ vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
32315+ if (vma_m->vm_file)
32316+ get_file(vma_m->vm_file);
32317+ if (vma_m->vm_ops && vma_m->vm_ops->open)
32318+ vma_m->vm_ops->open(vma_m);
32319+ find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
32320+ vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
32321+ vma_m->vm_mirror = vma;
32322+ vma->vm_mirror = vma_m;
32323+}
32324+#endif
32325+
32326 /*
32327 * Return true if the calling process may expand its vm space by the passed
32328 * number of pages
32329@@ -2104,7 +2484,7 @@ int may_expand_vm(struct mm_struct *mm,
32330 unsigned long lim;
32331
32332 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
32333-
32334+ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
32335 if (cur + npages > lim)
32336 return 0;
32337 if (!vx_vmpages_avail(mm, npages))
32338@@ -2118,7 +2498,7 @@ @@ static struct page *special_mapping_nopa
32339 {
32340 struct page **pages;
32341
32342- BUG_ON(address < vma->vm_start || address >= vma->vm_end);
32343+ BUG_ON(address < vma->vm_start || address >= vma->vm_end || (address & ~PAGE_MASK));
32344
32345 address -= vma->vm_start;
32346 for (pages = vma->vm_private_data; address > 0 && *pages; ++pages)
32347@@ -2168,8 +2548,17 @@ int install_special_mapping(struct mm_st
32348 vma->vm_start = addr;
32349 vma->vm_end = addr + len;
32350
32351+#ifdef CONFIG_PAX_MPROTECT
32352+ if (mm->pax_flags & MF_PAX_MPROTECT) {
32353+ if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
32354+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
32355+ else
32356+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
32357+ }
32358+#endif
32359+
32360 vma->vm_flags = vm_flags | mm->def_flags;
32361- vma->vm_page_prot = protection_map[vma->vm_flags & 7];
32362+ vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
32363
32364 vma->vm_ops = &special_mapping_vmops;
32365 vma->vm_private_data = pages;
32366diff -urNp linux-2.6.22.1/mm/mprotect.c linux-2.6.22.1/mm/mprotect.c
32367--- linux-2.6.22.1/mm/mprotect.c 2007-07-10 14:56:30.000000000 -0400
32368+++ linux-2.6.22.1/mm/mprotect.c 2007-08-02 11:41:53.000000000 -0400
32369@@ -21,10 +21,17 @@
32370 #include <linux/syscalls.h>
32371 #include <linux/swap.h>
32372 #include <linux/swapops.h>
32373+#include <linux/grsecurity.h>
32374+
32375+#ifdef CONFIG_PAX_MPROTECT
32376+#include <linux/elf.h>
32377+#endif
32378+
32379 #include <asm/uaccess.h>
32380 #include <asm/pgtable.h>
32381 #include <asm/cacheflush.h>
32382 #include <asm/tlbflush.h>
32383+#include <asm/mmu_context.h>
32384
32385 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
32386 unsigned long addr, unsigned long end, pgprot_t newprot,
32387@@ -128,6 +135,49 @@ static void change_protection(struct vm_
32388 flush_tlb_range(vma, start, end);
32389 }
32390
32391+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
32392+/* called while holding the mmap semaphor for writing */
32393+static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
32394+{
32395+ struct vm_area_struct *vma = find_vma(mm, start);
32396+
32397+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
32398+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
32399+}
32400+
32401+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
32402+{
32403+ unsigned long oldlimit, newlimit = 0UL;
32404+
32405+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
32406+ return;
32407+
32408+ spin_lock(&mm->page_table_lock);
32409+ oldlimit = mm->context.user_cs_limit;
32410+ if ((prot & VM_EXEC) && oldlimit < end)
32411+ /* USER_CS limit moved up */
32412+ newlimit = end;
32413+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
32414+ /* USER_CS limit moved down */
32415+ newlimit = start;
32416+
32417+ if (newlimit) {
32418+ mm->context.user_cs_limit = newlimit;
32419+
32420+#ifdef CONFIG_SMP
32421+ wmb();
32422+ cpus_clear(mm->context.cpu_user_cs_mask);
32423+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
32424+#endif
32425+
32426+ set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
32427+ }
32428+ spin_unlock(&mm->page_table_lock);
32429+ if (newlimit == end)
32430+ establish_user_cs_limit(mm, oldlimit, end);
32431+}
32432+#endif
32433+
32434 static int
32435 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
32436 unsigned long start, unsigned long end, unsigned long newflags)
32437@@ -140,11 +190,39 @@ mprotect_fixup(struct vm_area_struct *vm
32438 int error;
32439 int dirty_accountable = 0;
32440
32441+#ifdef CONFIG_PAX_SEGMEXEC
32442+ struct vm_area_struct *vma_m = NULL;
32443+ unsigned long start_m, end_m;
32444+
32445+ start_m = start + SEGMEXEC_TASK_SIZE;
32446+ end_m = end + SEGMEXEC_TASK_SIZE;
32447+#endif
32448+
32449 if (newflags == oldflags) {
32450 *pprev = vma;
32451 return 0;
32452 }
32453
32454+#ifdef CONFIG_PAX_SEGMEXEC
32455+ if (pax_find_mirror_vma(vma) && !(newflags & VM_EXEC)) {
32456+ if (start != vma->vm_start) {
32457+ error = split_vma(mm, vma, start, 1);
32458+ if (error)
32459+ return -ENOMEM;
32460+ }
32461+
32462+ if (end != vma->vm_end) {
32463+ error = split_vma(mm, vma, end, 0);
32464+ if (error)
32465+ return -ENOMEM;
32466+ }
32467+
32468+ error = __do_munmap(mm, start_m, end_m - start_m);
32469+ if (error)
32470+ return -ENOMEM;
32471+ }
32472+#endif
32473+
32474 /*
32475 * If we make a private mapping writable we increase our commit;
32476 * but (without finer accounting) cannot reduce our commit if we
32477@@ -187,17 +265,25 @@ mprotect_fixup(struct vm_area_struct *vm
32478 goto fail;
32479 }
32480
32481+#ifdef CONFIG_PAX_SEGMEXEC
32482+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(oldflags & VM_EXEC) && (newflags & VM_EXEC)) {
32483+ vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
32484+ if (!vma_m) {
32485+ error = -ENOMEM;
32486+ goto fail;
32487+ }
32488+ }
32489+#endif
32490+
32491 success:
32492 /*
32493 * vm_flags and vm_page_prot are protected by the mmap_sem
32494 * held in write mode.
32495 */
32496 vma->vm_flags = newflags;
32497- vma->vm_page_prot = protection_map[newflags &
32498- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
32499+ vma->vm_page_prot = vm_get_page_prot(newflags);
32500 if (vma_wants_writenotify(vma)) {
32501- vma->vm_page_prot = protection_map[newflags &
32502- (VM_READ|VM_WRITE|VM_EXEC)];
32503+ vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
32504 dirty_accountable = 1;
32505 }
32506
32507@@ -205,6 +291,12 @@ success:
32508 hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
32509 else
32510 change_protection(vma, start, end, vma->vm_page_prot, dirty_accountable);
32511+
32512+#ifdef CONFIG_PAX_SEGMEXEC
32513+ if (vma_m)
32514+ pax_mirror_vma(vma_m, vma);
32515+#endif
32516+
32517 vm_stat_account(mm, oldflags, vma->vm_file, -nrpages);
32518 vm_stat_account(mm, newflags, vma->vm_file, nrpages);
32519 return 0;
32520@@ -214,6 +306,70 @@ fail:
32521 return error;
32522 }
32523
32524+#ifdef CONFIG_PAX_MPROTECT
32525+/* PaX: non-PIC ELF libraries need relocations on their executable segments
32526+ * therefore we'll grant them VM_MAYWRITE once during their life.
32527+ *
32528+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
32529+ * basis because we want to allow the common case and not the special ones.
32530+ */
32531+static inline void pax_handle_maywrite(struct vm_area_struct *vma, unsigned long start)
32532+{
32533+ struct elfhdr elf_h;
32534+ struct elf_phdr elf_p;
32535+ elf_addr_t dyn_offset = 0UL;
32536+ elf_dyn dyn;
32537+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
32538+
32539+#ifndef CONFIG_PAX_NOELFRELOCS
32540+ if ((vma->vm_start != start) ||
32541+ !vma->vm_file ||
32542+ !(vma->vm_flags & VM_MAYEXEC) ||
32543+ (vma->vm_flags & VM_MAYNOTWRITE))
32544+#endif
32545+
32546+ return;
32547+
32548+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
32549+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
32550+
32551+#ifdef CONFIG_PAX_ETEXECRELOCS
32552+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
32553+#else
32554+ elf_h.e_type != ET_DYN ||
32555+#endif
32556+
32557+ !elf_check_arch(&elf_h) ||
32558+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
32559+ elf_h.e_phnum > j)
32560+ return;
32561+
32562+ for (i = 0UL; i < elf_h.e_phnum; i++) {
32563+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
32564+ return;
32565+ if (elf_p.p_type == PT_DYNAMIC) {
32566+ dyn_offset = elf_p.p_offset;
32567+ j = i;
32568+ }
32569+ }
32570+ if (elf_h.e_phnum <= j)
32571+ return;
32572+
32573+ i = 0UL;
32574+ do {
32575+ if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
32576+ return;
32577+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
32578+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
32579+ gr_log_textrel(vma);
32580+ return;
32581+ }
32582+ i++;
32583+ } while (dyn.d_tag != DT_NULL);
32584+ return;
32585+}
32586+#endif
32587+
32588 asmlinkage long
32589 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
32590 {
32591@@ -233,6 +389,17 @@ sys_mprotect(unsigned long start, size_t
32592 end = start + len;
32593 if (end <= start)
32594 return -ENOMEM;
32595+
32596+#ifdef CONFIG_PAX_SEGMEXEC
32597+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
32598+ if (end > SEGMEXEC_TASK_SIZE)
32599+ return -EINVAL;
32600+ } else
32601+#endif
32602+
32603+ if (end > TASK_SIZE)
32604+ return -EINVAL;
32605+
32606 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
32607 return -EINVAL;
32608
32609@@ -240,7 +407,7 @@ sys_mprotect(unsigned long start, size_t
32610 /*
32611 * Does the application expect PROT_READ to imply PROT_EXEC:
32612 */
32613- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
32614+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
32615 prot |= PROT_EXEC;
32616
32617 vm_flags = calc_vm_prot_bits(prot);
32618@@ -272,6 +439,16 @@ sys_mprotect(unsigned long start, size_t
32619 if (start > vma->vm_start)
32620 prev = vma;
32621
32622+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
32623+ error = -EACCES;
32624+ goto out;
32625+ }
32626+
32627+#ifdef CONFIG_PAX_MPROTECT
32628+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
32629+ pax_handle_maywrite(vma, start);
32630+#endif
32631+
32632 for (nstart = start ; ; ) {
32633 unsigned long newflags;
32634
32635@@ -285,6 +462,12 @@ sys_mprotect(unsigned long start, size_t
32636 goto out;
32637 }
32638
32639+#ifdef CONFIG_PAX_MPROTECT
32640+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
32641+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
32642+ newflags &= ~VM_MAYWRITE;
32643+#endif
32644+
32645 error = security_file_mprotect(vma, reqprot, prot);
32646 if (error)
32647 goto out;
32648@@ -295,6 +478,9 @@ sys_mprotect(unsigned long start, size_t
32649 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
32650 if (error)
32651 goto out;
32652+
32653+ track_exec_limit(current->mm, nstart, tmp, vm_flags);
32654+
32655 nstart = tmp;
32656
32657 if (nstart < prev->vm_end)
32658diff -urNp linux-2.6.22.1/mm/mremap.c linux-2.6.22.1/mm/mremap.c
32659--- linux-2.6.22.1/mm/mremap.c 2007-07-10 14:56:30.000000000 -0400
32660+++ linux-2.6.22.1/mm/mremap.c 2007-08-02 11:38:48.000000000 -0400
32661@@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
32662 continue;
32663 pte = ptep_clear_flush(vma, old_addr, old_pte);
32664 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
32665+
32666+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
32667+ if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
32668+ pte = pte_exprotect(pte);
32669+#endif
32670+
32671 set_pte_at(mm, new_addr, new_pte, pte);
32672 }
32673
32674@@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
32675 struct vm_area_struct *vma;
32676 unsigned long ret = -EINVAL;
32677 unsigned long charged = 0;
32678+ unsigned long task_size = TASK_SIZE;
32679
32680 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
32681 goto out;
32682@@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
32683 if (!new_len)
32684 goto out;
32685
32686+#ifdef CONFIG_PAX_SEGMEXEC
32687+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
32688+ task_size = SEGMEXEC_TASK_SIZE;
32689+#endif
32690+
32691+ if (new_len > task_size || addr > task_size-new_len ||
32692+ old_len > task_size || addr > task_size-old_len)
32693+ goto out;
32694+
32695 /* new_addr is only valid if MREMAP_FIXED is specified */
32696 if (flags & MREMAP_FIXED) {
32697 if (new_addr & ~PAGE_MASK)
32698@@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
32699 if (!(flags & MREMAP_MAYMOVE))
32700 goto out;
32701
32702- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
32703+ if (new_addr > task_size - new_len)
32704 goto out;
32705
32706 /* Check if the location we're moving into overlaps the
32707 * old location at all, and fail if it does.
32708 */
32709- if ((new_addr <= addr) && (new_addr+new_len) > addr)
32710- goto out;
32711-
32712- if ((addr <= new_addr) && (addr+old_len) > new_addr)
32713+ if (addr + old_len > new_addr && new_addr + new_len > addr)
32714 goto out;
32715
32716 ret = do_munmap(mm, new_addr, new_len);
32717@@ -322,6 +335,14 @@ unsigned long do_mremap(unsigned long ad
32718 ret = -EINVAL;
32719 goto out;
32720 }
32721+
32722+#ifdef CONFIG_PAX_SEGMEXEC
32723+ if (pax_find_mirror_vma(vma)) {
32724+ ret = -EINVAL;
32725+ goto out;
32726+ }
32727+#endif
32728+
32729 /* We can't remap across vm area boundaries */
32730 if (old_len > vma->vm_end - addr)
32731 goto out;
32732@@ -355,7 +376,7 @@ unsigned long do_mremap(unsigned long ad
32733 if (old_len == vma->vm_end - addr &&
32734 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
32735 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
32736- unsigned long max_addr = TASK_SIZE;
32737+ unsigned long max_addr = task_size;
32738 if (vma->vm_next)
32739 max_addr = vma->vm_next->vm_start;
32740 /* can we just expand the current mapping? */
32741@@ -373,6 +394,7 @@ unsigned long do_mremap(unsigned long ad
32742 addr + new_len);
32743 }
32744 ret = addr;
32745+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
32746 goto out;
32747 }
32748 }
32749@@ -383,8 +405,8 @@ unsigned long do_mremap(unsigned long ad
32750 */
32751 ret = -ENOMEM;
32752 if (flags & MREMAP_MAYMOVE) {
32753+ unsigned long map_flags = 0;
32754 if (!(flags & MREMAP_FIXED)) {
32755- unsigned long map_flags = 0;
32756 if (vma->vm_flags & VM_MAYSHARE)
32757 map_flags |= MAP_SHARED;
32758
32759@@ -394,7 +416,12 @@ unsigned long do_mremap(unsigned long ad
32760 if (new_addr & ~PAGE_MASK)
32761 goto out;
32762 }
32763+ map_flags = vma->vm_flags;
32764 ret = move_vma(vma, addr, old_len, new_len, new_addr);
32765+ if (!(ret & ~PAGE_MASK)) {
32766+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
32767+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
32768+ }
32769 }
32770 out:
32771 if (ret & ~PAGE_MASK)
32772diff -urNp linux-2.6.22.1/mm/nommu.c linux-2.6.22.1/mm/nommu.c
32773--- linux-2.6.22.1/mm/nommu.c 2007-07-10 14:56:30.000000000 -0400
32774+++ linux-2.6.22.1/mm/nommu.c 2007-08-02 11:38:48.000000000 -0400
32775@@ -359,15 +359,6 @@ struct vm_area_struct *find_vma(struct m
32776 EXPORT_SYMBOL(find_vma);
32777
32778 /*
32779- * find a VMA
32780- * - we don't extend stack VMAs under NOMMU conditions
32781- */
32782-struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
32783-{
32784- return find_vma(mm, addr);
32785-}
32786-
32787-/*
32788 * look up the first VMA exactly that exactly matches addr
32789 * - should be called with mm->mmap_sem at least held readlocked
32790 */
32791diff -urNp linux-2.6.22.1/mm/page_alloc.c linux-2.6.22.1/mm/page_alloc.c
32792--- linux-2.6.22.1/mm/page_alloc.c 2007-07-10 14:56:30.000000000 -0400
32793+++ linux-2.6.22.1/mm/page_alloc.c 2007-08-02 11:38:48.000000000 -0400
32794@@ -393,7 +393,7 @@ static inline int page_is_buddy(struct p
32795 static inline void __free_one_page(struct page *page,
32796 struct zone *zone, unsigned int order)
32797 {
32798- unsigned long page_idx;
32799+ unsigned long page_idx, index;
32800 int order_size = 1 << order;
32801
32802 if (unlikely(PageCompound(page)))
32803@@ -404,6 +404,11 @@ static inline void __free_one_page(struc
32804 VM_BUG_ON(page_idx & (order_size - 1));
32805 VM_BUG_ON(bad_range(zone, page));
32806
32807+#ifdef CONFIG_PAX_MEMORY_SANITIZE
32808+ for (index = order_size; index; --index)
32809+ sanitize_highpage(page + index - 1);
32810+#endif
32811+
32812 __mod_zone_page_state(zone, NR_FREE_PAGES, order_size);
32813 while (order < MAX_ORDER-1) {
32814 unsigned long combined_idx;
32815diff -urNp linux-2.6.22.1/mm/rmap.c linux-2.6.22.1/mm/rmap.c
32816--- linux-2.6.22.1/mm/rmap.c 2007-07-10 14:56:30.000000000 -0400
32817+++ linux-2.6.22.1/mm/rmap.c 2007-08-02 11:38:48.000000000 -0400
32818@@ -63,6 +63,10 @@ int anon_vma_prepare(struct vm_area_stru
32819 struct mm_struct *mm = vma->vm_mm;
32820 struct anon_vma *allocated, *locked;
32821
32822+#ifdef CONFIG_PAX_SEGMEXEC
32823+ struct vm_area_struct *vma_m;
32824+#endif
32825+
32826 anon_vma = find_mergeable_anon_vma(vma);
32827 if (anon_vma) {
32828 allocated = NULL;
32829@@ -79,6 +83,15 @@ int anon_vma_prepare(struct vm_area_stru
32830 /* page_table_lock to protect against threads */
32831 spin_lock(&mm->page_table_lock);
32832 if (likely(!vma->anon_vma)) {
32833+
32834+#ifdef CONFIG_PAX_SEGMEXEC
32835+ vma_m = pax_find_mirror_vma(vma);
32836+ if (vma_m) {
32837+ vma_m->anon_vma = anon_vma;
32838+ __anon_vma_link(vma_m);
32839+ }
32840+#endif
32841+
32842 vma->anon_vma = anon_vma;
32843 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
32844 allocated = NULL;
32845diff -urNp linux-2.6.22.1/mm/shmem.c linux-2.6.22.1/mm/shmem.c
32846--- linux-2.6.22.1/mm/shmem.c 2007-07-10 14:56:30.000000000 -0400
32847+++ linux-2.6.22.1/mm/shmem.c 2007-08-02 11:09:17.000000000 -0400
32848@@ -2484,7 +2484,7 @@ static struct file_system_type tmpfs_fs_
32849 .get_sb = shmem_get_sb,
32850 .kill_sb = kill_litter_super,
32851 };
32852-static struct vfsmount *shm_mnt;
32853+struct vfsmount *shm_mnt;
32854
32855 static int __init init_tmpfs(void)
32856 {
32857diff -urNp linux-2.6.22.1/mm/slab.c linux-2.6.22.1/mm/slab.c
32858--- linux-2.6.22.1/mm/slab.c 2007-07-10 14:56:30.000000000 -0400
32859+++ linux-2.6.22.1/mm/slab.c 2007-08-02 11:38:48.000000000 -0400
32860@@ -306,7 +306,7 @@ struct kmem_list3 {
32861 * Need this for bootstrapping a per node allocator.
32862 */
32863 #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
32864-struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
32865+struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
32866 #define CACHE_CACHE 0
32867 #define SIZE_AC 1
32868 #define SIZE_L3 (1 + MAX_NUMNODES)
32869@@ -655,14 +655,14 @@ struct cache_names {
32870 static struct cache_names __initdata cache_names[] = {
32871 #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
32872 #include <linux/kmalloc_sizes.h>
32873- {NULL,}
32874+ {NULL, NULL}
32875 #undef CACHE
32876 };
32877
32878 static struct arraycache_init initarray_cache __initdata =
32879- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
32880+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
32881 static struct arraycache_init initarray_generic =
32882- { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
32883+ { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
32884
32885 /* internal cache of cache description objs */
32886 static struct kmem_cache cache_cache = {
32887@@ -2977,7 +2977,7 @@ retry:
32888 * there must be at least one object available for
32889 * allocation.
32890 */
32891- BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
32892+ BUG_ON(slabp->inuse >= cachep->num);
32893
32894 while (slabp->inuse < cachep->num && batchcount--) {
32895 STATS_INC_ALLOCED(cachep);
32896diff -urNp linux-2.6.22.1/mm/slub.c linux-2.6.22.1/mm/slub.c
32897--- linux-2.6.22.1/mm/slub.c 2007-07-10 14:56:30.000000000 -0400
32898+++ linux-2.6.22.1/mm/slub.c 2007-08-03 12:34:39.000000000 -0400
32899@@ -1480,7 +1480,7 @@ debug:
32900 *
32901 * Otherwise we can simply pick the next object from the lockless free list.
32902 */
32903-static void __always_inline *slab_alloc(struct kmem_cache *s,
32904+static __always_inline void *slab_alloc(struct kmem_cache *s,
32905 gfp_t gfpflags, int node, void *addr)
32906 {
32907 struct page *page;
32908@@ -1585,7 +1585,7 @@ debug:
32909 * If fastpath is not possible then fall back to __slab_free where we deal
32910 * with all sorts of special processing.
32911 */
32912-static void __always_inline slab_free(struct kmem_cache *s,
32913+static __always_inline void slab_free(struct kmem_cache *s,
32914 struct page *page, void *x, void *addr)
32915 {
32916 void **object = (void *)x;
32917diff -urNp linux-2.6.22.1/mm/swap.c linux-2.6.22.1/mm/swap.c
32918--- linux-2.6.22.1/mm/swap.c 2007-07-10 14:56:30.000000000 -0400
32919+++ linux-2.6.22.1/mm/swap.c 2007-08-02 11:38:48.000000000 -0400
32920@@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed);
32921 * lru_cache_add: add a page to the page lists
32922 * @page: the page to add
32923 */
32924-static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
32925-static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
32926+static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
32927+static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
32928
32929 void fastcall lru_cache_add(struct page *page)
32930 {
32931diff -urNp linux-2.6.22.1/mm/tiny-shmem.c linux-2.6.22.1/mm/tiny-shmem.c
32932--- linux-2.6.22.1/mm/tiny-shmem.c 2007-07-10 14:56:30.000000000 -0400
32933+++ linux-2.6.22.1/mm/tiny-shmem.c 2007-08-02 11:09:17.000000000 -0400
32934@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
32935 .kill_sb = kill_litter_super,
32936 };
32937
32938-static struct vfsmount *shm_mnt;
32939+struct vfsmount *shm_mnt;
32940
32941 static int __init init_tmpfs(void)
32942 {
32943diff -urNp linux-2.6.22.1/mm/vmalloc.c linux-2.6.22.1/mm/vmalloc.c
32944--- linux-2.6.22.1/mm/vmalloc.c 2007-07-10 14:56:30.000000000 -0400
32945+++ linux-2.6.22.1/mm/vmalloc.c 2007-08-02 11:38:48.000000000 -0400
32946@@ -195,6 +195,8 @@ static struct vm_struct *__get_vm_area_n
32947
32948 write_lock(&vmlist_lock);
32949 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
32950+ if (addr > end - size)
32951+ goto out;
32952 if ((unsigned long)tmp->addr < addr) {
32953 if((unsigned long)tmp->addr + tmp->size >= addr)
32954 addr = ALIGN(tmp->size +
32955@@ -206,8 +208,6 @@ static struct vm_struct *__get_vm_area_n
32956 if (size + addr <= (unsigned long)tmp->addr)
32957 goto found;
32958 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
32959- if (addr > end - size)
32960- goto out;
32961 }
32962
32963 found:
32964diff -urNp linux-2.6.22.1/net/core/flow.c linux-2.6.22.1/net/core/flow.c
32965--- linux-2.6.22.1/net/core/flow.c 2007-07-10 14:56:30.000000000 -0400
32966+++ linux-2.6.22.1/net/core/flow.c 2007-08-02 11:38:48.000000000 -0400
32967@@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
32968
32969 static u32 flow_hash_shift;
32970 #define flow_hash_size (1 << flow_hash_shift)
32971-static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
32972+static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
32973
32974 #define flow_table(cpu) (per_cpu(flow_tables, cpu))
32975
32976@@ -53,7 +53,7 @@ struct flow_percpu_info {
32977 u32 hash_rnd;
32978 int count;
32979 } ____cacheline_aligned;
32980-static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
32981+static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
32982
32983 #define flow_hash_rnd_recalc(cpu) \
32984 (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
32985@@ -70,7 +70,7 @@ struct flow_flush_info {
32986 atomic_t cpuleft;
32987 struct completion completion;
32988 };
32989-static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
32990+static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
32991
32992 #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
32993
32994diff -urNp linux-2.6.22.1/net/dccp/ccids/ccid3.c linux-2.6.22.1/net/dccp/ccids/ccid3.c
32995--- linux-2.6.22.1/net/dccp/ccids/ccid3.c 2007-07-10 14:56:30.000000000 -0400
32996+++ linux-2.6.22.1/net/dccp/ccids/ccid3.c 2007-08-02 11:38:48.000000000 -0400
32997@@ -44,7 +44,7 @@
32998 static int ccid3_debug;
32999 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
33000 #else
33001-#define ccid3_pr_debug(format, a...)
33002+#define ccid3_pr_debug(format, a...) do {} while (0)
33003 #endif
33004
33005 static struct dccp_tx_hist *ccid3_tx_hist;
33006@@ -829,7 +829,7 @@ static u32 ccid3_hc_rx_calc_first_li(str
33007 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
33008 u32 x_recv, p;
33009 suseconds_t rtt, delta;
33010- struct timeval tstamp = { 0, };
33011+ struct timeval tstamp = { 0, 0 };
33012 int interval = 0;
33013 int win_count = 0;
33014 int step = 0;
33015diff -urNp linux-2.6.22.1/net/dccp/dccp.h linux-2.6.22.1/net/dccp/dccp.h
33016--- linux-2.6.22.1/net/dccp/dccp.h 2007-07-10 14:56:30.000000000 -0400
33017+++ linux-2.6.22.1/net/dccp/dccp.h 2007-08-02 11:38:48.000000000 -0400
33018@@ -42,8 +42,8 @@ extern int dccp_debug;
33019 #define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
33020 #define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
33021 #else
33022-#define dccp_pr_debug(format, a...)
33023-#define dccp_pr_debug_cat(format, a...)
33024+#define dccp_pr_debug(format, a...) do {} while (0)
33025+#define dccp_pr_debug_cat(format, a...) do {} while (0)
33026 #endif
33027
33028 extern struct inet_hashinfo dccp_hashinfo;
33029diff -urNp linux-2.6.22.1/net/ipv4/inet_connection_sock.c linux-2.6.22.1/net/ipv4/inet_connection_sock.c
33030--- linux-2.6.22.1/net/ipv4/inet_connection_sock.c 2007-07-10 14:56:30.000000000 -0400
33031+++ linux-2.6.22.1/net/ipv4/inet_connection_sock.c 2007-08-02 11:09:17.000000000 -0400
33032@@ -15,6 +15,7 @@
33033
33034 #include <linux/module.h>
33035 #include <linux/jhash.h>
33036+#include <linux/grsecurity.h>
33037
33038 #include <net/inet_connection_sock.h>
33039 #include <net/inet_hashtables.h>
33040diff -urNp linux-2.6.22.1/net/ipv4/inet_hashtables.c linux-2.6.22.1/net/ipv4/inet_hashtables.c
33041--- linux-2.6.22.1/net/ipv4/inet_hashtables.c 2007-07-10 14:56:30.000000000 -0400
33042+++ linux-2.6.22.1/net/ipv4/inet_hashtables.c 2007-08-02 11:09:17.000000000 -0400
33043@@ -18,11 +18,14 @@
33044 #include <linux/sched.h>
33045 #include <linux/slab.h>
33046 #include <linux/wait.h>
33047+#include <linux/grsecurity.h>
33048
33049 #include <net/inet_connection_sock.h>
33050 #include <net/inet_hashtables.h>
33051 #include <net/ip.h>
33052
33053+extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
33054+
33055 /*
33056 * Allocate and initialize a new local port bind bucket.
33057 * The bindhash mutex for snum's hash chain must be held here.
33058@@ -338,6 +341,8 @@ ok:
33059 }
33060 spin_unlock(&head->lock);
33061
33062+ gr_update_task_in_ip_table(current, inet_sk(sk));
33063+
33064 if (tw) {
33065 inet_twsk_deschedule(tw, death_row);
33066 inet_twsk_put(tw);
33067diff -urNp linux-2.6.22.1/net/ipv4/netfilter/ipt_stealth.c linux-2.6.22.1/net/ipv4/netfilter/ipt_stealth.c
33068--- linux-2.6.22.1/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
33069+++ linux-2.6.22.1/net/ipv4/netfilter/ipt_stealth.c 2007-08-02 11:09:17.000000000 -0400
33070@@ -0,0 +1,114 @@
33071+/* Kernel module to add stealth support.
33072+ *
33073+ * Copyright (C) 2002-2006 Brad Spengler <spender@grsecurity.net>
33074+ *
33075+ */
33076+
33077+#include <linux/kernel.h>
33078+#include <linux/module.h>
33079+#include <linux/skbuff.h>
33080+#include <linux/net.h>
33081+#include <linux/sched.h>
33082+#include <linux/inet.h>
33083+#include <linux/stddef.h>
33084+
33085+#include <net/ip.h>
33086+#include <net/sock.h>
33087+#include <net/tcp.h>
33088+#include <net/udp.h>
33089+#include <net/route.h>
33090+#include <net/inet_common.h>
33091+
33092+#include <linux/netfilter_ipv4/ip_tables.h>
33093+
33094+MODULE_LICENSE("GPL");
33095+
33096+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
33097+
33098+static int
33099+match(const struct sk_buff *skb,
33100+ const struct net_device *in,
33101+ const struct net_device *out,
33102+ const struct xt_match *match,
33103+ const void *matchinfo,
33104+ int offset,
33105+ unsigned int protoff,
33106+ int *hotdrop)
33107+{
33108+ struct iphdr *ip = ip_hdr(skb);
33109+ struct tcphdr th;
33110+ struct udphdr uh;
33111+ struct sock *sk = NULL;
33112+
33113+ if (!ip || offset) return 0;
33114+
33115+ switch(ip->protocol) {
33116+ case IPPROTO_TCP:
33117+ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
33118+ *hotdrop = 1;
33119+ return 0;
33120+ }
33121+ if (!(th.syn && !th.ack)) return 0;
33122+ sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb));
33123+ break;
33124+ case IPPROTO_UDP:
33125+ if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
33126+ *hotdrop = 1;
33127+ return 0;
33128+ }
33129+ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
33130+ break;
33131+ default:
33132+ return 0;
33133+ }
33134+
33135+ if(!sk) // port is being listened on, match this
33136+ return 1;
33137+ else {
33138+ sock_put(sk);
33139+ return 0;
33140+ }
33141+}
33142+
33143+/* Called when user tries to insert an entry of this type. */
33144+static int
33145+checkentry(const char *tablename,
33146+ const void *nip,
33147+ const struct xt_match *match,
33148+ void *matchinfo,
33149+ unsigned int hook_mask)
33150+{
33151+ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
33152+
33153+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
33154+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
33155+ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
33156+ return 1;
33157+
33158+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
33159+
33160+ return 0;
33161+}
33162+
33163+
33164+static struct xt_match stealth_match = {
33165+ .name = "stealth",
33166+ .family = AF_INET,
33167+ .match = match,
33168+ .checkentry = checkentry,
33169+ .destroy = NULL,
33170+ .me = THIS_MODULE
33171+};
33172+
33173+static int __init init(void)
33174+{
33175+ return xt_register_match(&stealth_match);
33176+}
33177+
33178+static void __exit fini(void)
33179+{
33180+ xt_unregister_match(&stealth_match);
33181+}
33182+
33183+module_init(init);
33184+module_exit(fini);
33185diff -urNp linux-2.6.22.1/net/ipv4/netfilter/Kconfig linux-2.6.22.1/net/ipv4/netfilter/Kconfig
33186--- linux-2.6.22.1/net/ipv4/netfilter/Kconfig 2007-07-10 14:56:30.000000000 -0400
33187+++ linux-2.6.22.1/net/ipv4/netfilter/Kconfig 2007-08-02 11:09:17.000000000 -0400
33188@@ -130,6 +130,21 @@ config IP_NF_MATCH_ADDRTYPE
33189 If you want to compile it as a module, say M here and read
33190 <file:Documentation/modules.txt>. If unsure, say `N'.
33191
33192+config IP_NF_MATCH_STEALTH
33193+ tristate "stealth match support"
33194+ depends on IP_NF_IPTABLES
33195+ help
33196+ Enabling this option will drop all syn packets coming to unserved tcp
33197+ ports as well as all packets coming to unserved udp ports. If you
33198+ are using your system to route any type of packets (ie. via NAT)
33199+ you should put this module at the end of your ruleset, since it will
33200+ drop packets that aren't going to ports that are listening on your
33201+ machine itself, it doesn't take into account that the packet might be
33202+ destined for someone on your internal network if you're using NAT for
33203+ instance.
33204+
33205+ To compile it as a module, choose M here. If unsure, say N.
33206+
33207 # `filter', generic and specific targets
33208 config IP_NF_FILTER
33209 tristate "Packet filtering"
33210@@ -403,4 +418,3 @@ config IP_NF_ARP_MANGLE
33211 hardware and network addresses.
33212
33213 endmenu
33214-
33215diff -urNp linux-2.6.22.1/net/ipv4/netfilter/Makefile linux-2.6.22.1/net/ipv4/netfilter/Makefile
33216--- linux-2.6.22.1/net/ipv4/netfilter/Makefile 2007-07-10 14:56:30.000000000 -0400
33217+++ linux-2.6.22.1/net/ipv4/netfilter/Makefile 2007-08-02 11:09:17.000000000 -0400
33218@@ -49,6 +49,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn
33219 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
33220 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
33221 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
33222+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
33223
33224 # targets
33225 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
33226diff -urNp linux-2.6.22.1/net/ipv4/tcp_ipv4.c linux-2.6.22.1/net/ipv4/tcp_ipv4.c
33227--- linux-2.6.22.1/net/ipv4/tcp_ipv4.c 2007-07-10 14:56:30.000000000 -0400
33228+++ linux-2.6.22.1/net/ipv4/tcp_ipv4.c 2007-08-02 11:09:17.000000000 -0400
33229@@ -61,6 +61,7 @@
33230 #include <linux/jhash.h>
33231 #include <linux/init.h>
33232 #include <linux/times.h>
33233+#include <linux/grsecurity.h>
33234
33235 #include <net/icmp.h>
33236 #include <net/inet_hashtables.h>
33237diff -urNp linux-2.6.22.1/net/ipv4/udp.c linux-2.6.22.1/net/ipv4/udp.c
33238--- linux-2.6.22.1/net/ipv4/udp.c 2007-07-10 14:56:30.000000000 -0400
33239+++ linux-2.6.22.1/net/ipv4/udp.c 2007-08-02 11:28:52.000000000 -0400
33240@@ -97,12 +97,19 @@
33241 #include <linux/skbuff.h>
33242 #include <linux/proc_fs.h>
33243 #include <linux/seq_file.h>
33244+#include <linux/grsecurity.h>
33245 #include <net/icmp.h>
33246 #include <net/route.h>
33247 #include <net/checksum.h>
33248 #include <net/xfrm.h>
33249 #include "udp_impl.h"
33250
33251+extern int gr_search_udp_recvmsg(const struct sock *sk,
33252+ const struct sk_buff *skb);
33253+extern int gr_search_udp_sendmsg(const struct sock *sk,
33254+ const struct sockaddr_in *addr);
33255+
33256+
33257 /*
33258 * Snmp MIB for the UDP layer
33259 */
33260@@ -286,6 +293,13 @@ static struct sock *__udp4_lib_lookup(__
33261 return result;
33262 }
33263
33264+struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
33265+ __be32 daddr, __be16 dport, int dif)
33266+{
33267+ return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
33268+}
33269+
33270+
33271 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
33272 __be16 loc_port, __be32 loc_addr,
33273 __be16 rmt_port, __be32 rmt_addr,
33274@@ -569,9 +583,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
33275 dport = usin->sin_port;
33276 if (dport == 0)
33277 return -EINVAL;
33278+
33279+ if (!gr_search_udp_sendmsg(sk, usin))
33280+ return -EPERM;
33281 } else {
33282 if (sk->sk_state != TCP_ESTABLISHED)
33283 return -EDESTADDRREQ;
33284+
33285+ if (!gr_search_udp_sendmsg(sk, NULL))
33286+ return -EPERM;
33287+
33288 daddr = inet->daddr;
33289 dport = inet->dport;
33290 /* Open fast path for connected socket.
33291@@ -833,6 +854,11 @@ try_again:
33292 if (!skb)
33293 goto out;
33294
33295+ if (!gr_search_udp_recvmsg(sk, skb)) {
33296+ err = -EPERM;
33297+ goto out_free;
33298+ }
33299+
33300 ulen = skb->len - sizeof(struct udphdr);
33301 copied = len;
33302 if (copied > ulen)
33303diff -urNp linux-2.6.22.1/net/ipv6/exthdrs.c linux-2.6.22.1/net/ipv6/exthdrs.c
33304--- linux-2.6.22.1/net/ipv6/exthdrs.c 2007-07-10 14:56:30.000000000 -0400
33305+++ linux-2.6.22.1/net/ipv6/exthdrs.c 2007-08-02 11:38:48.000000000 -0400
33306@@ -737,7 +737,7 @@ static struct tlvtype_proc tlvprochopopt
33307 .type = IPV6_TLV_JUMBO,
33308 .func = ipv6_hop_jumbo,
33309 },
33310- { -1, }
33311+ { -1, NULL }
33312 };
33313
33314 int ipv6_parse_hopopts(struct sk_buff **skbp)
33315diff -urNp linux-2.6.22.1/net/ipv6/raw.c linux-2.6.22.1/net/ipv6/raw.c
33316--- linux-2.6.22.1/net/ipv6/raw.c 2007-07-10 14:56:30.000000000 -0400
33317+++ linux-2.6.22.1/net/ipv6/raw.c 2007-08-02 11:38:48.000000000 -0400
33318@@ -549,7 +549,7 @@ out:
33319 return err;
33320 }
33321
33322-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
33323+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
33324 struct flowi *fl, struct rt6_info *rt,
33325 unsigned int flags)
33326 {
33327diff -urNp linux-2.6.22.1/net/irda/ircomm/ircomm_tty.c linux-2.6.22.1/net/irda/ircomm/ircomm_tty.c
33328--- linux-2.6.22.1/net/irda/ircomm/ircomm_tty.c 2007-07-10 14:56:30.000000000 -0400
33329+++ linux-2.6.22.1/net/irda/ircomm/ircomm_tty.c 2007-08-02 11:38:48.000000000 -0400
33330@@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
33331 IRDA_DEBUG(2, "%s()\n", __FUNCTION__ );
33332
33333 line = tty->index;
33334- if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
33335+ if (line >= IRCOMM_TTY_PORTS) {
33336 return -ENODEV;
33337 }
33338
33339diff -urNp linux-2.6.22.1/net/mac80211/ieee80211.c linux-2.6.22.1/net/mac80211/ieee80211.c
33340--- linux-2.6.22.1/net/mac80211/ieee80211.c 2007-07-10 14:56:30.000000000 -0400
33341+++ linux-2.6.22.1/net/mac80211/ieee80211.c 2007-08-02 11:38:48.000000000 -0400
33342@@ -1118,7 +1118,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
33343 }
33344
33345
33346-static void inline
33347+static inline void
33348 __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
33349 struct sk_buff *skb,
33350 struct net_device *dev,
33351@@ -1164,7 +1164,7 @@ __ieee80211_tx_prepare(struct ieee80211_
33352
33353 }
33354
33355-static int inline is_ieee80211_device(struct net_device *dev,
33356+static inline int is_ieee80211_device(struct net_device *dev,
33357 struct net_device *master)
33358 {
33359 return (wdev_priv(dev->ieee80211_ptr) ==
33360@@ -1173,7 +1173,7 @@ static int inline is_ieee80211_device(st
33361
33362 /* Device in tx->dev has a reference added; use dev_put(tx->dev) when
33363 * finished with it. */
33364-static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
33365+static inline int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
33366 struct sk_buff *skb,
33367 struct net_device *mdev,
33368 struct ieee80211_tx_control *control)
33369diff -urNp linux-2.6.22.1/net/mac80211/ieee80211_ioctl.c linux-2.6.22.1/net/mac80211/ieee80211_ioctl.c
33370--- linux-2.6.22.1/net/mac80211/ieee80211_ioctl.c 2007-07-10 14:56:30.000000000 -0400
33371+++ linux-2.6.22.1/net/mac80211/ieee80211_ioctl.c 2007-08-02 11:38:48.000000000 -0400
33372@@ -399,14 +399,14 @@ static const struct ieee80211_channel_ra
33373 { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */,
33374 { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */,
33375 { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */,
33376- { 0 }
33377+ { 0, 0, 0, 0 }
33378 };
33379
33380 static const struct ieee80211_channel_range ieee80211_mkk_channels[] = {
33381 { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */,
33382 { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */,
33383 { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */,
33384- { 0 }
33385+ { 0, 0, 0, 0 }
33386 };
33387
33388
33389diff -urNp linux-2.6.22.1/net/sctp/socket.c linux-2.6.22.1/net/sctp/socket.c
33390--- linux-2.6.22.1/net/sctp/socket.c 2007-07-10 14:56:30.000000000 -0400
33391+++ linux-2.6.22.1/net/sctp/socket.c 2007-08-02 11:38:48.000000000 -0400
33392@@ -1391,7 +1391,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
33393 struct sctp_sndrcvinfo *sinfo;
33394 struct sctp_initmsg *sinit;
33395 sctp_assoc_t associd = 0;
33396- sctp_cmsgs_t cmsgs = { NULL };
33397+ sctp_cmsgs_t cmsgs = { NULL, NULL };
33398 int err;
33399 sctp_scope_t scope;
33400 long timeo;
33401diff -urNp linux-2.6.22.1/net/socket.c linux-2.6.22.1/net/socket.c
33402--- linux-2.6.22.1/net/socket.c 2007-07-10 14:56:30.000000000 -0400
33403+++ linux-2.6.22.1/net/socket.c 2007-08-02 12:03:21.000000000 -0400
33404@@ -84,6 +84,7 @@
33405 #include <linux/kmod.h>
33406 #include <linux/audit.h>
33407 #include <linux/wireless.h>
33408+#include <linux/in.h>
33409
33410 #include <asm/uaccess.h>
33411 #include <asm/unistd.h>
33412@@ -93,6 +94,21 @@
33413 #include <linux/vs_inet.h>
33414 #include <linux/vs_inet6.h>
33415
33416+extern void gr_attach_curr_ip(const struct sock *sk);
33417+extern int gr_handle_sock_all(const int family, const int type,
33418+ const int protocol);
33419+extern int gr_handle_sock_server(const struct sockaddr *sck);
33420+extern int gr_handle_sock_server_other(const struct socket *sck);
33421+extern int gr_handle_sock_client(const struct sockaddr *sck);
33422+extern int gr_search_connect(const struct socket * sock,
33423+ const struct sockaddr_in * addr);
33424+extern int gr_search_bind(const struct socket * sock,
33425+ const struct sockaddr_in * addr);
33426+extern int gr_search_listen(const struct socket * sock);
33427+extern int gr_search_accept(const struct socket * sock);
33428+extern int gr_search_socket(const int domain, const int type,
33429+ const int protocol);
33430+
33431 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
33432 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
33433 unsigned long nr_segs, loff_t pos);
33434@@ -293,7 +309,7 @@ static int sockfs_get_sb(struct file_sys
33435 mnt);
33436 }
33437
33438-static struct vfsmount *sock_mnt __read_mostly;
33439+struct vfsmount *sock_mnt __read_mostly;
33440
33441 static struct file_system_type sock_fs_type = {
33442 .name = "sockfs",
33443@@ -1203,6 +1219,16 @@ asmlinkage long sys_socket(int family, i
33444 int retval;
33445 struct socket *sock;
33446
33447+ if(!gr_search_socket(family, type, protocol)) {
33448+ retval = -EACCES;
33449+ goto out;
33450+ }
33451+
33452+ if (gr_handle_sock_all(family, type, protocol)) {
33453+ retval = -EACCES;
33454+ goto out;
33455+ }
33456+
33457 retval = sock_create(family, type, protocol, &sock);
33458 if (retval < 0)
33459 goto out;
33460@@ -1330,6 +1356,12 @@ asmlinkage long sys_bind(int fd, struct
33461 if (sock) {
33462 err = move_addr_to_kernel(umyaddr, addrlen, address);
33463 if (err >= 0) {
33464+ if (!gr_search_bind(sock, (struct sockaddr_in *)address) ||
33465+ gr_handle_sock_server((struct sockaddr *)address)) {
33466+ err = -EACCES;
33467+ goto error;
33468+ }
33469+
33470 err = security_socket_bind(sock,
33471 (struct sockaddr *)address,
33472 addrlen);
33473@@ -1338,6 +1370,7 @@ asmlinkage long sys_bind(int fd, struct
33474 (struct sockaddr *)
33475 address, addrlen);
33476 }
33477+error:
33478 fput_light(sock->file, fput_needed);
33479 }
33480 return err;
33481@@ -1361,10 +1394,17 @@ asmlinkage long sys_listen(int fd, int b
33482 if ((unsigned)backlog > sysctl_somaxconn)
33483 backlog = sysctl_somaxconn;
33484
33485+ if (gr_handle_sock_server_other(sock) ||
33486+ !gr_search_listen(sock)) {
33487+ err = -EPERM;
33488+ goto error;
33489+ }
33490+
33491 err = security_socket_listen(sock, backlog);
33492 if (!err)
33493 err = sock->ops->listen(sock, backlog);
33494
33495+error:
33496 fput_light(sock->file, fput_needed);
33497 }
33498 return err;
33499@@ -1401,6 +1441,13 @@ asmlinkage long sys_accept(int fd, struc
33500 newsock->type = sock->type;
33501 newsock->ops = sock->ops;
33502
33503+ if (gr_handle_sock_server_other(sock) ||
33504+ !gr_search_accept(sock)) {
33505+ err = -EPERM;
33506+ sock_release(newsock);
33507+ goto out_put;
33508+ }
33509+
33510 /*
33511 * We don't need try_module_get here, as the listening socket (sock)
33512 * has the protocol module (sock->ops->owner) held.
33513@@ -1444,6 +1491,7 @@ asmlinkage long sys_accept(int fd, struc
33514 err = newfd;
33515
33516 security_socket_post_accept(sock, newsock);
33517+ gr_attach_curr_ip(newsock->sk);
33518
33519 out_put:
33520 fput_light(sock->file, fput_needed);
33521@@ -1477,6 +1525,7 @@ asmlinkage long sys_connect(int fd, stru
33522 {
33523 struct socket *sock;
33524 char address[MAX_SOCK_ADDR];
33525+ struct sockaddr *sck;
33526 int err, fput_needed;
33527
33528 sock = sockfd_lookup_light(fd, &err, &fput_needed);
33529@@ -1486,6 +1535,13 @@ asmlinkage long sys_connect(int fd, stru
33530 if (err < 0)
33531 goto out_put;
33532
33533+ sck = (struct sockaddr *)address;
33534+ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
33535+ gr_handle_sock_client(sck)) {
33536+ err = -EACCES;
33537+ goto out_put;
33538+ }
33539+
33540 err =
33541 security_socket_connect(sock, (struct sockaddr *)address, addrlen);
33542 if (err)
33543@@ -1763,6 +1819,7 @@ asmlinkage long sys_shutdown(int fd, int
33544 err = sock->ops->shutdown(sock, how);
33545 fput_light(sock->file, fput_needed);
33546 }
33547+
33548 return err;
33549 }
33550
33551diff -urNp linux-2.6.22.1/net/unix/af_unix.c linux-2.6.22.1/net/unix/af_unix.c
33552--- linux-2.6.22.1/net/unix/af_unix.c 2007-07-10 14:56:30.000000000 -0400
33553+++ linux-2.6.22.1/net/unix/af_unix.c 2007-08-02 11:09:17.000000000 -0400
33554@@ -115,6 +115,7 @@
33555 #include <linux/security.h>
33556 #include <linux/vs_context.h>
33557 #include <linux/vs_limit.h>
33558+#include <linux/grsecurity.h>
33559
33560 int sysctl_unix_max_dgram_qlen __read_mostly = 10;
33561
33562@@ -706,6 +707,11 @@ static struct sock *unix_find_other(stru
33563 if (err)
33564 goto put_fail;
33565
33566+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
33567+ err = -EACCES;
33568+ goto put_fail;
33569+ }
33570+
33571 err = -ECONNREFUSED;
33572 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
33573 goto put_fail;
33574@@ -729,6 +735,13 @@ static struct sock *unix_find_other(stru
33575 if (u) {
33576 struct dentry *dentry;
33577 dentry = unix_sk(u)->dentry;
33578+
33579+ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
33580+ err = -EPERM;
33581+ sock_put(u);
33582+ goto fail;
33583+ }
33584+
33585 if (dentry)
33586 touch_atime(unix_sk(u)->mnt, dentry);
33587 } else
33588@@ -807,9 +820,18 @@ static int unix_bind(struct socket *sock
33589 */
33590 mode = S_IFSOCK |
33591 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
33592+
33593+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
33594+ err = -EACCES;
33595+ goto out_mknod_dput;
33596+ }
33597+
33598 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
33599 if (err)
33600 goto out_mknod_dput;
33601+
33602+ gr_handle_create(dentry, nd.mnt);
33603+
33604 mutex_unlock(&nd.dentry->d_inode->i_mutex);
33605 dput(nd.dentry);
33606 nd.dentry = dentry;
33607@@ -827,6 +849,10 @@ static int unix_bind(struct socket *sock
33608 goto out_unlock;
33609 }
33610
33611+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
33612+ sk->sk_peercred.pid = current->pid;
33613+#endif
33614+
33615 list = &unix_socket_table[addr->hash];
33616 } else {
33617 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
33618diff -urNp linux-2.6.22.1/scripts/pnmtologo.c linux-2.6.22.1/scripts/pnmtologo.c
33619--- linux-2.6.22.1/scripts/pnmtologo.c 2007-07-10 14:56:30.000000000 -0400
33620+++ linux-2.6.22.1/scripts/pnmtologo.c 2007-08-02 11:38:48.000000000 -0400
33621@@ -237,14 +237,14 @@ static void write_header(void)
33622 fprintf(out, " * Linux logo %s\n", logoname);
33623 fputs(" */\n\n", out);
33624 fputs("#include <linux/linux_logo.h>\n\n", out);
33625- fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
33626+ fprintf(out, "static unsigned char %s_data[] = {\n",
33627 logoname);
33628 }
33629
33630 static void write_footer(void)
33631 {
33632 fputs("\n};\n\n", out);
33633- fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
33634+ fprintf(out, "struct linux_logo %s = {\n", logoname);
33635 fprintf(out, " .type\t= %s,\n", logo_types[logo_type]);
33636 fprintf(out, " .width\t= %d,\n", logo_width);
33637 fprintf(out, " .height\t= %d,\n", logo_height);
33638@@ -374,7 +374,7 @@ static void write_logo_clut224(void)
33639 fputs("\n};\n\n", out);
33640
33641 /* write logo clut */
33642- fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
33643+ fprintf(out, "static unsigned char %s_clut[] = {\n",
33644 logoname);
33645 write_hex_cnt = 0;
33646 for (i = 0; i < logo_clutsize; i++) {
33647diff -urNp linux-2.6.22.1/security/commoncap.c linux-2.6.22.1/security/commoncap.c
33648--- linux-2.6.22.1/security/commoncap.c 2007-07-10 14:56:30.000000000 -0400
33649+++ linux-2.6.22.1/security/commoncap.c 2007-08-02 11:09:17.000000000 -0400
33650@@ -22,10 +22,11 @@
33651 #include <linux/xattr.h>
33652 #include <linux/hugetlb.h>
33653 #include <linux/vs_context.h>
33654+#include <linux/grsecurity.h>
33655
33656 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
33657 {
33658- cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
33659+ cap_t(NETLINK_CB(skb).eff_cap) = gr_cap_rtnetlink();
33660 return 0;
33661 }
33662
33663@@ -43,7 +44,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
33664 int cap_capable (struct task_struct *tsk, int cap)
33665 {
33666 /* Derived from include/linux/sched.h:capable. */
33667- if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
33668+ if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
33669+ return 0;
33670+ return -EPERM;
33671+}
33672+
33673+int cap_capable_nolog (struct task_struct *tsk, int cap)
33674+{
33675+ /* tsk = current for all callers */
33676+ if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
33677 return 0;
33678 return -EPERM;
33679 }
33680@@ -164,8 +173,11 @@ void cap_bprm_apply_creds (struct linux_
33681 }
33682 }
33683
33684- current->suid = current->euid = current->fsuid = bprm->e_uid;
33685- current->sgid = current->egid = current->fsgid = bprm->e_gid;
33686+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
33687+ current->suid = current->euid = current->fsuid = bprm->e_uid;
33688+
33689+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
33690+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
33691
33692 /* For init, we want to retain the capabilities set
33693 * in the init_task struct. Thus we skip the usual
33694@@ -176,6 +188,8 @@ void cap_bprm_apply_creds (struct linux_
33695 cap_intersect (new_permitted, bprm->cap_effective);
33696 }
33697
33698+ gr_handle_chroot_caps(current);
33699+
33700 /* AUD: Audit candidate if current->cap_effective is set */
33701
33702 current->keep_capabilities = 0;
33703@@ -322,12 +336,13 @@ int cap_vm_enough_memory(long pages)
33704 {
33705 int cap_sys_admin = 0;
33706
33707- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
33708+ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
33709 cap_sys_admin = 1;
33710 return __vm_enough_memory(pages, cap_sys_admin);
33711 }
33712
33713 EXPORT_SYMBOL(cap_capable);
33714+EXPORT_SYMBOL(cap_capable_nolog);
33715 EXPORT_SYMBOL(cap_settime);
33716 EXPORT_SYMBOL(cap_ptrace);
33717 EXPORT_SYMBOL(cap_capget);
33718diff -urNp linux-2.6.22.1/security/dummy.c linux-2.6.22.1/security/dummy.c
33719--- linux-2.6.22.1/security/dummy.c 2007-07-10 14:56:30.000000000 -0400
33720+++ linux-2.6.22.1/security/dummy.c 2007-08-02 11:09:17.000000000 -0400
33721@@ -28,6 +28,7 @@
33722 #include <linux/ptrace.h>
33723 #include <linux/file.h>
33724 #include <linux/vs_context.h>
33725+#include <linux/grsecurity.h>
33726
33727 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
33728 {
33729@@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
33730 }
33731 }
33732
33733- current->suid = current->euid = current->fsuid = bprm->e_uid;
33734- current->sgid = current->egid = current->fsgid = bprm->e_gid;
33735+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
33736+ current->suid = current->euid = current->fsuid = bprm->e_uid;
33737+
33738+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
33739+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
33740
33741 dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
33742 }
33743diff -urNp linux-2.6.22.1/security/Kconfig linux-2.6.22.1/security/Kconfig
33744--- linux-2.6.22.1/security/Kconfig 2007-07-10 14:56:30.000000000 -0400
33745+++ linux-2.6.22.1/security/Kconfig 2007-08-03 12:37:41.000000000 -0400
33746@@ -4,6 +4,429 @@
33747
33748 menu "Security options"
33749
33750+source grsecurity/Kconfig
33751+
33752+menu "PaX"
33753+
33754+config PAX
33755+ bool "Enable various PaX features"
33756+ depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
33757+ help
33758+ This allows you to enable various PaX features. PaX adds
33759+ intrusion prevention mechanisms to the kernel that reduce
33760+ the risks posed by exploitable memory corruption bugs.
33761+
33762+menu "PaX Control"
33763+ depends on PAX
33764+
33765+config PAX_SOFTMODE
33766+ bool 'Support soft mode'
33767+ help
33768+ Enabling this option will allow you to run PaX in soft mode, that
33769+ is, PaX features will not be enforced by default, only on executables
33770+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
33771+ is the only way to mark executables for soft mode use.
33772+
33773+ Soft mode can be activated by using the "pax_softmode=1" kernel command
33774+ line option on boot. Furthermore you can control various PaX features
33775+ at runtime via the entries in /proc/sys/kernel/pax.
33776+
33777+config PAX_EI_PAX
33778+ bool 'Use legacy ELF header marking'
33779+ help
33780+ Enabling this option will allow you to control PaX features on
33781+ a per executable basis via the 'chpax' utility available at
33782+ http://pax.grsecurity.net/. The control flags will be read from
33783+ an otherwise reserved part of the ELF header. This marking has
33784+ numerous drawbacks (no support for soft-mode, toolchain does not
33785+ know about the non-standard use of the ELF header) therefore it
33786+ has been deprecated in favour of PT_PAX_FLAGS support.
33787+
33788+ If you have applications not marked by the PT_PAX_FLAGS ELF
33789+ program header then you MUST enable this option otherwise they
33790+ will not get any protection.
33791+
33792+ Note that if you enable PT_PAX_FLAGS marking support as well,
33793+ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
33794+
33795+config PAX_PT_PAX_FLAGS
33796+ bool 'Use ELF program header marking'
33797+ help
33798+ Enabling this option will allow you to control PaX features on
33799+ a per executable basis via the 'paxctl' utility available at
33800+ http://pax.grsecurity.net/. The control flags will be read from
33801+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
33802+ has the benefits of supporting both soft mode and being fully
33803+ integrated into the toolchain (the binutils patch is available
33804+ from http://pax.grsecurity.net).
33805+
33806+ If you have applications not marked by the PT_PAX_FLAGS ELF
33807+ program header then you MUST enable the EI_PAX marking support
33808+ otherwise they will not get any protection.
33809+
33810+ Note that if you enable the legacy EI_PAX marking support as well,
33811+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
33812+
33813+choice
33814+ prompt 'MAC system integration'
33815+ default PAX_HAVE_ACL_FLAGS
33816+ help
33817+ Mandatory Access Control systems have the option of controlling
33818+ PaX flags on a per executable basis, choose the method supported
33819+ by your particular system.
33820+
33821+ - "none": if your MAC system does not interact with PaX,
33822+ - "direct": if your MAC system defines pax_set_initial_flags() itself,
33823+ - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
33824+
33825+ NOTE: this option is for developers/integrators only.
33826+
33827+config PAX_NO_ACL_FLAGS
33828+ bool 'none'
33829+
33830+config PAX_HAVE_ACL_FLAGS
33831+ bool 'direct'
33832+
33833+config PAX_HOOK_ACL_FLAGS
33834+ bool 'hook'
33835+endchoice
33836+
33837+endmenu
33838+
33839+menu "Non-executable pages"
33840+ depends on PAX
33841+
33842+config PAX_NOEXEC
33843+ bool "Enforce non-executable pages"
33844+ 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)
33845+ help
33846+ By design some architectures do not allow for protecting memory
33847+ pages against execution or even if they do, Linux does not make
33848+ use of this feature. In practice this means that if a page is
33849+ readable (such as the stack or heap) it is also executable.
33850+
33851+ There is a well known exploit technique that makes use of this
33852+ fact and a common programming mistake where an attacker can
33853+ introduce code of his choice somewhere in the attacked program's
33854+ memory (typically the stack or the heap) and then execute it.
33855+
33856+ If the attacked program was running with different (typically
33857+ higher) privileges than that of the attacker, then he can elevate
33858+ his own privilege level (e.g. get a root shell, write to files for
33859+ which he does not have write access to, etc).
33860+
33861+ Enabling this option will let you choose from various features
33862+ that prevent the injection and execution of 'foreign' code in
33863+ a program.
33864+
33865+ This will also break programs that rely on the old behaviour and
33866+ expect that dynamically allocated memory via the malloc() family
33867+ of functions is executable (which it is not). Notable examples
33868+ are the XFree86 4.x server, the java runtime and wine.
33869+
33870+config PAX_PAGEEXEC
33871+ bool "Paging based non-executable pages"
33872+ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
33873+ help
33874+ This implementation is based on the paging feature of the CPU.
33875+ On i386 without hardware non-executable bit support there is a
33876+ variable but usually low performance impact, however on Intel's
33877+ P4 core based CPUs it is very high so you should not enable this
33878+ for kernels meant to be used on such CPUs.
33879+
33880+ On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
33881+ with hardware non-executable bit support there is no performance
33882+ impact, on ppc the impact is negligible.
33883+
33884+ Note that several architectures require various emulations due to
33885+ badly designed userland ABIs, this will cause a performance impact
33886+ but will disappear as soon as userland is fixed (e.g., ppc users
33887+ can make use of the secure-plt feature found in binutils).
33888+
33889+config PAX_SEGMEXEC
33890+ bool "Segmentation based non-executable pages"
33891+ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
33892+ help
33893+ This implementation is based on the segmentation feature of the
33894+ CPU and has a very small performance impact, however applications
33895+ will be limited to a 1.5 GB address space instead of the normal
33896+ 3 GB.
33897+
33898+config PAX_EMUTRAMP
33899+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
33900+ default y if PARISC || PPC32
33901+ help
33902+ There are some programs and libraries that for one reason or
33903+ another attempt to execute special small code snippets from
33904+ non-executable memory pages. Most notable examples are the
33905+ signal handler return code generated by the kernel itself and
33906+ the GCC trampolines.
33907+
33908+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
33909+ such programs will no longer work under your kernel.
33910+
33911+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
33912+ utilities to enable trampoline emulation for the affected programs
33913+ yet still have the protection provided by the non-executable pages.
33914+
33915+ On parisc and ppc you MUST enable this option and EMUSIGRT as
33916+ well, otherwise your system will not even boot.
33917+
33918+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
33919+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
33920+ for the affected files.
33921+
33922+ NOTE: enabling this feature *may* open up a loophole in the
33923+ protection provided by non-executable pages that an attacker
33924+ could abuse. Therefore the best solution is to not have any
33925+ files on your system that would require this option. This can
33926+ be achieved by not using libc5 (which relies on the kernel
33927+ signal handler return code) and not using or rewriting programs
33928+ that make use of the nested function implementation of GCC.
33929+ Skilled users can just fix GCC itself so that it implements
33930+ nested function calls in a way that does not interfere with PaX.
33931+
33932+config PAX_EMUSIGRT
33933+ bool "Automatically emulate sigreturn trampolines"
33934+ depends on PAX_EMUTRAMP && (PARISC || PPC32)
33935+ default y
33936+ help
33937+ Enabling this option will have the kernel automatically detect
33938+ and emulate signal return trampolines executing on the stack
33939+ that would otherwise lead to task termination.
33940+
33941+ This solution is intended as a temporary one for users with
33942+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
33943+ Modula-3 runtime, etc) or executables linked to such, basically
33944+ everything that does not specify its own SA_RESTORER function in
33945+ normal executable memory like glibc 2.1+ does.
33946+
33947+ On parisc and ppc you MUST enable this option, otherwise your
33948+ system will not even boot.
33949+
33950+ NOTE: this feature cannot be disabled on a per executable basis
33951+ and since it *does* open up a loophole in the protection provided
33952+ by non-executable pages, the best solution is to not have any
33953+ files on your system that would require this option.
33954+
33955+config PAX_MPROTECT
33956+ bool "Restrict mprotect()"
33957+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
33958+ help
33959+ Enabling this option will prevent programs from
33960+ - changing the executable status of memory pages that were
33961+ not originally created as executable,
33962+ - making read-only executable pages writable again,
33963+ - creating executable pages from anonymous memory.
33964+
33965+ You should say Y here to complete the protection provided by
33966+ the enforcement of non-executable pages.
33967+
33968+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
33969+ this feature on a per file basis.
33970+
33971+config PAX_NOELFRELOCS
33972+ bool "Disallow ELF text relocations"
33973+ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
33974+ help
33975+ Non-executable pages and mprotect() restrictions are effective
33976+ in preventing the introduction of new executable code into an
33977+ attacked task's address space. There remain only two venues
33978+ for this kind of attack: if the attacker can execute already
33979+ existing code in the attacked task then he can either have it
33980+ create and mmap() a file containing his code or have it mmap()
33981+ an already existing ELF library that does not have position
33982+ independent code in it and use mprotect() on it to make it
33983+ writable and copy his code there. While protecting against
33984+ the former approach is beyond PaX, the latter can be prevented
33985+ by having only PIC ELF libraries on one's system (which do not
33986+ need to relocate their code). If you are sure this is your case,
33987+ then enable this option otherwise be careful as you may not even
33988+ be able to boot or log on your system (for example, some PAM
33989+ modules are erroneously compiled as non-PIC by default).
33990+
33991+ NOTE: if you are using dynamic ELF executables (as suggested
33992+ when using ASLR) then you must have made sure that you linked
33993+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
33994+ referenced there has already been updated to support this).
33995+
33996+config PAX_ETEXECRELOCS
33997+ bool "Allow ELF ET_EXEC text relocations"
33998+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
33999+ default y
34000+ help
34001+ On some architectures there are incorrectly created applications
34002+ that require text relocations and would not work without enabling
34003+ this option. If you are an alpha, ia64 or parisc user, you should
34004+ enable this option and disable it once you have made sure that
34005+ none of your applications need it.
34006+
34007+config PAX_EMUPLT
34008+ bool "Automatically emulate ELF PLT"
34009+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
34010+ default y
34011+ help
34012+ Enabling this option will have the kernel automatically detect
34013+ and emulate the Procedure Linkage Table entries in ELF files.
34014+ On some architectures such entries are in writable memory, and
34015+ become non-executable leading to task termination. Therefore
34016+ it is mandatory that you enable this option on alpha, parisc,
34017+ ppc (if secure-plt is not used throughout in userland), sparc
34018+ and sparc64, otherwise your system would not even boot.
34019+
34020+ NOTE: this feature *does* open up a loophole in the protection
34021+ provided by the non-executable pages, therefore the proper
34022+ solution is to modify the toolchain to produce a PLT that does
34023+ not need to be writable.
34024+
34025+config PAX_DLRESOLVE
34026+ bool
34027+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
34028+ default y
34029+
34030+config PAX_SYSCALL
34031+ bool
34032+ depends on PAX_PAGEEXEC && PPC32
34033+ default y
34034+
34035+config PAX_KERNEXEC
34036+ bool "Enforce non-executable kernel pages"
34037+ depends on PAX_NOEXEC && X86_32 && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK && !PARAVIRT
34038+ help
34039+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
34040+ that is, enabling this option will make it harder to inject
34041+ and execute 'foreign' code in kernel memory itself.
34042+
34043+endmenu
34044+
34045+menu "Address Space Layout Randomization"
34046+ depends on PAX
34047+
34048+config PAX_ASLR
34049+ bool "Address Space Layout Randomization"
34050+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
34051+ help
34052+ Many if not most exploit techniques rely on the knowledge of
34053+ certain addresses in the attacked program. The following options
34054+ will allow the kernel to apply a certain amount of randomization
34055+ to specific parts of the program thereby forcing an attacker to
34056+ guess them in most cases. Any failed guess will most likely crash
34057+ the attacked program which allows the kernel to detect such attempts
34058+ and react on them. PaX itself provides no reaction mechanisms,
34059+ instead it is strongly encouraged that you make use of Nergal's
34060+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
34061+ (http://www.grsecurity.net/) built-in crash detection features or
34062+ develop one yourself.
34063+
34064+ By saying Y here you can choose to randomize the following areas:
34065+ - top of the task's kernel stack
34066+ - top of the task's userland stack
34067+ - base address for mmap() requests that do not specify one
34068+ (this includes all libraries)
34069+ - base address of the main executable
34070+
34071+ It is strongly recommended to say Y here as address space layout
34072+ randomization has negligible impact on performance yet it provides
34073+ a very effective protection.
34074+
34075+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
34076+ this feature on a per file basis.
34077+
34078+config PAX_RANDKSTACK
34079+ bool "Randomize kernel stack base"
34080+ depends on PAX_ASLR && X86_TSC && X86_32
34081+ help
34082+ By saying Y here the kernel will randomize every task's kernel
34083+ stack on every system call. This will not only force an attacker
34084+ to guess it but also prevent him from making use of possible
34085+ leaked information about it.
34086+
34087+ Since the kernel stack is a rather scarce resource, randomization
34088+ may cause unexpected stack overflows, therefore you should very
34089+ carefully test your system. Note that once enabled in the kernel
34090+ configuration, this feature cannot be disabled on a per file basis.
34091+
34092+config PAX_RANDUSTACK
34093+ bool "Randomize user stack base"
34094+ depends on PAX_ASLR
34095+ help
34096+ By saying Y here the kernel will randomize every task's userland
34097+ stack. The randomization is done in two steps where the second
34098+ one may apply a big amount of shift to the top of the stack and
34099+ cause problems for programs that want to use lots of memory (more
34100+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
34101+ For this reason the second step can be controlled by 'chpax' or
34102+ 'paxctl' on a per file basis.
34103+
34104+config PAX_RANDMMAP
34105+ bool "Randomize mmap() base"
34106+ depends on PAX_ASLR
34107+ help
34108+ By saying Y here the kernel will use a randomized base address for
34109+ mmap() requests that do not specify one themselves. As a result
34110+ all dynamically loaded libraries will appear at random addresses
34111+ and therefore be harder to exploit by a technique where an attacker
34112+ attempts to execute library code for his purposes (e.g. spawn a
34113+ shell from an exploited program that is running at an elevated
34114+ privilege level).
34115+
34116+ Furthermore, if a program is relinked as a dynamic ELF file, its
34117+ base address will be randomized as well, completing the full
34118+ randomization of the address space layout. Attacking such programs
34119+ becomes a guess game. You can find an example of doing this at
34120+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
34121+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
34122+
34123+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
34124+ feature on a per file basis.
34125+
34126+endmenu
34127+
34128+menu "Miscellaneous hardening features"
34129+
34130+config PAX_MEMORY_SANITIZE
34131+ bool "Sanitize all freed memory"
34132+ help
34133+ By saying Y here the kernel will erase memory pages as soon as they
34134+ are freed. This in turn reduces the lifetime of data stored in the
34135+ pages, making it less likely that sensitive information such as
34136+ passwords, cryptographic secrets, etc stay in memory for too long.
34137+
34138+ This is especially useful for programs whose runtime is short, long
34139+ lived processes and the kernel itself benefit from this as long as
34140+ they operate on whole memory pages and ensure timely freeing of pages
34141+ that may hold sensitive information.
34142+
34143+ The tradeoff is performance impact, on a single CPU system kernel
34144+ compilation sees a 3% slowdown, other systems and workloads may vary
34145+ and you are advised to test this feature on your expected workload
34146+ before deploying it.
34147+
34148+ Note that this feature does not protect data stored in live pages,
34149+ e.g., process memory swapped to disk may stay there for a long time.
34150+
34151+config PAX_MEMORY_UDEREF
34152+ bool "Prevent invalid userland pointer dereference"
34153+ depends on X86_32 && !COMPAT_VDSO
34154+ help
34155+ By saying Y here the kernel will be prevented from dereferencing
34156+ userland pointers in contexts where the kernel expects only kernel
34157+ pointers. This is both a useful runtime debugging feature and a
34158+ security measure that prevents exploiting a class of kernel bugs.
34159+
34160+ The tradeoff is that some virtualization solutions may experience
34161+ a huge slowdown and therefore you should not enable this feature
34162+ for kernels meant to run in such environments. Whether a given VM
34163+ solution is affected or not is best determined by simply trying it
34164+ out, the performance impact will be obvious right on boot as this
34165+ mechanism engages from very early on. A good rule of thumb is that
34166+ VMs running on CPUs without hardware virtualization support (i.e.,
34167+ the majority of IA-32 CPUs) will likely experience the slowdown.
34168+
34169+endmenu
34170+
34171+endmenu
34172+
34173 config KEYS
34174 bool "Enable access key retention support"
34175 depends on !VSERVER_SECURITY
34176diff -urNp linux-2.6.22.1/sound/core/oss/pcm_oss.c linux-2.6.22.1/sound/core/oss/pcm_oss.c
34177--- linux-2.6.22.1/sound/core/oss/pcm_oss.c 2007-07-10 14:56:30.000000000 -0400
34178+++ linux-2.6.22.1/sound/core/oss/pcm_oss.c 2007-08-02 11:38:48.000000000 -0400
34179@@ -2880,8 +2880,8 @@ static void snd_pcm_oss_proc_done(struct
34180 }
34181 }
34182 #else /* !CONFIG_SND_VERBOSE_PROCFS */
34183-#define snd_pcm_oss_proc_init(pcm)
34184-#define snd_pcm_oss_proc_done(pcm)
34185+#define snd_pcm_oss_proc_init(pcm) do {} while (0)
34186+#define snd_pcm_oss_proc_done(pcm) do {} while (0)
34187 #endif /* CONFIG_SND_VERBOSE_PROCFS */
34188
34189 /*
34190diff -urNp linux-2.6.22.1/sound/core/seq/seq_lock.h linux-2.6.22.1/sound/core/seq/seq_lock.h
34191--- linux-2.6.22.1/sound/core/seq/seq_lock.h 2007-07-10 14:56:30.000000000 -0400
34192+++ linux-2.6.22.1/sound/core/seq/seq_lock.h 2007-08-02 11:38:48.000000000 -0400
34193@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
34194 #else /* SMP || CONFIG_SND_DEBUG */
34195
34196 typedef spinlock_t snd_use_lock_t; /* dummy */
34197-#define snd_use_lock_init(lockp) /**/
34198-#define snd_use_lock_use(lockp) /**/
34199-#define snd_use_lock_free(lockp) /**/
34200-#define snd_use_lock_sync(lockp) /**/
34201+#define snd_use_lock_init(lockp) do {} while (0)
34202+#define snd_use_lock_use(lockp) do {} while (0)
34203+#define snd_use_lock_free(lockp) do {} while (0)
34204+#define snd_use_lock_sync(lockp) do {} while (0)
34205
34206 #endif /* SMP || CONFIG_SND_DEBUG */
34207
34208diff -urNp linux-2.6.22.1/sound/pci/ac97/ac97_patch.c linux-2.6.22.1/sound/pci/ac97/ac97_patch.c
34209--- linux-2.6.22.1/sound/pci/ac97/ac97_patch.c 2007-07-10 14:56:30.000000000 -0400
34210+++ linux-2.6.22.1/sound/pci/ac97/ac97_patch.c 2007-08-02 11:38:48.000000000 -0400
34211@@ -1415,7 +1415,7 @@ static const struct snd_ac97_res_table a
34212 { AC97_VIDEO, 0x9f1f },
34213 { AC97_AUX, 0x9f1f },
34214 { AC97_PCM, 0x9f1f },
34215- { } /* terminator */
34216+ { 0, 0 } /* terminator */
34217 };
34218
34219 static int patch_ad1819(struct snd_ac97 * ac97)
34220@@ -3489,7 +3489,7 @@ static struct snd_ac97_res_table lm4550_
34221 { AC97_AUX, 0x1f1f },
34222 { AC97_PCM, 0x1f1f },
34223 { AC97_REC_GAIN, 0x0f0f },
34224- { } /* terminator */
34225+ { 0, 0 } /* terminator */
34226 };
34227
34228 static int patch_lm4550(struct snd_ac97 *ac97)
34229diff -urNp linux-2.6.22.1/sound/pci/ens1370.c linux-2.6.22.1/sound/pci/ens1370.c
34230--- linux-2.6.22.1/sound/pci/ens1370.c 2007-07-10 14:56:30.000000000 -0400
34231+++ linux-2.6.22.1/sound/pci/ens1370.c 2007-08-02 11:38:48.000000000 -0400
34232@@ -453,7 +453,7 @@ static struct pci_device_id snd_audiopci
34233 { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */
34234 { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */
34235 #endif
34236- { 0, }
34237+ { 0, 0, 0, 0, 0, 0, 0 }
34238 };
34239
34240 MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
34241diff -urNp linux-2.6.22.1/sound/pci/intel8x0.c linux-2.6.22.1/sound/pci/intel8x0.c
34242--- linux-2.6.22.1/sound/pci/intel8x0.c 2007-07-10 14:56:30.000000000 -0400
34243+++ linux-2.6.22.1/sound/pci/intel8x0.c 2007-08-02 11:38:48.000000000 -0400
34244@@ -436,7 +436,7 @@ static struct pci_device_id snd_intel8x0
34245 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
34246 { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
34247 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
34248- { 0, }
34249+ { 0, 0, 0, 0, 0, 0, 0 }
34250 };
34251
34252 MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
34253@@ -2044,7 +2044,7 @@ static struct ac97_quirk ac97_quirks[] _
34254 .type = AC97_TUNE_HP_ONLY
34255 },
34256 #endif
34257- { } /* terminator */
34258+ { 0, 0, 0, 0, NULL, 0 } /* terminator */
34259 };
34260
34261 static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
34262diff -urNp linux-2.6.22.1/sound/pci/intel8x0m.c linux-2.6.22.1/sound/pci/intel8x0m.c
34263--- linux-2.6.22.1/sound/pci/intel8x0m.c 2007-07-10 14:56:30.000000000 -0400
34264+++ linux-2.6.22.1/sound/pci/intel8x0m.c 2007-08-02 11:38:48.000000000 -0400
34265@@ -240,7 +240,7 @@ static struct pci_device_id snd_intel8x0
34266 { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
34267 { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */
34268 #endif
34269- { 0, }
34270+ { 0, 0, 0, 0, 0, 0, 0 }
34271 };
34272
34273 MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
34274@@ -1261,7 +1261,7 @@ static struct shortname_table {
34275 { 0x5455, "ALi M5455" },
34276 { 0x746d, "AMD AMD8111" },
34277 #endif
34278- { 0 },
34279+ { 0, NULL },
34280 };
34281
34282 static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
34283--- linux-2.6.22./fs/ext3/balloc.c 2007-08-09 00:16:48.425144000 +0200
34284+++ linux-2.6.22/fs/ext3/balloc.c 2007-08-09 20:38:20.862277750 +0200
34285@@ -1373,14 +1373,14 @@ static int ext3_has_free_blocks(struct s
34286 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
34287
34288 cond = (free_blocks < root_blocks + 1 &&
34289- !capable(CAP_SYS_RESOURCE) &&
34290+ !capable_nolog(CAP_SYS_RESOURCE) &&
34291 sbi->s_resuid != current->fsuid &&
34292 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
34293
34294 vxdprintk(VXD_CBIT(dlim, 3),
34295 "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
34296 sb, free_blocks, root_blocks,
34297- !capable(CAP_SYS_RESOURCE)?'1':'0',
34298+ !capable_nolog(CAP_SYS_RESOURCE)?'1':'0',
34299 sbi->s_resuid, current->fsuid, cond?0:1);
34300
34301 return (cond ? 0 : 1);
b5630f59 34302diff -urNp linux-2.6.22/fs/ext3/namei.c linux-2.6.22/fs/ext3/namei.c
34303--- linux-2.6.22/fs/ext3/namei.c 2007-09-00 00:00:00.000000000 -0400
34304+++ linux-2.6.22/fs/ext3/namei.c 2007-09-00 00:00:00.000000000 -0400
34305@@ -1178,9 +1178,9 @@ static struct ext3_dir_entry_2 *do_split
34306 u32 hash2;
34307 struct dx_map_entry *map;
34308 char *data1 = (*bh)->b_data, *data2;
34309- unsigned split, move, size, i;
34310+ unsigned split, move, size;
34311 struct ext3_dir_entry_2 *de = NULL, *de2;
34312- int err = 0;
34313+ int i, err = 0;
34314
34315 bh2 = ext3_append (handle, dir, &newblock, &err);
34316 if (!(bh2)) {
34317diff -urNp linux-2.6.22/fs/ext3/xattr.c linux-2.6.22/fs/ext3/xattr.c
34318--- linux-2.6.22/fs/ext3/xattr.c 2007-09-00 00:00:00.000000000 -0400
34319+++ linux-2.6.22/fs/ext3/xattr.c 2007-09-00 00:00:00.000000000 -0400
34320@@ -89,8 +89,8 @@
34321 printk("\n"); \
34322 } while (0)
34323 #else
34324-# define ea_idebug(f...)
34325-# define ea_bdebug(f...)
34326+# define ea_idebug(f...) do {} while (0)
34327+# define ea_bdebug(f...) do {} while (0)
34328 #endif
34329
34330 static void ext3_xattr_cache_insert(struct buffer_head *);
3ba9fddb 34331diff -urNp linux-2.6.22./fs/ext4/balloc.c linux-2.6.22/fs/ext4/balloc.c
34332--- linux-2.6.22./fs/ext4/balloc.c 2007-08-09 00:16:48.441145000 +0200
34333+++ linux-2.6.22/fs/ext4/balloc.c 2007-08-09 20:40:25.878090750 +0200
34334@@ -1390,14 +1390,14 @@ static int ext4_has_free_blocks(struct s
34335 DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
34336
34337 cond = (free_blocks < root_blocks + 1 &&
34338- !capable(CAP_SYS_RESOURCE) &&
34339+ !capable_nolog(CAP_SYS_RESOURCE) &&
34340 sbi->s_resuid != current->fsuid &&
34341 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
34342
34343 vxdprintk(VXD_CBIT(dlim, 3),
34344 "ext4_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
34345 sb, free_blocks, root_blocks,
34346- !capable(CAP_SYS_RESOURCE)?'1':'0',
34347+ !capable_nolog(CAP_SYS_RESOURCE)?'1':'0',
34348 sbi->s_resuid, current->fsuid, cond?0:1);
34349
34350 return (cond ? 0 : 1);
b5630f59 34351diff -urNp linux-2.6.22/fs/ext4/namei.c linux-2.6.22/fs/ext4/namei.c
34352--- linux-2.6.22/fs/ext4/namei.c 2007-09-00 00:00:00.000000000 -0400
34353+++ linux-2.6.22/fs/ext4/namei.c 2007-09-00 00:00:00.000000000 -0400
34354@@ -1176,9 +1176,9 @@ static struct ext4_dir_entry_2 *do_split
34355 u32 hash2;
34356 struct dx_map_entry *map;
34357 char *data1 = (*bh)->b_data, *data2;
34358- unsigned split, move, size, i;
34359+ unsigned split, move, size;
34360 struct ext4_dir_entry_2 *de = NULL, *de2;
34361- int err = 0;
34362+ int i, err = 0;
34363
34364 bh2 = ext4_append (handle, dir, &newblock, &err);
34365 if (!(bh2)) {
This page took 4.210287 seconds and 4 git commands to generate.