]> git.pld-linux.org Git - packages/kernel.git/blame - grsecurity-2.1.9-2.6.19.1.patch
- updated for 2.6.25.4
[packages/kernel.git] / grsecurity-2.1.9-2.6.19.1.patch
CommitLineData
c3e8c1b5 1diff -urNp linux-2.6.19.1/arch/alpha/kernel/module.c linux-2.6.19.1/arch/alpha/kernel/module.c
2--- linux-2.6.19.1/arch/alpha/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
3+++ linux-2.6.19.1/arch/alpha/kernel/module.c 2006-12-03 15:15:43.000000000 -0500
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.19.1/arch/alpha/kernel/osf_sys.c linux-2.6.19.1/arch/alpha/kernel/osf_sys.c
14--- linux-2.6.19.1/arch/alpha/kernel/osf_sys.c 2006-11-29 16:57:37.000000000 -0500
15+++ linux-2.6.19.1/arch/alpha/kernel/osf_sys.c 2006-12-03 15:15:43.000000000 -0500
16@@ -1277,6 +1277,10 @@ arch_get_unmapped_area(struct file *filp
17 merely specific addresses, but regions of memory -- perhaps
18 this feature should be incorporated into all ports? */
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@@ -1284,8 +1288,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.19.1/arch/alpha/kernel/ptrace.c linux-2.6.19.1/arch/alpha/kernel/ptrace.c
39--- linux-2.6.19.1/arch/alpha/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
40+++ linux-2.6.19.1/arch/alpha/kernel/ptrace.c 2006-12-03 15:15:43.000000000 -0500
41@@ -15,6 +15,7 @@
c3e8c1b5 42 #include <linux/security.h>
43 #include <linux/signal.h>
b6fa5d20 44 #include <linux/vs_base.h>
c3e8c1b5 45+#include <linux/grsecurity.h>
46
47 #include <asm/uaccess.h>
48 #include <asm/pgtable.h>
49@@ -283,6 +284,9 @@ do_sys_ptrace(long request, long pid, lo
50 goto out_notsk;
51 }
52
53+ if (gr_handle_ptrace(child, request))
54+ goto out;
55+
56 if (request == PTRACE_ATTACH) {
57 ret = ptrace_attach(child);
58 goto out;
59diff -urNp linux-2.6.19.1/arch/alpha/mm/fault.c linux-2.6.19.1/arch/alpha/mm/fault.c
60--- linux-2.6.19.1/arch/alpha/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
61+++ linux-2.6.19.1/arch/alpha/mm/fault.c 2006-12-03 15:15:43.000000000 -0500
62@@ -24,6 +24,7 @@
63 #include <linux/smp_lock.h>
64 #include <linux/interrupt.h>
65 #include <linux/module.h>
66+#include <linux/binfmts.h>
67
68 #include <asm/system.h>
69 #include <asm/uaccess.h>
70@@ -55,6 +56,124 @@ __load_new_mm_context(struct mm_struct *
71 __reload_thread(pcb);
72 }
73
74+#ifdef CONFIG_PAX_PAGEEXEC
75+/*
76+ * PaX: decide what to do with offenders (regs->pc = fault address)
77+ *
78+ * returns 1 when task should be killed
79+ * 2 when patched PLT trampoline was detected
80+ * 3 when unpatched PLT trampoline was detected
81+ */
82+static int pax_handle_fetch_fault(struct pt_regs *regs)
83+{
84+
85+#ifdef CONFIG_PAX_EMUPLT
86+ int err;
87+
88+ do { /* PaX: patched PLT emulation #1 */
89+ unsigned int ldah, ldq, jmp;
90+
91+ err = get_user(ldah, (unsigned int *)regs->pc);
92+ err |= get_user(ldq, (unsigned int *)(regs->pc+4));
93+ err |= get_user(jmp, (unsigned int *)(regs->pc+8));
94+
95+ if (err)
96+ break;
97+
98+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
99+ (ldq & 0xFFFF0000U) == 0xA77B0000U &&
100+ jmp == 0x6BFB0000U)
101+ {
102+ unsigned long r27, addr;
103+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
104+ unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
105+
106+ addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
107+ err = get_user(r27, (unsigned long*)addr);
108+ if (err)
109+ break;
110+
111+ regs->r27 = r27;
112+ regs->pc = r27;
113+ return 2;
114+ }
115+ } while (0);
116+
117+ do { /* PaX: patched PLT emulation #2 */
118+ unsigned int ldah, lda, br;
119+
120+ err = get_user(ldah, (unsigned int *)regs->pc);
121+ err |= get_user(lda, (unsigned int *)(regs->pc+4));
122+ err |= get_user(br, (unsigned int *)(regs->pc+8));
123+
124+ if (err)
125+ break;
126+
127+ if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
128+ (lda & 0xFFFF0000U) == 0xA77B0000U &&
129+ (br & 0xFFE00000U) == 0xC3E00000U)
130+ {
131+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
132+ unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
133+ unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
134+
135+ regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
136+ regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
137+ return 2;
138+ }
139+ } while (0);
140+
141+ do { /* PaX: unpatched PLT emulation */
142+ unsigned int br;
143+
144+ err = get_user(br, (unsigned int *)regs->pc);
145+
146+ if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
147+ unsigned int br2, ldq, nop, jmp;
148+ unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
149+
150+ addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
151+ err = get_user(br2, (unsigned int *)addr);
152+ err |= get_user(ldq, (unsigned int *)(addr+4));
153+ err |= get_user(nop, (unsigned int *)(addr+8));
154+ err |= get_user(jmp, (unsigned int *)(addr+12));
155+ err |= get_user(resolver, (unsigned long *)(addr+16));
156+
157+ if (err)
158+ break;
159+
160+ if (br2 == 0xC3600000U &&
161+ ldq == 0xA77B000CU &&
162+ nop == 0x47FF041FU &&
163+ jmp == 0x6B7B0000U)
164+ {
165+ regs->r28 = regs->pc+4;
166+ regs->r27 = addr+16;
167+ regs->pc = resolver;
168+ return 3;
169+ }
170+ }
171+ } while (0);
172+#endif
173+
174+ return 1;
175+}
176+
177+void pax_report_insns(void *pc, void *sp)
178+{
179+ unsigned long i;
180+
181+ printk(KERN_ERR "PAX: bytes at PC: ");
182+ for (i = 0; i < 5; i++) {
183+ unsigned int c;
184+ if (get_user(c, (unsigned int*)pc+i))
185+ printk("???????? ");
186+ else
187+ printk("%08x ", c);
188+ }
189+ printk("\n");
190+}
191+#endif
192
193 /*
194 * This routine handles page faults. It determines the address,
195@@ -132,8 +251,29 @@ do_page_fault(unsigned long address, uns
196 good_area:
197 si_code = SEGV_ACCERR;
198 if (cause < 0) {
199- if (!(vma->vm_flags & VM_EXEC))
200+ if (!(vma->vm_flags & VM_EXEC)) {
201+
202+#ifdef CONFIG_PAX_PAGEEXEC
203+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
204+ goto bad_area;
205+
206+ up_read(&mm->mmap_sem);
207+ switch(pax_handle_fetch_fault(regs)) {
208+
209+#ifdef CONFIG_PAX_EMUPLT
210+ case 2:
211+ case 3:
212+ return;
213+#endif
214+
215+ }
216+ pax_report_fault(regs, (void*)regs->pc, (void*)rdusp());
217+ do_exit(SIGKILL);
218+#else
219 goto bad_area;
220+#endif
221+
222+ }
223 } else if (!cause) {
224 /* Allow reads even for write-only mappings */
225 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
226diff -urNp linux-2.6.19.1/arch/arm/mm/mmap.c linux-2.6.19.1/arch/arm/mm/mmap.c
227--- linux-2.6.19.1/arch/arm/mm/mmap.c 2006-11-29 16:57:37.000000000 -0500
228+++ linux-2.6.19.1/arch/arm/mm/mmap.c 2006-12-03 15:15:44.000000000 -0500
229@@ -61,6 +61,10 @@ arch_get_unmapped_area(struct file *filp
230 if (len > TASK_SIZE)
231 return -ENOMEM;
232
233+#ifdef CONFIG_PAX_RANDMMAP
234+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
235+#endif
236+
237 if (addr) {
238 if (do_align)
239 addr = COLOUR_ALIGN(addr, pgoff);
240@@ -75,7 +79,7 @@ arch_get_unmapped_area(struct file *filp
241 if (len > mm->cached_hole_size) {
242 start_addr = addr = mm->free_area_cache;
243 } else {
244- start_addr = addr = TASK_UNMAPPED_BASE;
245+ start_addr = addr = mm->mmap_base;
246 mm->cached_hole_size = 0;
247 }
248
249@@ -92,8 +96,8 @@ full_search:
250 * Start a new search - just in case we missed
251 * some holes.
252 */
253- if (start_addr != TASK_UNMAPPED_BASE) {
254- start_addr = addr = TASK_UNMAPPED_BASE;
255+ if (start_addr != mm->mmap_base) {
256+ start_addr = addr = mm->mmap_base;
257 mm->cached_hole_size = 0;
258 goto full_search;
259 }
260diff -urNp linux-2.6.19.1/arch/i386/boot/compressed/head.S linux-2.6.19.1/arch/i386/boot/compressed/head.S
261--- linux-2.6.19.1/arch/i386/boot/compressed/head.S 2006-11-29 16:57:37.000000000 -0500
262+++ linux-2.6.19.1/arch/i386/boot/compressed/head.S 2006-12-03 15:15:45.000000000 -0500
263@@ -39,11 +39,13 @@ startup_32:
264 movl %eax,%gs
265
266 lss stack_start,%esp
267+ movl 0x000000,%ecx
268 xorl %eax,%eax
269 1: incl %eax # check that A20 really IS enabled
270 movl %eax,0x000000 # loop forever if it isn't
271 cmpl %eax,0x100000
272 je 1b
273+ movl %ecx,0x000000
274
275 /*
276 * Initialize eflags. Some BIOS's leave bits like NT set. This would
277diff -urNp linux-2.6.19.1/arch/i386/Kconfig linux-2.6.19.1/arch/i386/Kconfig
278--- linux-2.6.19.1/arch/i386/Kconfig 2006-11-29 16:57:37.000000000 -0500
279+++ linux-2.6.19.1/arch/i386/Kconfig 2006-12-03 15:15:45.000000000 -0500
280@@ -803,7 +803,7 @@ config HOTPLUG_CPU
281
282 config COMPAT_VDSO
283 bool "Compat VDSO support"
284- default y
285+ default n
286 depends on !PARAVIRT
287 help
288 Map the VDSO to the predictable old-style address too.
289@@ -999,7 +999,7 @@ config PCI
290 choice
291 prompt "PCI access mode"
292 depends on PCI && !X86_VISWS
293- default PCI_GOANY
294+ default PCI_GODIRECT
295 ---help---
296 On PCI systems, the BIOS can be used to detect the PCI devices and
297 determine their configuration. However, some old PCI motherboards
298@@ -1031,7 +1031,7 @@ endchoice
299
300 config PCI_BIOS
301 bool
302- depends on !X86_VISWS && PCI && (PCI_GOBIOS || PCI_GOANY)
303+ depends on !X86_VISWS && PCI && PCI_GOBIOS
304 default y
305
306 config PCI_DIRECT
307diff -urNp linux-2.6.19.1/arch/i386/Kconfig.cpu linux-2.6.19.1/arch/i386/Kconfig.cpu
308--- linux-2.6.19.1/arch/i386/Kconfig.cpu 2006-11-29 16:57:37.000000000 -0500
309+++ linux-2.6.19.1/arch/i386/Kconfig.cpu 2006-12-03 15:15:45.000000000 -0500
310@@ -252,7 +252,7 @@ config X86_PPRO_FENCE
311
312 config X86_F00F_BUG
313 bool
314- depends on M586MMX || M586TSC || M586 || M486 || M386
315+ depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
316 default y
317
318 config X86_WP_WORKS_OK
319@@ -282,7 +282,7 @@ config X86_CMPXCHG64
320
321 config X86_ALIGNMENT_16
322 bool
323- depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
324+ depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
325 default y
326
327 config X86_GOOD_APIC
328diff -urNp linux-2.6.19.1/arch/i386/Kconfig.debug linux-2.6.19.1/arch/i386/Kconfig.debug
329--- linux-2.6.19.1/arch/i386/Kconfig.debug 2006-11-29 16:57:37.000000000 -0500
330+++ linux-2.6.19.1/arch/i386/Kconfig.debug 2006-12-03 15:15:45.000000000 -0500
331@@ -48,7 +48,7 @@ config DEBUG_PAGEALLOC
332
333 config DEBUG_RODATA
334 bool "Write protect kernel read-only data structures"
335- depends on DEBUG_KERNEL
336+ depends on DEBUG_KERNEL && !PAX_KERNEXEC
337 help
338 Mark the kernel read-only data as write-protected in the pagetables,
339 in order to catch accidental (and incorrect) writes to such const
340diff -urNp linux-2.6.19.1/arch/i386/kernel/alternative.c linux-2.6.19.1/arch/i386/kernel/alternative.c
341--- linux-2.6.19.1/arch/i386/kernel/alternative.c 2006-11-29 16:57:37.000000000 -0500
342+++ linux-2.6.19.1/arch/i386/kernel/alternative.c 2006-12-03 15:15:45.000000000 -0500
343@@ -3,6 +3,7 @@
344 #include <linux/list.h>
345 #include <asm/alternative.h>
346 #include <asm/sections.h>
347+#include <asm/desc.h>
348
349 static int no_replacement = 0;
350 static int smp_alt_once = 0;
351@@ -142,6 +143,12 @@ void apply_alternatives(struct alt_instr
352 u8 *instr;
353 int diff, i, k;
354
355+#ifdef CONFIG_PAX_KERNEXEC
356+ unsigned long cr0;
357+
358+ pax_open_kernel(cr0);
359+#endif
360+
361 DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
362 for (a = start; a < end; a++) {
363 BUG_ON(a->replacementlen > a->instrlen);
364@@ -156,16 +163,21 @@ void apply_alternatives(struct alt_instr
365 __FUNCTION__, a->instr, instr);
366 }
367 #endif
368- memcpy(instr, a->replacement, a->replacementlen);
369+ memcpy(instr + __KERNEL_TEXT_OFFSET, a->replacement, a->replacementlen);
370 diff = a->instrlen - a->replacementlen;
371 /* Pad the rest with nops */
372 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
373 k = diff;
374 if (k > ASM_NOP_MAX)
375 k = ASM_NOP_MAX;
376- memcpy(a->instr + i, noptable[k], k);
377+ memcpy(a->instr + i + __KERNEL_TEXT_OFFSET, noptable[k], k);
378 }
379 }
380+
381+#ifdef CONFIG_PAX_KERNEXEC
382+ pax_close_kernel(cr0);
383+#endif
384+
385 }
386
387 #ifdef CONFIG_SMP
388@@ -174,50 +186,96 @@ static void alternatives_smp_save(struct
389 {
390 struct alt_instr *a;
391
392+#ifdef CONFIG_PAX_KERNEXEC
393+ unsigned long cr0;
394+
395+ pax_open_kernel(cr0);
396+#endif
397+
398 DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
399 for (a = start; a < end; a++) {
400 memcpy(a->replacement + a->replacementlen,
401- a->instr,
402+ a->instr + __KERNEL_TEXT_OFFSET,
403 a->instrlen);
404 }
405+
406+#ifdef CONFIG_PAX_KERNEXEC
407+ pax_close_kernel(cr0);
408+#endif
409+
410 }
411
412 static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
413 {
414 struct alt_instr *a;
415
416+#ifdef CONFIG_PAX_KERNEXEC
417+ unsigned long cr0;
418+
419+ pax_open_kernel(cr0);
420+#endif
421+
422 for (a = start; a < end; a++) {
423- memcpy(a->instr,
424+ memcpy(a->instr + __KERNEL_TEXT_OFFSET,
425 a->replacement + a->replacementlen,
426 a->instrlen);
427 }
428+
429+#ifdef CONFIG_PAX_KERNEXEC
430+ pax_close_kernel(cr0);
431+#endif
432+
433 }
434
435 static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
436 {
437- u8 **ptr;
438+ u8 *ptr;
439+
440+#ifdef CONFIG_PAX_KERNEXEC
441+ unsigned long cr0;
442
443- for (ptr = start; ptr < end; ptr++) {
444- if (*ptr < text)
445+ pax_open_kernel(cr0);
446+#endif
447+
448+ for (; start < end; start++) {
449+ ptr = *start + __KERNEL_TEXT_OFFSET;
450+ if (ptr < text)
451 continue;
452- if (*ptr > text_end)
453+ if (ptr > text_end)
454 continue;
455- **ptr = 0xf0; /* lock prefix */
456+ *ptr = 0xf0; /* lock prefix */
457 };
458+
459+#ifdef CONFIG_PAX_KERNEXEC
460+ pax_close_kernel(cr0);
461+#endif
462+
463 }
464
465 static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
466 {
467 unsigned char **noptable = find_nop_table();
468- u8 **ptr;
469+ u8 *ptr;
470+
471+#ifdef CONFIG_PAX_KERNEXEC
472+ unsigned long cr0;
473+
474+ pax_open_kernel(cr0);
475+#endif
476
477- for (ptr = start; ptr < end; ptr++) {
478- if (*ptr < text)
479+ for (; start < end; start++) {
480+ ptr = *start + __KERNEL_TEXT_OFFSET;
481+ if (ptr < text)
482 continue;
483- if (*ptr > text_end)
484+ if (ptr > text_end)
485 continue;
486- **ptr = noptable[1][0];
487+ *ptr = noptable[1][0];
488 };
489+
490+#ifdef CONFIG_PAX_KERNEXEC
491+ pax_close_kernel(cr0);
492+#endif
493+
494 }
495
496 struct smp_alt_module {
497diff -urNp linux-2.6.19.1/arch/i386/kernel/apic.c linux-2.6.19.1/arch/i386/kernel/apic.c
498--- linux-2.6.19.1/arch/i386/kernel/apic.c 2006-11-29 16:57:37.000000000 -0500
499+++ linux-2.6.19.1/arch/i386/kernel/apic.c 2006-12-03 15:15:45.000000000 -0500
500@@ -1197,7 +1197,7 @@ inline void smp_local_timer_interrupt(vo
501 {
502 profile_tick(CPU_PROFILING);
503 #ifdef CONFIG_SMP
504- update_process_times(user_mode_vm(get_irq_regs()));
505+ update_process_times(user_mode(get_irq_regs()));
506 #endif
507
508 /*
509diff -urNp linux-2.6.19.1/arch/i386/kernel/apm.c linux-2.6.19.1/arch/i386/kernel/apm.c
510--- linux-2.6.19.1/arch/i386/kernel/apm.c 2006-11-29 16:57:37.000000000 -0500
511+++ linux-2.6.19.1/arch/i386/kernel/apm.c 2006-12-03 15:15:45.000000000 -0500
512@@ -235,7 +235,7 @@
513 #include "io_ports.h"
514
515 extern unsigned long get_cmos_time(void);
516-extern void machine_real_restart(unsigned char *, int);
517+extern void machine_real_restart(const unsigned char *, unsigned int);
518
519 #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
520 extern int (*console_blank_hook)(int);
521@@ -608,9 +608,18 @@ static u8 apm_bios_call(u32 func, u32 eb
522 struct desc_struct save_desc_40;
523 struct desc_struct *gdt;
524
525+#ifdef CONFIG_PAX_KERNEXEC
526+ unsigned long cr0;
527+#endif
528+
529 cpus = apm_save_cpus();
530
531 cpu = get_cpu();
532+
533+#ifdef CONFIG_PAX_KERNEXEC
534+ pax_open_kernel(cr0);
535+#endif
536+
537 gdt = get_cpu_gdt_table(cpu);
538 save_desc_40 = gdt[0x40 / 8];
539 gdt[0x40 / 8] = bad_bios_desc;
540@@ -621,6 +630,11 @@ static u8 apm_bios_call(u32 func, u32 eb
541 APM_DO_RESTORE_SEGS;
542 apm_irq_restore(flags);
543 gdt[0x40 / 8] = save_desc_40;
544+
545+#ifdef CONFIG_PAX_KERNEXEC
546+ pax_close_kernel(cr0);
547+#endif
548+
549 put_cpu();
550 apm_restore_cpus(cpus);
551
552@@ -651,9 +665,18 @@ static u8 apm_bios_call_simple(u32 func,
553 struct desc_struct save_desc_40;
554 struct desc_struct *gdt;
555
556+#ifdef CONFIG_PAX_KERNEXEC
557+ unsigned long cr0;
558+#endif
559+
560 cpus = apm_save_cpus();
561
562 cpu = get_cpu();
563+
564+#ifdef CONFIG_PAX_KERNEXEC
565+ pax_open_kernel(cr0);
566+#endif
567+
568 gdt = get_cpu_gdt_table(cpu);
569 save_desc_40 = gdt[0x40 / 8];
570 gdt[0x40 / 8] = bad_bios_desc;
571@@ -664,6 +687,11 @@ static u8 apm_bios_call_simple(u32 func,
572 APM_DO_RESTORE_SEGS;
573 apm_irq_restore(flags);
574 gdt[0x40 / 8] = save_desc_40;
575+
576+#ifdef CONFIG_PAX_KERNEXEC
577+ pax_close_kernel(cr0);
578+#endif
579+
580 put_cpu();
581 apm_restore_cpus(cpus);
582 return error;
583@@ -927,7 +955,7 @@ recalc:
584
585 static void apm_power_off(void)
586 {
587- unsigned char po_bios_call[] = {
588+ const unsigned char po_bios_call[] = {
589 0xb8, 0x00, 0x10, /* movw $0x1000,ax */
590 0x8e, 0xd0, /* movw ax,ss */
591 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */
592diff -urNp linux-2.6.19.1/arch/i386/kernel/asm-offsets.c linux-2.6.19.1/arch/i386/kernel/asm-offsets.c
593--- linux-2.6.19.1/arch/i386/kernel/asm-offsets.c 2006-11-29 16:57:37.000000000 -0500
594+++ linux-2.6.19.1/arch/i386/kernel/asm-offsets.c 2006-12-03 15:15:45.000000000 -0500
595@@ -71,6 +71,7 @@ void foo(void)
596 sizeof(struct tss_struct));
597
598 DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
599+ DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
600 DEFINE(VDSO_PRELINK, VDSO_PRELINK);
601
602 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
603diff -urNp linux-2.6.19.1/arch/i386/kernel/cpu/common.c linux-2.6.19.1/arch/i386/kernel/cpu/common.c
604--- linux-2.6.19.1/arch/i386/kernel/cpu/common.c 2006-11-29 16:57:37.000000000 -0500
605+++ linux-2.6.19.1/arch/i386/kernel/cpu/common.c 2006-12-03 15:15:45.000000000 -0500
606@@ -4,7 +4,6 @@
607 #include <linux/smp.h>
608 #include <linux/module.h>
609 #include <linux/percpu.h>
610-#include <linux/bootmem.h>
611 #include <asm/semaphore.h>
612 #include <asm/processor.h>
613 #include <asm/i387.h>
614@@ -21,16 +20,18 @@
615
616 #include "cpu.h"
617
618-DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
619-EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
620-
621 DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
622 EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);
623
624 static int cachesize_override __cpuinitdata = -1;
625 static int disable_x86_fxsr __cpuinitdata;
626 static int disable_x86_serial_nr __cpuinitdata = 1;
627+
628+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC)
629+static int disable_x86_sep __cpuinitdata = 1;
630+#else
631 static int disable_x86_sep __cpuinitdata;
632+#endif
633
634 struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
635
636@@ -600,11 +601,10 @@ void __init early_cpu_init(void)
637 void __cpuinit cpu_init(void)
638 {
639 int cpu = smp_processor_id();
640- struct tss_struct * t = &per_cpu(init_tss, cpu);
641+ struct tss_struct * t = init_tss + cpu;
642 struct thread_struct *thread = &current->thread;
643- struct desc_struct *gdt;
644+ struct desc_struct *gdt = get_cpu_gdt_table(cpu);
645 __u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
646- struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
647
648 if (cpu_test_and_set(cpu, cpu_initialized)) {
649 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
650@@ -621,36 +621,12 @@ void __cpuinit cpu_init(void)
651 set_in_cr4(X86_CR4_TSD);
652 }
653
654- /* The CPU hotplug case */
655- if (cpu_gdt_descr->address) {
656- gdt = (struct desc_struct *)cpu_gdt_descr->address;
657- memset(gdt, 0, PAGE_SIZE);
658- goto old_gdt;
659- }
660- /*
661- * This is a horrible hack to allocate the GDT. The problem
662- * is that cpu_init() is called really early for the boot CPU
663- * (and hence needs bootmem) but much later for the secondary
664- * CPUs, when bootmem will have gone away
665- */
666- if (NODE_DATA(0)->bdata->node_bootmem_map) {
667- gdt = (struct desc_struct *)alloc_bootmem_pages(PAGE_SIZE);
668- /* alloc_bootmem_pages panics on failure, so no check */
669- memset(gdt, 0, PAGE_SIZE);
670- } else {
671- gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
672- if (unlikely(!gdt)) {
673- printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
674- for (;;)
675- local_irq_enable();
676- }
677- }
678-old_gdt:
679 /*
680 * Initialize the per-CPU GDT with the boot GDT,
681 * and set up the GDT descriptor:
682 */
683- memcpy(gdt, cpu_gdt_table, GDT_SIZE);
684+ if (cpu)
685+ memcpy(gdt, cpu_gdt_table, GDT_SIZE);
686
687 /* Set up GDT entry for 16bit stack */
688 *(__u64 *)(&gdt[GDT_ENTRY_ESPFIX_SS]) |=
689@@ -658,10 +634,10 @@ old_gdt:
690 ((((__u64)stk16_off) << 32) & 0xff00000000000000ULL) |
691 (CPU_16BIT_STACK_SIZE - 1);
692
693- cpu_gdt_descr->size = GDT_SIZE - 1;
694- cpu_gdt_descr->address = (unsigned long)gdt;
695+ cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
696+ cpu_gdt_descr[cpu].address = (unsigned long)gdt;
697
698- load_gdt(cpu_gdt_descr);
699+ load_gdt(&cpu_gdt_descr[cpu]);
700 load_idt(&idt_descr);
701
702 /*
703diff -urNp linux-2.6.19.1/arch/i386/kernel/crash.c linux-2.6.19.1/arch/i386/kernel/crash.c
704--- linux-2.6.19.1/arch/i386/kernel/crash.c 2006-11-29 16:57:37.000000000 -0500
705+++ linux-2.6.19.1/arch/i386/kernel/crash.c 2006-12-03 15:15:45.000000000 -0500
706@@ -117,7 +117,7 @@ static int crash_nmi_callback(struct not
707 return NOTIFY_STOP;
708 local_irq_disable();
709
710- if (!user_mode_vm(regs)) {
711+ if (!user_mode(regs)) {
712 crash_fixup_ss_esp(&fixed_regs, regs);
713 regs = &fixed_regs;
714 }
715diff -urNp linux-2.6.19.1/arch/i386/kernel/doublefault.c linux-2.6.19.1/arch/i386/kernel/doublefault.c
716--- linux-2.6.19.1/arch/i386/kernel/doublefault.c 2006-11-29 16:57:37.000000000 -0500
717+++ linux-2.6.19.1/arch/i386/kernel/doublefault.c 2006-12-03 15:15:45.000000000 -0500
718@@ -11,7 +11,7 @@
719
720 #define DOUBLEFAULT_STACKSIZE (1024)
721 static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
722-#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
723+#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
724
725 #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
726
727@@ -57,10 +57,10 @@ struct tss_struct doublefault_tss __cach
728 .eip = (unsigned long) doublefault_fn,
729 .eflags = X86_EFLAGS_SF | 0x2, /* 0x2 bit is always set */
730 .esp = STACK_START,
731- .es = __USER_DS,
732+ .es = __KERNEL_DS,
733 .cs = __KERNEL_CS,
734 .ss = __KERNEL_DS,
735- .ds = __USER_DS,
736+ .ds = __KERNEL_DS,
737
738 .__cr3 = __pa(swapper_pg_dir)
739 };
740diff -urNp linux-2.6.19.1/arch/i386/kernel/efi.c linux-2.6.19.1/arch/i386/kernel/efi.c
741--- linux-2.6.19.1/arch/i386/kernel/efi.c 2006-11-29 16:57:37.000000000 -0500
742+++ linux-2.6.19.1/arch/i386/kernel/efi.c 2006-12-03 15:15:45.000000000 -0500
743@@ -63,82 +63,43 @@ extern void * boot_ioremap(unsigned long
744
745 static unsigned long efi_rt_eflags;
746 static DEFINE_SPINLOCK(efi_rt_lock);
747-static pgd_t efi_bak_pg_dir_pointer[2];
748+static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
749
750 static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
751 {
752- unsigned long cr4;
753- unsigned long temp;
754- struct Xgt_desc_struct *cpu_gdt_descr;
755-
756 spin_lock(&efi_rt_lock);
757 local_irq_save(efi_rt_eflags);
758
759- cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
760-
761- /*
762- * If I don't have PSE, I should just duplicate two entries in page
763- * directory. If I have PSE, I just need to duplicate one entry in
764- * page directory.
765- */
766- cr4 = read_cr4();
767-
768- if (cr4 & X86_CR4_PSE) {
769- efi_bak_pg_dir_pointer[0].pgd =
770- swapper_pg_dir[pgd_index(0)].pgd;
771- swapper_pg_dir[0].pgd =
772- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
773- } else {
774- efi_bak_pg_dir_pointer[0].pgd =
775- swapper_pg_dir[pgd_index(0)].pgd;
776- efi_bak_pg_dir_pointer[1].pgd =
777- swapper_pg_dir[pgd_index(0x400000)].pgd;
778- swapper_pg_dir[pgd_index(0)].pgd =
779- swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
780- temp = PAGE_OFFSET + 0x400000;
781- swapper_pg_dir[pgd_index(0x400000)].pgd =
782- swapper_pg_dir[pgd_index(temp)].pgd;
783- }
784+ clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
785+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
786+ USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
787
788 /*
789 * After the lock is released, the original page table is restored.
790 */
791- local_flush_tlb();
792+ __flush_tlb_all();
793
794- cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
795- load_gdt(cpu_gdt_descr);
796+ cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
797+ load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
798 }
799
800 static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
801 {
802- unsigned long cr4;
803- struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
804-
805- cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
806- load_gdt(cpu_gdt_descr);
807+ cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
808+ load_gdt(&cpu_gdt_descr[0]);
809
810- cr4 = read_cr4();
811-
812- if (cr4 & X86_CR4_PSE) {
813- swapper_pg_dir[pgd_index(0)].pgd =
814- efi_bak_pg_dir_pointer[0].pgd;
815- } else {
816- swapper_pg_dir[pgd_index(0)].pgd =
817- efi_bak_pg_dir_pointer[0].pgd;
818- swapper_pg_dir[pgd_index(0x400000)].pgd =
819- efi_bak_pg_dir_pointer[1].pgd;
820- }
821+ clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
822
823 /*
824 * After the lock is released, the original page table is restored.
825 */
826- local_flush_tlb();
827+ __flush_tlb_all();
828
829 local_irq_restore(efi_rt_eflags);
830 spin_unlock(&efi_rt_lock);
831 }
832
833-static efi_status_t
834+static efi_status_t __init
835 phys_efi_set_virtual_address_map(unsigned long memory_map_size,
836 unsigned long descriptor_size,
837 u32 descriptor_version,
838@@ -154,7 +115,7 @@ phys_efi_set_virtual_address_map(unsigne
839 return status;
840 }
841
842-static efi_status_t
843+static efi_status_t __init
844 phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
845 {
846 efi_status_t status;
847diff -urNp linux-2.6.19.1/arch/i386/kernel/efi_stub.S linux-2.6.19.1/arch/i386/kernel/efi_stub.S
848--- linux-2.6.19.1/arch/i386/kernel/efi_stub.S 2006-11-29 16:57:37.000000000 -0500
849+++ linux-2.6.19.1/arch/i386/kernel/efi_stub.S 2006-12-03 15:15:45.000000000 -0500
850@@ -6,6 +6,7 @@
851 */
852
853 #include <linux/linkage.h>
854+#include <linux/init.h>
855 #include <asm/page.h>
856
857 /*
858@@ -20,7 +21,7 @@
859 * service functions will comply with gcc calling convention, too.
860 */
861
862-.text
863+__INIT
864 ENTRY(efi_call_phys)
865 /*
866 * 0. The function can only be called in Linux kernel. So CS has been
867@@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
868 * The mapping of lower virtual memory has been created in prelog and
869 * epilog.
870 */
871- movl $1f, %edx
872- subl $__PAGE_OFFSET, %edx
873- jmp *%edx
874+ jmp 1f-__PAGE_OFFSET
875 1:
876
877 /*
878@@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
879 * parameter 2, ..., param n. To make things easy, we save the return
880 * address of efi_call_phys in a global variable.
881 */
882- popl %edx
883- movl %edx, saved_return_addr
884- /* get the function pointer into ECX*/
885- popl %ecx
886- movl %ecx, efi_rt_function_ptr
887- movl $2f, %edx
888- subl $__PAGE_OFFSET, %edx
889- pushl %edx
890+ popl (saved_return_addr)
891+ popl (efi_rt_function_ptr)
892
893 /*
894 * 3. Clear PG bit in %CR0.
895@@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
896 /*
897 * 5. Call the physical function.
898 */
899- jmp *%ecx
900+ call *(efi_rt_function_ptr-__PAGE_OFFSET)
901
902-2:
903 /*
904 * 6. After EFI runtime service returns, control will return to
905 * following instruction. We'd better readjust stack pointer first.
906@@ -85,37 +77,29 @@ ENTRY(efi_call_phys)
907 /*
908 * 7. Restore PG bit
909 */
910- movl %cr0, %edx
911- orl $0x80000000, %edx
912- movl %edx, %cr0
913- jmp 1f
914-1:
915 /*
916 * 8. Now restore the virtual mode from flat mode by
917 * adding EIP with PAGE_OFFSET.
918 */
919- movl $1f, %edx
920- jmp *%edx
921+ movl %cr0, %edx
922+ orl $0x80000000, %edx
923+ movl %edx, %cr0
924+ jmp 1f+__PAGE_OFFSET
925 1:
926
927 /*
928 * 9. Balance the stack. And because EAX contain the return value,
929 * we'd better not clobber it.
930 */
931- leal efi_rt_function_ptr, %edx
932- movl (%edx), %ecx
933- pushl %ecx
934+ pushl (efi_rt_function_ptr)
935
936 /*
937- * 10. Push the saved return address onto the stack and return.
938+ * 10. Return to the saved return address.
939 */
940- leal saved_return_addr, %edx
941- movl (%edx), %ecx
942- pushl %ecx
943- ret
944+ jmpl *(saved_return_addr)
945 .previous
946
947-.data
948+__INITDATA
949 saved_return_addr:
950 .long 0
951 efi_rt_function_ptr:
952diff -urNp linux-2.6.19.1/arch/i386/kernel/entry.S linux-2.6.19.1/arch/i386/kernel/entry.S
953--- linux-2.6.19.1/arch/i386/kernel/entry.S 2006-11-29 16:57:37.000000000 -0500
954+++ linux-2.6.19.1/arch/i386/kernel/entry.S 2006-12-10 21:43:36.000000000 -0500
955@@ -82,6 +82,8 @@ VM_MASK = 0x00020000
956 #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit
957 #define INTERRUPT_RETURN iret
958 #define GET_CR0_INTO_EAX movl %cr0, %eax
959+#define GET_CR0_INTO_EDX movl %cr0, %edx
960+#define SET_CR0_FROM_EDX movl %edx, %cr0
961
962 #ifdef CONFIG_PREEMPT
963 #define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF
964@@ -105,7 +107,7 @@ VM_MASK = 0x00020000
965 #define resume_userspace_sig resume_userspace
966 #endif
967
968-#define SAVE_ALL \
969+#define __SAVE_ALL(_DS) \
970 cld; \
971 pushl %es; \
972 CFI_ADJUST_CFA_OFFSET 4;\
973@@ -134,10 +136,24 @@ VM_MASK = 0x00020000
974 pushl %ebx; \
975 CFI_ADJUST_CFA_OFFSET 4;\
976 CFI_REL_OFFSET ebx, 0;\
977- movl $(__USER_DS), %edx; \
978+ movl $(_DS), %edx; \
979 movl %edx, %ds; \
980 movl %edx, %es;
981
982+#ifdef CONFIG_PAX_KERNEXEC
983+#define SAVE_ALL \
984+ __SAVE_ALL(__KERNEL_DS) \
985+ GET_CR0_INTO_EDX; \
986+ movl %edx, %esi; \
987+ orl $0x10000, %edx; \
988+ xorl %edx, %esi; \
989+ SET_CR0_FROM_EDX
990+#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
991+#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
992+#else
993+#define SAVE_ALL __SAVE_ALL(__USER_DS)
994+#endif
995+
996 #define RESTORE_INT_REGS \
997 popl %ebx; \
998 CFI_ADJUST_CFA_OFFSET -4;\
999@@ -245,7 +261,18 @@ check_userspace:
1000 movb CS(%esp), %al
1001 andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
1002 cmpl $USER_RPL, %eax
1003+
1004+#ifdef CONFIG_PAX_KERNEXEC
1005+ jae resume_userspace
1006+
1007+ GET_CR0_INTO_EDX
1008+ xorl %esi, %edx
1009+ SET_CR0_FROM_EDX
1010+ jmp resume_kernel
1011+#else
1012 jb resume_kernel # not returning to v8086 or userspace
1013+#endif
1014+
1015 ENTRY(resume_userspace)
1016 DISABLE_INTERRUPTS # make sure we don't miss an interrupt
1017 # setting need_resched or sigpending
1018@@ -301,10 +328,9 @@ sysenter_past_esp:
1019 /*CFI_REL_OFFSET cs, 0*/
1020 /*
1021 * Push current_thread_info()->sysenter_return to the stack.
1022- * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
1023- * pushed above; +8 corresponds to copy_thread's esp0 setting.
1024 */
1025- pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
1026+ GET_THREAD_INFO(%ebp)
1027+ pushl TI_sysenter_return(%ebp)
1028 CFI_ADJUST_CFA_OFFSET 4
1029 CFI_REL_OFFSET eip, 0
1030
1031@@ -312,9 +338,20 @@ sysenter_past_esp:
1032 * Load the potential sixth argument from user stack.
1033 * Careful about security.
1034 */
1035+ movl 12(%esp),%ebp
1036+
1037+#ifdef CONFIG_PAX_MEMORY_UDEREF
1038+ pushl $(__USER_DS)
1039+ CFI_ADJUST_CFA_OFFSET 4
1040+ pop %ds
1041+ CFI_ADJUST_CFA_OFFSET -4
1042+1: movl %ds:(%ebp),%ebp
1043+#else
1044 cmpl $__PAGE_OFFSET-3,%ebp
1045 jae syscall_fault
1046 1: movl (%ebp),%ebp
1047+#endif
1048+
1049 .section __ex_table,"a"
1050 .align 4
1051 .long 1b,syscall_fault
1052@@ -337,14 +374,36 @@ sysenter_past_esp:
1053 movl TI_flags(%ebp), %ecx
1054 testw $_TIF_ALLWORK_MASK, %cx
1055 jne syscall_exit_work
1056+
1057+#ifdef CONFIG_PAX_RANDKSTACK
1058+ pushl %eax
1059+ CFI_ADJUST_CFA_OFFSET 4
1060+ call pax_randomize_kstack
1061+ popl %eax
1062+ CFI_ADJUST_CFA_OFFSET -4
1063+#endif
1064+
1065 /* if something modifies registers it must also disable sysexit */
1066 movl EIP(%esp), %edx
1067 movl OLDESP(%esp), %ecx
1068 xorl %ebp,%ebp
1069 TRACE_IRQS_ON
1070+1: mov DS(%esp), %ds
1071+2: mov ES(%esp), %es
1072 ENABLE_INTERRUPTS_SYSEXIT
1073 CFI_ENDPROC
1074
1075+.section .fixup,"ax"
1076+3: movl $0,DS(%esp)
1077+ jmp 1b
1078+4: movl $0,ES(%esp)
1079+ jmp 2b
1080+.previous
1081+.section __ex_table,"a"
1082+ .align 4
1083+ .long 1b,3b
1084+ .long 2b,4b
1085+.previous
1086
1087 # system call handler stub
1088 ENTRY(system_call)
1089@@ -375,6 +434,10 @@ syscall_exit:
1090 testw $_TIF_ALLWORK_MASK, %cx # current->work
1091 jne syscall_exit_work
1092
1093+#ifdef CONFIG_PAX_RANDKSTACK
1094+ call pax_randomize_kstack
1095+#endif
1096+
1097 restore_all:
1098 movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
1099 # Warning: OLDSS(%esp) contains the wrong/random values if we
1100@@ -553,7 +616,7 @@ syscall_badsys:
1101 * Build the entry stubs and pointer table with
1102 * some assembler magic.
1103 */
1104-.data
1105+.section .rodata,"a",@progbits
1106 ENTRY(interrupt)
1107 .text
1108
1109@@ -568,7 +631,7 @@ ENTRY(irq_entries_start)
1110 1: pushl $~(vector)
1111 CFI_ADJUST_CFA_OFFSET 4
1112 jmp common_interrupt
1113-.data
1114+.section .rodata,"a",@progbits
1115 .long 1b
1116 .text
1117 vector=vector+1
1118@@ -642,12 +705,21 @@ error_code:
1119 popl %ecx
1120 CFI_ADJUST_CFA_OFFSET -4
1121 /*CFI_REGISTER es, ecx*/
1122+
1123+#ifdef CONFIG_PAX_KERNEXEC
1124+ GET_CR0_INTO_EDX
1125+ movl %edx, %esi
1126+ orl $0x10000, %edx
1127+ xorl %edx, %esi
1128+ SET_CR0_FROM_EDX
1129+#endif
1130+
1131 movl ES(%esp), %edi # get the function address
1132 movl ORIG_EAX(%esp), %edx # get the error code
1133 movl %eax, ORIG_EAX(%esp)
1134 movl %ecx, ES(%esp)
1135 /*CFI_REL_OFFSET es, ES*/
1136- movl $(__USER_DS), %ecx
1137+ movl $(__KERNEL_DS), %ecx
1138 movl %ecx, %ds
1139 movl %ecx, %es
1140 movl %esp,%eax # pt_regs pointer
1141@@ -778,6 +850,13 @@ nmi_stack_correct:
1142 xorl %edx,%edx # zero error code
1143 movl %esp,%eax # pt_regs pointer
1144 call do_nmi
1145+
1146+#ifdef CONFIG_PAX_KERNEXEC
1147+ GET_CR0_INTO_EDX
1148+ xorl %esi, %edx
1149+ SET_CR0_FROM_EDX
1150+#endif
1151+
1152 jmp restore_nocheck_notrace
1153 CFI_ENDPROC
1154
1155@@ -820,6 +899,13 @@ nmi_16bit_stack:
1156 CFI_ADJUST_CFA_OFFSET -20 # the frame has now moved
1157 xorl %edx,%edx # zero error code
1158 call do_nmi
1159+
1160+#ifdef CONFIG_PAX_KERNEXEC
1161+ GET_CR0_INTO_EDX
1162+ xorl %esi, %edx
1163+ SET_CR0_FROM_EDX
1164+#endif
1165+
1166 RESTORE_REGS
1167 lss 12+4(%esp), %esp # back to 16bit stack
1168 1: INTERRUPT_RETURN
1169@@ -957,8 +1043,8 @@ ENTRY(arch_unwind_init_running)
1170 movl %edi, EDI(%edx)
1171 movl %ebp, EBP(%edx)
1172 movl %ebx, EAX(%edx)
1173- movl $__USER_DS, DS(%edx)
1174- movl $__USER_DS, ES(%edx)
1175+ movl $__KERNEL_DS, DS(%edx)
1176+ movl $__KERNEL_DS, ES(%edx)
1177 movl %ebx, ORIG_EAX(%edx)
1178 movl %ecx, EIP(%edx)
1179 movl 12(%esp), %ecx
1180@@ -987,7 +1073,6 @@ ENTRY(kernel_thread_helper)
1181 CFI_ENDPROC
1182 ENDPROC(kernel_thread_helper)
1183
1184-.section .rodata,"a"
1185 #include "syscall_table.S"
1186
1187 syscall_table_size=(.-sys_call_table)
1188diff -urNp linux-2.6.19.1/arch/i386/kernel/head.S linux-2.6.19.1/arch/i386/kernel/head.S
1189--- linux-2.6.19.1/arch/i386/kernel/head.S 2006-11-29 16:57:37.000000000 -0500
1190+++ linux-2.6.19.1/arch/i386/kernel/head.S 2006-12-03 15:15:45.000000000 -0500
1191@@ -45,6 +45,16 @@
1192 */
1193 #define INIT_MAP_BEYOND_END (128*1024)
1194
1195+#ifdef CONFIG_PAX_KERNEXEC
1196+/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1197+.fill 4096,1,0xcc
1198+#endif
1199+
1200+/*
1201+ * Real beginning of normal "text" segment
1202+ */
1203+ENTRY(stext)
1204+ENTRY(_stext)
1205
1206 /*
1207 * 32-bit kernel entrypoint; only used by the boot CPU. On entry,
1208@@ -66,6 +76,36 @@ ENTRY(startup_32)
1209 movl %eax,%fs
1210 movl %eax,%gs
1211
1212+#ifdef CONFIG_PAX_MEMORY_UDEREF
1213+ /* check for VMware */
1214+ movl $0x564d5868,%eax
1215+ xorl %ebx,%ebx
1216+ movl $0xa,%ecx
1217+ movl $0x5658,%edx
1218+ in (%dx),%eax
1219+ cmpl $0x564d5868,%ebx
1220+ jz 1f
1221+
1222+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1223+ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1224+ movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1225+ movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1226+1:
1227+#endif
1228+
1229+#ifdef CONFIG_PAX_KERNEXEC
1230+ movl $ __KERNEL_TEXT_OFFSET,%eax
1231+ movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1232+ rorl $16,%eax
1233+ movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1234+ movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1235+
1236+ movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1237+ movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1238+ rorl $16,%eax
1239+ movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1240+#endif
1241+
1242 /*
1243 * Clear BSS first so that there are no surprises...
1244 * No need to cld as DF is already clear from cld above...
1245@@ -113,24 +153,42 @@ ENTRY(startup_32)
1246 * Warning: don't use %esi or the stack in this code. However, %esp
1247 * can be used as a GPR if you really need it...
1248 */
1249-page_pde_offset = (__PAGE_OFFSET >> 20);
1250-
1251+#ifdef CONFIG_X86_PAE
1252+page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1253+#else
1254+page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1255+#endif
1256 movl $(pg0 - __PAGE_OFFSET), %edi
1257+#ifdef CONFIG_X86_PAE
1258+ movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1259+#else
1260 movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1261- movl $0x007, %eax /* 0x007 = PRESENT+RW+USER */
1262+#endif
1263+ movl $0x063, %eax /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1264 10:
1265- leal 0x007(%edi),%ecx /* Create PDE entry */
1266+ leal 0x063(%edi),%ecx /* Create PDE entry */
1267 movl %ecx,(%edx) /* Store identity PDE entry */
1268 movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */
1269+#ifdef CONFIG_X86_PAE
1270+ movl $0,4(%edx)
1271+ movl $0,page_pde_offset+4(%edx)
1272+ addl $8,%edx
1273+ movl $512, %ecx
1274+#else
1275 addl $4,%edx
1276 movl $1024, %ecx
1277+#endif
1278 11:
1279 stosl
1280+#ifdef CONFIG_X86_PAE
1281+ movl $0,(%edi)
1282+ addl $4,%edi
1283+#endif
1284 addl $0x1000,%eax
1285 loop 11b
1286 /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1287- /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1288- leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1289+ /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1290+ leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1291 cmpl %ebp,%eax
1292 jb 10b
1293 movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1294@@ -153,6 +211,11 @@ ENTRY(startup_32_smp)
1295 movl %eax,%fs
1296 movl %eax,%gs
1297
1298+ /* This is a secondary processor (AP) */
1299+ xorl %ebx,%ebx
1300+ incl %ebx
1301+#endif /* CONFIG_SMP */
1302+
1303 /*
1304 * New page tables may be in 4Mbyte page mode and may
1305 * be using the global pages.
1306@@ -168,26 +231,27 @@ ENTRY(startup_32_smp)
1307 * not yet offset PAGE_OFFSET..
1308 */
1309 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1310+3:
1311 movl cr4_bits,%edx
1312 andl %edx,%edx
1313- jz 6f
1314+ jz 5f
1315 movl %cr4,%eax # Turn on paging options (PSE,PAE,..)
1316 orl %edx,%eax
1317 movl %eax,%cr4
1318
1319- btl $5, %eax # check if PAE is enabled
1320- jnc 6f
1321+#ifdef CONFIG_X86_PAE
1322+ movl %ebx,%edi
1323
1324 /* Check if extended functions are implemented */
1325 movl $0x80000000, %eax
1326 cpuid
1327 cmpl $0x80000000, %eax
1328- jbe 6f
1329+ jbe 4f
1330 mov $0x80000001, %eax
1331 cpuid
1332 /* Execute Disable bit supported? */
1333 btl $20, %edx
1334- jnc 6f
1335+ jnc 4f
1336
1337 /* Setup EFER (Extended Feature Enable Register) */
1338 movl $0xc0000080, %ecx
1339@@ -196,14 +260,12 @@ ENTRY(startup_32_smp)
1340 btsl $11, %eax
1341 /* Make changes effective */
1342 wrmsr
1343+ btsl $63,__supported_pte_mask-__PAGE_OFFSET
1344
1345-6:
1346- /* This is a secondary processor (AP) */
1347- xorl %ebx,%ebx
1348- incl %ebx
1349-
1350-3:
1351-#endif /* CONFIG_SMP */
1352+4:
1353+ movl %edi,%ebx
1354+#endif
1355+5:
1356
1357 /*
1358 * Enable paging
1359@@ -228,9 +290,7 @@ ENTRY(startup_32_smp)
1360
1361 #ifdef CONFIG_SMP
1362 andl %ebx,%ebx
1363- jz 1f /* Initial CPU cleans BSS */
1364- jmp checkCPUtype
1365-1:
1366+ jnz checkCPUtype /* Initial CPU cleans BSS */
1367 #endif /* CONFIG_SMP */
1368
1369 /*
1370@@ -307,8 +367,6 @@ is386: movl $2,%ecx # set MP
1371 ljmp $(__KERNEL_CS),$1f
1372 1: movl $(__KERNEL_DS),%eax # reload all the segment registers
1373 movl %eax,%ss # after changing gdt.
1374-
1375- movl $(__USER_DS),%eax # DS/ES contains default USER segment
1376 movl %eax,%ds
1377 movl %eax,%es
1378
1379@@ -433,8 +491,8 @@ hlt_loop:
1380 /* This is the default interrupt "handler" :-) */
1381 ALIGN
1382 ignore_int:
1383- cld
1384 #ifdef CONFIG_PRINTK
1385+ cld
1386 pushl %eax
1387 pushl %ecx
1388 pushl %edx
1389@@ -465,32 +523,50 @@ ignore_int:
1390 #endif
1391 iret
1392
1393-/*
1394- * Real beginning of normal "text" segment
1395- */
1396-ENTRY(stext)
1397-ENTRY(_stext)
1398-
1399-/*
1400- * BSS section
1401- */
1402-.section ".bss.page_aligned","w"
1403+.section .swapper_pg_dir,"a",@progbits
1404 ENTRY(swapper_pg_dir)
1405+#ifdef CONFIG_X86_PAE
1406+ .long swapper_pm_dir-__PAGE_OFFSET+1
1407+ .long 0
1408+ .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1409+ .long 0
1410+ .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1411+ .long 0
1412+ .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1413+ .long 0
1414+#else
1415 .fill 1024,4,0
1416+#endif
1417+
1418+#ifdef CONFIG_X86_PAE
1419+.section .swapper_pm_dir,"a",@progbits
1420+ENTRY(swapper_pm_dir)
1421+ .fill 512,8,0
1422+ .fill 512,8,0
1423+ .fill 512,8,0
1424+ .fill 512,8,0
1425+#endif
1426+
1427+.section .empty_zero_page,"a",@progbits
1428 ENTRY(empty_zero_page)
1429 .fill 4096,1,0
1430
1431 /*
1432- * This starts the data section.
1433- */
1434-.data
1435+ * The IDT has to be page-aligned to simplify the Pentium
1436+ * F0 0F bug workaround.. We have a special link segment
1437+ * for this.
1438+ */
1439+.section .idt,"a",@progbits
1440+ENTRY(idt_table)
1441+ .fill 256,8,0
1442+
1443+.section .rodata,"a",@progbits
1444+ready: .byte 0
1445
1446 ENTRY(stack_start)
1447- .long init_thread_union+THREAD_SIZE
1448+ .long init_thread_union+THREAD_SIZE-8
1449 .long __BOOT_DS
1450
1451-ready: .byte 0
1452-
1453 early_recursion_flag:
1454 .long 0
1455
1456@@ -525,10 +601,12 @@ idt_descr:
1457
1458 # boot GDT descriptor (later on used by CPU#0):
1459 .word 0 # 32 bit align gdt_desc.address
1460-cpu_gdt_descr:
1461+ENTRY(cpu_gdt_descr)
1462 .word GDT_ENTRIES*8-1
1463 .long cpu_gdt_table
1464
1465+ .fill NR_CPUS*8-6,1,0 # space for the other GDT descriptors
1466+
1467 /*
1468 * The boot_gdt_table must mirror the equivalent in setup.S and is
1469 * used only for booting.
1470@@ -536,13 +614,13 @@ cpu_gdt_descr:
1471 .align L1_CACHE_BYTES
1472 ENTRY(boot_gdt_table)
1473 .fill GDT_ENTRY_BOOT_CS,8,0
1474- .quad 0x00cf9a000000ffff /* kernel 4GB code at 0x00000000 */
1475- .quad 0x00cf92000000ffff /* kernel 4GB data at 0x00000000 */
1476+ .quad 0x00cf9b000000ffff /* kernel 4GB code at 0x00000000 */
1477+ .quad 0x00cf93000000ffff /* kernel 4GB data at 0x00000000 */
1478
1479 /*
1480 * The Global Descriptor Table contains 28 quadwords, per-CPU.
1481 */
1482- .align L1_CACHE_BYTES
1483+ .align PAGE_SIZE_asm
1484 ENTRY(cpu_gdt_table)
1485 .quad 0x0000000000000000 /* NULL descriptor */
1486 .quad 0x0000000000000000 /* 0x0b reserved */
1487@@ -557,10 +635,10 @@ ENTRY(cpu_gdt_table)
1488 .quad 0x0000000000000000 /* 0x53 reserved */
1489 .quad 0x0000000000000000 /* 0x5b reserved */
1490
1491- .quad 0x00cf9a000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
1492- .quad 0x00cf92000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
1493- .quad 0x00cffa000000ffff /* 0x73 user 4GB code at 0x00000000 */
1494- .quad 0x00cff2000000ffff /* 0x7b user 4GB data at 0x00000000 */
1495+ .quad 0x00cf9b000000ffff /* 0x60 kernel 4GB code at 0x00000000 */
1496+ .quad 0x00cf93000000ffff /* 0x68 kernel 4GB data at 0x00000000 */
1497+ .quad 0x00cffb000000ffff /* 0x73 user 4GB code at 0x00000000 */
1498+ .quad 0x00cff3000000ffff /* 0x7b user 4GB data at 0x00000000 */
1499
1500 .quad 0x0000000000000000 /* 0x80 TSS descriptor */
1501 .quad 0x0000000000000000 /* 0x88 LDT descriptor */
1502@@ -570,24 +648,30 @@ ENTRY(cpu_gdt_table)
1503 * They code segments and data segments have fixed 64k limits,
1504 * the transfer segment sizes are set at run time.
1505 */
1506- .quad 0x00409a000000ffff /* 0x90 32-bit code */
1507- .quad 0x00009a000000ffff /* 0x98 16-bit code */
1508- .quad 0x000092000000ffff /* 0xa0 16-bit data */
1509- .quad 0x0000920000000000 /* 0xa8 16-bit data */
1510- .quad 0x0000920000000000 /* 0xb0 16-bit data */
1511+ .quad 0x00409b000000ffff /* 0x90 32-bit code */
1512+ .quad 0x00009b000000ffff /* 0x98 16-bit code */
1513+ .quad 0x000093000000ffff /* 0xa0 16-bit data */
1514+ .quad 0x0000930000000000 /* 0xa8 16-bit data */
1515+ .quad 0x0000930000000000 /* 0xb0 16-bit data */
1516
1517 /*
1518 * The APM segments have byte granularity and their bases
1519 * are set at run time. All have 64k limits.
1520 */
1521- .quad 0x00409a000000ffff /* 0xb8 APM CS code */
1522- .quad 0x00009a000000ffff /* 0xc0 APM CS 16 code (16 bit) */
1523- .quad 0x004092000000ffff /* 0xc8 APM DS data */
1524+ .quad 0x00409b000000ffff /* 0xb8 APM CS code */
1525+ .quad 0x00009b000000ffff /* 0xc0 APM CS 16 code (16 bit) */
1526+ .quad 0x004093000000ffff /* 0xc8 APM DS data */
1527
1528- .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */
1529+ .quad 0x0000930000000000 /* 0xd0 - ESPFIX 16-bit SS */
1530 .quad 0x0000000000000000 /* 0xd8 - unused */
1531 .quad 0x0000000000000000 /* 0xe0 - unused */
1532 .quad 0x0000000000000000 /* 0xe8 - unused */
1533 .quad 0x0000000000000000 /* 0xf0 - unused */
1534 .quad 0x0000000000000000 /* 0xf8 - GDT entry 31: double-fault TSS */
1535
1536+ /* Be sure this is zeroed to avoid false validations in Xen */
1537+ .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
1538+
1539+#ifdef CONFIG_SMP
1540+ .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
1541+#endif
1542diff -urNp linux-2.6.19.1/arch/i386/kernel/i386_ksyms.c linux-2.6.19.1/arch/i386/kernel/i386_ksyms.c
1543--- linux-2.6.19.1/arch/i386/kernel/i386_ksyms.c 2006-11-29 16:57:37.000000000 -0500
1544+++ linux-2.6.19.1/arch/i386/kernel/i386_ksyms.c 2006-12-03 15:15:45.000000000 -0500
1545@@ -2,12 +2,16 @@
1546 #include <asm/checksum.h>
1547 #include <asm/desc.h>
1548
1549+EXPORT_SYMBOL_GPL(cpu_gdt_table);
1550+
1551 EXPORT_SYMBOL(__down_failed);
1552 EXPORT_SYMBOL(__down_failed_interruptible);
1553 EXPORT_SYMBOL(__down_failed_trylock);
1554 EXPORT_SYMBOL(__up_wakeup);
1555 /* Networking helper routines. */
1556 EXPORT_SYMBOL(csum_partial_copy_generic);
1557+EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
1558+EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
1559
1560 EXPORT_SYMBOL(__get_user_1);
1561 EXPORT_SYMBOL(__get_user_2);
1562diff -urNp linux-2.6.19.1/arch/i386/kernel/init_task.c linux-2.6.19.1/arch/i386/kernel/init_task.c
1563--- linux-2.6.19.1/arch/i386/kernel/init_task.c 2006-11-29 16:57:37.000000000 -0500
1564+++ linux-2.6.19.1/arch/i386/kernel/init_task.c 2006-12-03 15:15:45.000000000 -0500
1565@@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
1566 * per-CPU TSS segments. Threads are completely 'soft' on Linux,
1567 * no more per-task TSS's.
1568 */
1569-DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
1570+struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
1571
1572diff -urNp linux-2.6.19.1/arch/i386/kernel/io_apic.c linux-2.6.19.1/arch/i386/kernel/io_apic.c
1573--- linux-2.6.19.1/arch/i386/kernel/io_apic.c 2006-11-29 16:57:37.000000000 -0500
1574+++ linux-2.6.19.1/arch/i386/kernel/io_apic.c 2006-12-03 15:15:45.000000000 -0500
1575@@ -350,8 +350,8 @@ static void set_ioapic_affinity_irq(unsi
1576 # define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
1577 # define Dprintk(x...) do { TDprintk(x); } while (0)
1578 # else
1579-# define TDprintk(x...)
1580-# define Dprintk(x...)
1581+# define TDprintk(x...) do {} while (0)
1582+# define Dprintk(x...) do {} while (0)
1583 # endif
1584
1585 #define IRQBALANCE_CHECK_ARCH -999
1586diff -urNp linux-2.6.19.1/arch/i386/kernel/ioport.c linux-2.6.19.1/arch/i386/kernel/ioport.c
1587--- linux-2.6.19.1/arch/i386/kernel/ioport.c 2006-11-29 16:57:37.000000000 -0500
1588+++ linux-2.6.19.1/arch/i386/kernel/ioport.c 2006-12-03 15:15:45.000000000 -0500
1589@@ -16,6 +16,7 @@
1590 #include <linux/stddef.h>
1591 #include <linux/slab.h>
1592 #include <linux/thread_info.h>
1593+#include <linux/grsecurity.h>
1594
1595 /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
1596 static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
1597@@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
1598
1599 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
1600 return -EINVAL;
1601+#ifdef CONFIG_GRKERNSEC_IO
1602+ if (turn_on) {
1603+ gr_handle_ioperm();
1604+#else
1605 if (turn_on && !capable(CAP_SYS_RAWIO))
1606+#endif
1607 return -EPERM;
1608-
1609+#ifdef CONFIG_GRKERNSEC_IO
1610+ }
1611+#endif
1612 /*
1613 * If it's the first ioperm() call in this thread's lifetime, set the
1614 * IO bitmap up. ioperm() is much less timing critical than clone(),
1615@@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
1616 * because the ->io_bitmap_max value must match the bitmap
1617 * contents:
1618 */
1619- tss = &per_cpu(init_tss, get_cpu());
1620+ tss = init_tss + get_cpu();
1621
1622 set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
1623
1624@@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
1625 return -EINVAL;
1626 /* Trying to gain more privileges? */
1627 if (level > old) {
1628+#ifdef CONFIG_GRKERNSEC_IO
1629+ gr_handle_iopl();
1630+ return -EPERM;
1631+#else
1632 if (!capable(CAP_SYS_RAWIO))
1633 return -EPERM;
1634+#endif
1635 }
1636 t->iopl = level << 12;
1637 regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
1638diff -urNp linux-2.6.19.1/arch/i386/kernel/irq.c linux-2.6.19.1/arch/i386/kernel/irq.c
1639--- linux-2.6.19.1/arch/i386/kernel/irq.c 2006-11-29 16:57:37.000000000 -0500
1640+++ linux-2.6.19.1/arch/i386/kernel/irq.c 2006-12-03 15:15:45.000000000 -0500
1641@@ -100,7 +100,7 @@ fastcall unsigned int do_IRQ(struct pt_r
1642 int arg1, arg2, ebx;
1643
1644 /* build the stack frame on the IRQ stack */
1645- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1646+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1647 irqctx->tinfo.task = curctx->tinfo.task;
1648 irqctx->tinfo.previous_esp = current_stack_pointer;
1649
1650@@ -137,10 +137,10 @@ fastcall unsigned int do_IRQ(struct pt_r
1651 * gcc's 3.0 and earlier don't handle that correctly.
1652 */
1653 static char softirq_stack[NR_CPUS * THREAD_SIZE]
1654- __attribute__((__aligned__(THREAD_SIZE)));
1655+ __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1656
1657 static char hardirq_stack[NR_CPUS * THREAD_SIZE]
1658- __attribute__((__aligned__(THREAD_SIZE)));
1659+ __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
1660
1661 /*
1662 * allocate per-cpu stacks for hardirq and for softirq processing
1663@@ -200,7 +200,7 @@ asmlinkage void do_softirq(void)
1664 irqctx->tinfo.previous_esp = current_stack_pointer;
1665
1666 /* build the stack frame on the softirq stack */
1667- isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
1668+ isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
1669
1670 asm volatile(
1671 " xchgl %%ebx,%%esp \n"
1672diff -urNp linux-2.6.19.1/arch/i386/kernel/kprobes.c linux-2.6.19.1/arch/i386/kernel/kprobes.c
1673--- linux-2.6.19.1/arch/i386/kernel/kprobes.c 2006-11-29 16:57:37.000000000 -0500
1674+++ linux-2.6.19.1/arch/i386/kernel/kprobes.c 2006-12-03 15:15:45.000000000 -0500
1675@@ -661,7 +661,7 @@ int __kprobes kprobe_exceptions_notify(s
1676 struct die_args *args = (struct die_args *)data;
1677 int ret = NOTIFY_DONE;
1678
1679- if (args->regs && user_mode_vm(args->regs))
1680+ if (args->regs && user_mode(args->regs))
1681 return ret;
1682
1683 switch (val) {
1684diff -urNp linux-2.6.19.1/arch/i386/kernel/ldt.c linux-2.6.19.1/arch/i386/kernel/ldt.c
1685--- linux-2.6.19.1/arch/i386/kernel/ldt.c 2006-11-29 16:57:37.000000000 -0500
1686+++ linux-2.6.19.1/arch/i386/kernel/ldt.c 2006-12-03 15:15:45.000000000 -0500
1687@@ -20,6 +20,9 @@
1688 #include <asm/desc.h>
1689 #include <asm/mmu_context.h>
1690
1691+const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
1692+ { 0, 0 }, { 0, 0 } };
1693+
1694 #ifdef CONFIG_SMP /* avoids "defined but not used" warnig */
1695 static void flush_ldt(void *null)
1696 {
1697@@ -103,6 +106,22 @@ int init_new_context(struct task_struct
1698 retval = copy_ldt(&mm->context, &old_mm->context);
1699 up(&old_mm->context.sem);
1700 }
1701+
1702+ if (tsk == current) {
1703+ mm->context.vdso = ~0UL;
1704+
1705+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
1706+ mm->context.user_cs_base = 0UL;
1707+ mm->context.user_cs_limit = ~0UL;
1708+
1709+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
1710+ cpus_clear(mm->context.cpu_user_cs_mask);
1711+#endif
1712+
1713+#endif
1714+
1715+ }
1716+
1717 return retval;
1718 }
1719
1720@@ -160,11 +179,11 @@ static int read_default_ldt(void __user
1721 {
1722 int err;
1723 unsigned long size;
1724- void *address;
1725+ const void *address;
1726
1727 err = 0;
1728 address = &default_ldt[0];
1729- size = 5*sizeof(struct desc_struct);
1730+ size = sizeof default_ldt;
1731 if (size > bytecount)
1732 size = bytecount;
1733
1734@@ -215,6 +234,13 @@ static int write_ldt(void __user * ptr,
1735 }
1736 }
1737
1738+#ifdef CONFIG_PAX_SEGMEXEC
1739+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
1740+ error = -EINVAL;
1741+ goto out_unlock;
1742+ }
1743+#endif
1744+
1745 entry_1 = LDT_entry_a(&ldt_info);
1746 entry_2 = LDT_entry_b(&ldt_info);
1747 if (oldmode)
1748diff -urNp linux-2.6.19.1/arch/i386/kernel/module.c linux-2.6.19.1/arch/i386/kernel/module.c
1749--- linux-2.6.19.1/arch/i386/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
1750+++ linux-2.6.19.1/arch/i386/kernel/module.c 2006-12-03 15:15:45.000000000 -0500
1751@@ -21,6 +21,7 @@
1752 #include <linux/fs.h>
1753 #include <linux/string.h>
1754 #include <linux/kernel.h>
1755+#include <asm/desc.h>
1756
1757 #if 0
1758 #define DEBUGP printk
1759@@ -32,9 +33,30 @@ void *module_alloc(unsigned long size)
1760 {
1761 if (size == 0)
1762 return NULL;
1763+
1764+#ifdef CONFIG_PAX_KERNEXEC
1765+ return vmalloc(size);
1766+#else
1767 return vmalloc_exec(size);
1768+#endif
1769+
1770 }
1771
1772+#ifdef CONFIG_PAX_KERNEXEC
1773+void *module_alloc_exec(unsigned long size)
1774+{
1775+ struct vm_struct *area;
1776+
1777+ if (size == 0)
1778+ return NULL;
1779+
1780+ area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
1781+ if (area)
1782+ return area->addr;
1783+
1784+ return NULL;
1785+}
1786+#endif
1787
1788 /* Free memory returned from module_alloc */
1789 void module_free(struct module *mod, void *module_region)
1790@@ -44,6 +66,45 @@ void module_free(struct module *mod, voi
1791 table entries. */
1792 }
1793
1794+#ifdef CONFIG_PAX_KERNEXEC
1795+void module_free_exec(struct module *mod, void *module_region)
1796+{
1797+ struct vm_struct **p, *tmp;
1798+
1799+ if (!module_region)
1800+ return;
1801+
1802+ if ((PAGE_SIZE-1) & (unsigned long)module_region) {
1803+ printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
1804+ WARN_ON(1);
1805+ return;
1806+ }
1807+
1808+ write_lock(&vmlist_lock);
1809+ for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
1810+ if (tmp->addr == module_region)
1811+ break;
1812+
1813+ if (tmp) {
1814+ unsigned long cr0;
1815+
1816+ pax_open_kernel(cr0);
1817+ memset(tmp->addr, 0xCC, tmp->size);
1818+ pax_close_kernel(cr0);
1819+
1820+ *p = tmp->next;
1821+ kfree(tmp);
1822+ }
1823+ write_unlock(&vmlist_lock);
1824+
1825+ if (!tmp) {
1826+ printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
1827+ module_region);
1828+ WARN_ON(1);
1829+ }
1830+}
1831+#endif
1832+
1833 /* We don't need anything special. */
1834 int module_frob_arch_sections(Elf_Ehdr *hdr,
1835 Elf_Shdr *sechdrs,
1836@@ -62,14 +123,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1837 unsigned int i;
1838 Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
1839 Elf32_Sym *sym;
1840- uint32_t *location;
1841+ uint32_t *plocation, location;
1842
1843 DEBUGP("Applying relocate section %u to %u\n", relsec,
1844 sechdrs[relsec].sh_info);
1845 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
1846 /* This is where to make the change */
1847- location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
1848- + rel[i].r_offset;
1849+ plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
1850+ location = (uint32_t)plocation;
1851+ if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
1852+ plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
1853 /* This is the symbol it is referring to. Note that all
1854 undefined symbols have been resolved. */
1855 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
1856@@ -78,11 +141,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
1857 switch (ELF32_R_TYPE(rel[i].r_info)) {
1858 case R_386_32:
1859 /* We add the value into the location given */
1860- *location += sym->st_value;
1861+ *plocation += sym->st_value;
1862 break;
1863 case R_386_PC32:
1864 /* Add the value, subtract its postition */
1865- *location += sym->st_value - (uint32_t)location;
1866+ *plocation += sym->st_value - location;
1867 break;
1868 default:
1869 printk(KERN_ERR "module %s: Unknown relocation: %u\n",
1870diff -urNp linux-2.6.19.1/arch/i386/kernel/process.c linux-2.6.19.1/arch/i386/kernel/process.c
1871--- linux-2.6.19.1/arch/i386/kernel/process.c 2006-11-29 16:57:37.000000000 -0500
1872+++ linux-2.6.19.1/arch/i386/kernel/process.c 2006-12-03 15:15:45.000000000 -0500
1873@@ -69,7 +69,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
1874 */
1875 unsigned long thread_saved_pc(struct task_struct *tsk)
1876 {
1877- return ((unsigned long *)tsk->thread.esp)[3];
1878+ return tsk->thread.eip;
1879 }
1880
1881 /*
1882@@ -304,7 +304,7 @@ void show_regs(struct pt_regs * regs)
1883 printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id());
1884 print_symbol("EIP is at %s\n", regs->eip);
1885
1886- if (user_mode_vm(regs))
1887+ if (user_mode(regs))
1888 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
1889 printk(" EFLAGS: %08lx %s (%s %.*s)\n",
1890 regs->eflags, print_tainted(), init_utsname()->release,
1891@@ -344,8 +344,8 @@ int kernel_thread(int (*fn)(void *), voi
1892 regs.ebx = (unsigned long) fn;
1893 regs.edx = (unsigned long) arg;
1894
1895- regs.xds = __USER_DS;
1896- regs.xes = __USER_DS;
1897+ regs.xds = __KERNEL_DS;
1898+ regs.xes = __KERNEL_DS;
1899 regs.orig_eax = -1;
1900 regs.eip = (unsigned long) kernel_thread_helper;
1901 regs.xcs = __KERNEL_CS | get_kernel_rpl();
1902@@ -366,7 +366,7 @@ void exit_thread(void)
1903 struct task_struct *tsk = current;
1904 struct thread_struct *t = &tsk->thread;
1905 int cpu = get_cpu();
1906- struct tss_struct *tss = &per_cpu(init_tss, cpu);
1907+ struct tss_struct *tss = init_tss + cpu;
1908
1909 kfree(t->io_bitmap_ptr);
1910 t->io_bitmap_ptr = NULL;
1911@@ -387,6 +387,9 @@ void flush_thread(void)
1912 {
1913 struct task_struct *tsk = current;
1914
1915+ __asm__("mov %0,%%fs\n"
1916+ "mov %0,%%gs\n"
1917+ : : "r" (0) : "memory");
1918 memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
1919 memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));
1920 clear_tsk_thread_flag(tsk, TIF_DEBUG);
1921@@ -420,7 +423,7 @@ int copy_thread(int nr, unsigned long cl
1922 struct task_struct *tsk;
1923 int err;
1924
1925- childregs = task_pt_regs(p);
1926+ childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
1927 *childregs = *regs;
1928 childregs->eax = 0;
1929 childregs->esp = esp;
1930@@ -463,6 +466,11 @@ int copy_thread(int nr, unsigned long cl
1931 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
1932 goto out;
1933
1934+#ifdef CONFIG_PAX_SEGMEXEC
1935+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1936+ goto out;
1937+#endif
1938+
1939 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
1940 desc->a = LDT_entry_a(&info);
1941 desc->b = LDT_entry_b(&info);
1942@@ -642,7 +650,11 @@ struct task_struct fastcall * __switch_t
1943 struct thread_struct *prev = &prev_p->thread,
1944 *next = &next_p->thread;
1945 int cpu = smp_processor_id();
1946- struct tss_struct *tss = &per_cpu(init_tss, cpu);
1947+ struct tss_struct *tss = init_tss + cpu;
1948+
1949+#ifdef CONFIG_PAX_KERNEXEC
1950+ unsigned long cr0;
1951+#endif
1952
1953 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
1954
1955@@ -665,11 +677,24 @@ struct task_struct fastcall * __switch_t
1956 savesegment(fs, prev->fs);
1957 savesegment(gs, prev->gs);
1958
1959+#ifdef CONFIG_PAX_KERNEXEC
1960+ pax_open_kernel(cr0);
1961+#endif
1962+
1963+#ifdef CONFIG_PAX_MEMORY_UDEREF
1964+ if (!segment_eq(prev_p->thread_info->addr_limit, next_p->thread_info->addr_limit))
1965+ __set_fs(next_p->thread_info->addr_limit, cpu);
1966+#endif
1967+
1968 /*
1969 * Load the per-thread Thread-Local Storage descriptor.
1970 */
1971 load_TLS(next, cpu);
1972
1973+#ifdef CONFIG_PAX_KERNEXEC
1974+ pax_close_kernel(cr0);
1975+#endif
1976+
1977 /*
1978 * Restore %fs and %gs if needed.
1979 *
1980@@ -814,8 +839,18 @@ asmlinkage int sys_set_thread_area(struc
1981 struct desc_struct *desc;
1982 int cpu, idx;
1983
1984+#ifdef CONFIG_PAX_KERNEXEC
1985+ unsigned long cr0;
1986+#endif
1987+
1988 if (copy_from_user(&info, u_info, sizeof(info)))
1989 return -EFAULT;
1990+
1991+#ifdef CONFIG_PAX_SEGMEXEC
1992+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
1993+ return -EINVAL;
1994+#endif
1995+
1996 idx = info.entry_number;
1997
1998 /*
1999@@ -847,8 +882,17 @@ asmlinkage int sys_set_thread_area(struc
2000 desc->a = LDT_entry_a(&info);
2001 desc->b = LDT_entry_b(&info);
2002 }
2003+
2004+#ifdef CONFIG_PAX_KERNEXEC
2005+ pax_open_kernel(cr0);
2006+#endif
2007+
2008 load_TLS(t, cpu);
2009
2010+#ifdef CONFIG_PAX_KERNEXEC
2011+ pax_close_kernel(cr0);
2012+#endif
2013+
2014 put_cpu();
2015
2016 return 0;
2017@@ -904,9 +948,27 @@ asmlinkage int sys_get_thread_area(struc
2018 return 0;
2019 }
2020
2021-unsigned long arch_align_stack(unsigned long sp)
2022+#ifdef CONFIG_PAX_RANDKSTACK
2023+asmlinkage void pax_randomize_kstack(void)
2024 {
2025- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
2026- sp -= get_random_int() % 8192;
2027- return sp & ~0xf;
2028+ struct tss_struct *tss = init_tss + smp_processor_id();
2029+ unsigned long time;
2030+
2031+ if (!randomize_va_space)
2032+ return;
2033+
2034+ rdtscl(time);
2035+
2036+ /* P4 seems to return a 0 LSB, ignore it */
2037+#ifdef CONFIG_MPENTIUM4
2038+ time &= 0x1EUL;
2039+ time <<= 2;
2040+#else
2041+ time &= 0xFUL;
2042+ time <<= 3;
2043+#endif
2044+
2045+ tss->esp0 ^= time;
2046+ current->thread.esp0 = tss->esp0;
2047 }
2048+#endif
2049diff -urNp linux-2.6.19.1/arch/i386/kernel/ptrace.c linux-2.6.19.1/arch/i386/kernel/ptrace.c
2050--- linux-2.6.19.1/arch/i386/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
2051+++ linux-2.6.19.1/arch/i386/kernel/ptrace.c 2006-12-03 15:15:45.000000000 -0500
2052@@ -17,6 +17,7 @@
2053 #include <linux/audit.h>
2054 #include <linux/seccomp.h>
2055 #include <linux/signal.h>
2056+#include <linux/grsecurity.h>
2057
2058 #include <asm/uaccess.h>
2059 #include <asm/pgtable.h>
2060@@ -169,15 +170,15 @@ static unsigned long convert_eip_to_line
2061 * and APM bios ones we just ignore here.
2062 */
2063 if (seg & LDT_SEGMENT) {
2064- u32 *desc;
2065+ struct desc_struct *desc;
2066 unsigned long base;
2067
2068 down(&child->mm->context.sem);
2069- desc = child->mm->context.ldt + (seg & ~7);
2070- base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
2071+ desc = &child->mm->context.ldt[seg >> 3];
2072+ base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
2073
2074 /* 16-bit code segment? */
2075- if (!((desc[1] >> 22) & 1))
2076+ if (!((desc->b >> 22) & 1))
2077 addr &= 0xffff;
2078 addr += base;
2079 up(&child->mm->context.sem);
2080@@ -342,6 +343,11 @@ ptrace_set_thread_area(struct task_struc
2081 if (copy_from_user(&info, user_desc, sizeof(info)))
2082 return -EFAULT;
2083
2084+#ifdef CONFIG_PAX_SEGMEXEC
2085+ if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2086+ return -EINVAL;
2087+#endif
2088+
2089 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2090 return -EINVAL;
2091
2092@@ -432,6 +438,17 @@ long arch_ptrace(struct task_struct *chi
2093 if(addr == (long) &dummy->u_debugreg[5]) break;
2094 if(addr < (long) &dummy->u_debugreg[4] &&
2095 ((unsigned long) data) >= TASK_SIZE-3) break;
2096+
2097+#ifdef CONFIG_GRKERNSEC
2098+ if(addr >= (long) &dummy->u_debugreg[0] &&
2099+ addr <= (long) &dummy->u_debugreg[3]){
2100+ long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2;
2101+ long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
2102+ long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
2103+ if((type & 1) && (data & align))
2104+ break;
2105+ }
2106+#endif
2107
2108 /* Sanity-check data. Take one half-byte at once with
2109 * check = (val >> (16 + 4*i)) & 0xf. It contains the
2110@@ -648,7 +665,7 @@ void send_sigtrap(struct task_struct *ts
2111 info.si_code = TRAP_BRKPT;
2112
2113 /* User-mode eip? */
2114- info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2115+ info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2116
2117 /* Send us the fakey SIGTRAP */
2118 force_sig_info(SIGTRAP, &info, tsk);
2119diff -urNp linux-2.6.19.1/arch/i386/kernel/reboot.c linux-2.6.19.1/arch/i386/kernel/reboot.c
2120--- linux-2.6.19.1/arch/i386/kernel/reboot.c 2006-11-29 16:57:37.000000000 -0500
2121+++ linux-2.6.19.1/arch/i386/kernel/reboot.c 2006-12-03 15:15:45.000000000 -0500
2122@@ -24,7 +24,7 @@
2123 void (*pm_power_off)(void);
2124 EXPORT_SYMBOL(pm_power_off);
2125
2126-static int reboot_mode;
2127+static unsigned short reboot_mode;
2128 static int reboot_thru_bios;
2129
2130 #ifdef CONFIG_SMP
2131@@ -137,15 +137,15 @@ core_initcall(reboot_init);
2132 doesn't work with at least one type of 486 motherboard. It is easy
2133 to stop this code working; hence the copious comments. */
2134
2135-static unsigned long long
2136+static const unsigned long long
2137 real_mode_gdt_entries [3] =
2138 {
2139 0x0000000000000000ULL, /* Null descriptor */
2140- 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2141- 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2142+ 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
2143+ 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
2144 };
2145
2146-static struct Xgt_desc_struct
2147+static const struct Xgt_desc_struct
2148 real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
2149 real_mode_idt = { 0x3ff, 0 },
2150 no_idt = { 0, 0 };
2151@@ -170,7 +170,7 @@ no_idt = { 0, 0 };
2152 More could be done here to set up the registers as if a CPU reset had
2153 occurred; hopefully real BIOSs don't assume much. */
2154
2155-static unsigned char real_mode_switch [] =
2156+static const unsigned char real_mode_switch [] =
2157 {
2158 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
2159 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */
2160@@ -184,7 +184,7 @@ static unsigned char real_mode_switch []
2161 0x24, 0x10, /* f: andb $0x10,al */
2162 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
2163 };
2164-static unsigned char jump_to_bios [] =
2165+static const unsigned char jump_to_bios [] =
2166 {
2167 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */
2168 };
2169@@ -194,10 +194,14 @@ static unsigned char jump_to_bios [] =
2170 * specified by the code and length parameters.
2171 * We assume that length will aways be less that 100!
2172 */
2173-void machine_real_restart(unsigned char *code, int length)
2174+void machine_real_restart(const unsigned char *code, unsigned int length)
2175 {
2176 unsigned long flags;
2177
2178+#ifdef CONFIG_PAX_KERNEXEC
2179+ unsigned long cr0;
2180+#endif
2181+
2182 local_irq_disable();
2183
2184 /* Write zero to CMOS register number 0x0f, which the BIOS POST
2185@@ -218,8 +222,16 @@ void machine_real_restart(unsigned char
2186 from the kernel segment. This assumes the kernel segment starts at
2187 virtual address PAGE_OFFSET. */
2188
2189- memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2190- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2191+#ifdef CONFIG_PAX_KERNEXEC
2192+ pax_open_kernel(cr0);
2193+#endif
2194+
2195+ clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2196+ USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
2197+
2198+#ifdef CONFIG_PAX_KERNEXEC
2199+ pax_close_kernel(cr0);
2200+#endif
2201
2202 /*
2203 * Use `swapper_pg_dir' as our page directory.
2204@@ -232,7 +244,7 @@ void machine_real_restart(unsigned char
2205 REBOOT.COM programs, and the previous reset routine did this
2206 too. */
2207
2208- *((unsigned short *)0x472) = reboot_mode;
2209+ __put_user(reboot_mode, (unsigned short __user *)0x472);
2210
2211 /* For the switch to real mode, copy some code to low memory. It has
2212 to be in the first 64k because it is running in 16-bit mode, and it
2213@@ -240,9 +252,9 @@ void machine_real_restart(unsigned char
2214 off paging. Copy it near the end of the first page, out of the way
2215 of BIOS variables. */
2216
2217- memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2218+ flags = __copy_to_user ((void __user *) (0x1000 - sizeof (real_mode_switch) - 100),
2219 real_mode_switch, sizeof (real_mode_switch));
2220- memcpy ((void *) (0x1000 - 100), code, length);
2221+ flags = __copy_to_user ((void __user *) (0x1000 - 100), code, length);
2222
2223 /* Set up the IDT for real mode. */
2224
2225@@ -324,7 +336,7 @@ void machine_emergency_restart(void)
2226 __asm__ __volatile__("int3");
2227 }
2228 /* rebooting needs to touch the page at absolute addr 0 */
2229- *((unsigned short *)__va(0x472)) = reboot_mode;
2230+ __put_user(reboot_mode, (unsigned short __user *)0x472);
2231 for (;;) {
2232 mach_reboot_fixups(); /* for board specific fixups */
2233 mach_reboot();
2234diff -urNp linux-2.6.19.1/arch/i386/kernel/setup.c linux-2.6.19.1/arch/i386/kernel/setup.c
2235--- linux-2.6.19.1/arch/i386/kernel/setup.c 2006-11-29 16:57:37.000000000 -0500
2236+++ linux-2.6.19.1/arch/i386/kernel/setup.c 2006-12-03 15:15:45.000000000 -0500
2237@@ -88,7 +88,11 @@ struct cpuinfo_x86 new_cpu_data __initda
2238 struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2239 EXPORT_SYMBOL(boot_cpu_data);
2240
2241+#ifdef CONFIG_X86_PAE
2242+unsigned long mmu_cr4_features = X86_CR4_PAE;
2243+#else
2244 unsigned long mmu_cr4_features;
2245+#endif
2246
2247 /* for MCA, but anyone else can use it if they want */
2248 unsigned int machine_id;
2249@@ -1388,14 +1392,14 @@ void __init setup_arch(char **cmdline_p)
2250
2251 if (!MOUNT_ROOT_RDONLY)
2252 root_mountflags &= ~MS_RDONLY;
2253- init_mm.start_code = (unsigned long) _text;
2254- init_mm.end_code = (unsigned long) _etext;
2255+ init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2256+ init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2257 init_mm.end_data = (unsigned long) _edata;
2258 init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2259
2260- code_resource.start = virt_to_phys(_text);
2261- code_resource.end = virt_to_phys(_etext)-1;
2262- data_resource.start = virt_to_phys(_etext);
2263+ code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2264+ code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2265+ data_resource.start = virt_to_phys(_data);
2266 data_resource.end = virt_to_phys(_edata)-1;
2267
2268 parse_early_param();
2269diff -urNp linux-2.6.19.1/arch/i386/kernel/signal.c linux-2.6.19.1/arch/i386/kernel/signal.c
2270--- linux-2.6.19.1/arch/i386/kernel/signal.c 2006-11-29 16:57:37.000000000 -0500
2271+++ linux-2.6.19.1/arch/i386/kernel/signal.c 2006-12-03 15:15:45.000000000 -0500
2272@@ -351,7 +351,7 @@ static int setup_frame(int sig, struct k
2273 goto give_sigsegv;
2274 }
2275
2276- restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
2277+ restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
2278 if (ka->sa.sa_flags & SA_RESTORER)
2279 restorer = ka->sa.sa_restorer;
2280
2281@@ -447,7 +447,8 @@ static int setup_rt_frame(int sig, struc
2282 goto give_sigsegv;
2283
2284 /* Set up to return from userspace. */
2285- restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
2286+
2287+ restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
2288 if (ka->sa.sa_flags & SA_RESTORER)
2289 restorer = ka->sa.sa_restorer;
2290 err |= __put_user(restorer, &frame->pretcode);
2291@@ -580,7 +581,7 @@ static void fastcall do_signal(struct pt
2292 * before reaching here, so testing against kernel
2293 * CS suffices.
2294 */
2295- if (!user_mode(regs))
2296+ if (!user_mode_novm(regs))
2297 return;
2298
2299 if (test_thread_flag(TIF_RESTORE_SIGMASK))
2300diff -urNp linux-2.6.19.1/arch/i386/kernel/smpboot.c linux-2.6.19.1/arch/i386/kernel/smpboot.c
2301--- linux-2.6.19.1/arch/i386/kernel/smpboot.c 2006-11-29 16:57:37.000000000 -0500
2302+++ linux-2.6.19.1/arch/i386/kernel/smpboot.c 2006-12-03 15:15:45.000000000 -0500
2303@@ -1066,7 +1066,6 @@ static int __cpuinit __smp_prepare_cpu(i
2304 struct warm_boot_cpu_info info;
2305 struct work_struct task;
2306 int apicid, ret;
2307- struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
2308
2309 apicid = x86_cpu_to_apicid[cpu];
2310 if (apicid == BAD_APICID) {
2311@@ -1078,13 +1077,7 @@ static int __cpuinit __smp_prepare_cpu(i
2312 * the CPU isn't initialized at boot time, allocate gdt table here.
2313 * cpu_init will initialize it
2314 */
2315- if (!cpu_gdt_descr->address) {
2316- cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL);
2317- if (!cpu_gdt_descr->address)
2318- printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
2319- ret = -ENOMEM;
2320- goto exit;
2321- }
2322+ cpu_gdt_descr[cpu].address = get_cpu_gdt_table(cpu);
2323
2324 info.complete = &done;
2325 info.apicid = apicid;
2326@@ -1095,7 +1088,7 @@ static int __cpuinit __smp_prepare_cpu(i
2327
2328 /* init low mem mapping */
2329 clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2330- KERNEL_PGD_PTRS);
2331+ USER_PGD_PTRS >= KERNEL_PGD_PTRS ? KERNEL_PGD_PTRS : USER_PGD_PTRS);
2332 flush_tlb_all();
2333 schedule_work(&task);
2334 wait_for_completion(&done);
2335diff -urNp linux-2.6.19.1/arch/i386/kernel/syscall_table.S linux-2.6.19.1/arch/i386/kernel/syscall_table.S
2336--- linux-2.6.19.1/arch/i386/kernel/syscall_table.S 2006-11-29 16:57:37.000000000 -0500
2337+++ linux-2.6.19.1/arch/i386/kernel/syscall_table.S 2006-12-03 15:15:45.000000000 -0500
2338@@ -1,3 +1,4 @@
2339+.section .rodata,"a",@progbits
2340 ENTRY(sys_call_table)
2341 .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
2342 .long sys_exit
2343diff -urNp linux-2.6.19.1/arch/i386/kernel/sysenter.c linux-2.6.19.1/arch/i386/kernel/sysenter.c
2344--- linux-2.6.19.1/arch/i386/kernel/sysenter.c 2006-11-29 16:57:37.000000000 -0500
2345+++ linux-2.6.19.1/arch/i386/kernel/sysenter.c 2006-12-03 15:15:45.000000000 -0500
2346@@ -45,7 +45,7 @@ extern asmlinkage void sysenter_entry(vo
2347 void enable_sep_cpu(void)
2348 {
2349 int cpu = get_cpu();
2350- struct tss_struct *tss = &per_cpu(init_tss, cpu);
2351+ struct tss_struct *tss = init_tss + cpu;
2352
2353 if (!boot_cpu_has(X86_FEATURE_SEP)) {
2354 put_cpu();
2355@@ -125,16 +125,36 @@ int arch_setup_additional_pages(struct l
2356 unsigned long addr;
2357 int ret;
2358
2359+#ifdef CONFIG_PAX_SEGMEXEC
2360+ struct vm_area_struct *vma_m = NULL;
2361+#endif
2362+
2363+ vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
2364+ if (!vma)
2365+ return -ENOMEM;
2366+
2367+#ifdef CONFIG_PAX_SEGMEXEC
2368+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
2369+ vma_m = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
2370+ if (!vma_m) {
2371+ kmem_cache_free(vm_area_cachep, vma);
2372+ return -ENOMEM;
2373+ }
2374+ }
2375+#endif
2376+
2377 down_write(&mm->mmap_sem);
2378- addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
2379+ addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
2380 if (IS_ERR_VALUE(addr)) {
2381 ret = addr;
2382- goto up_fail;
2383- }
2384
2385- vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
2386- if (!vma) {
2387- ret = -ENOMEM;
2388+ kmem_cache_free(vm_area_cachep, vma);
2389+
2390+#ifdef CONFIG_PAX_SEGMEXEC
2391+ if (vma_m)
2392+ kmem_cache_free(vm_area_cachep, vma_m);
2393+#endif
2394+
2395 goto up_fail;
2396 }
2397
2398@@ -142,18 +162,49 @@ int arch_setup_additional_pages(struct l
2399 vma->vm_end = addr + PAGE_SIZE;
2400 /* MAYWRITE to allow gdb to COW and set breakpoints */
2401 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
2402+
2403+#ifdef CONFIG_PAX_MPROTECT
2404+ if (mm->pax_flags & MF_PAX_MPROTECT)
2405+ vma->vm_flags &= ~VM_MAYWRITE;
2406+#endif
2407+
2408 vma->vm_flags |= mm->def_flags;
2409- vma->vm_page_prot = protection_map[vma->vm_flags & 7];
2410+ vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
2411 vma->vm_ops = &syscall_vm_ops;
2412 vma->vm_mm = mm;
2413
2414 ret = insert_vm_struct(mm, vma);
2415 if (unlikely(ret)) {
2416 kmem_cache_free(vm_area_cachep, vma);
2417+
2418+#ifdef CONFIG_PAX_SEGMEXEC
2419+ if (vma_m)
2420+ kmem_cache_free(vm_area_cachep, vma_m);
2421+#endif
2422+
2423 goto up_fail;
2424 }
2425
2426- current->mm->context.vdso = (void *)addr;
2427+#ifdef CONFIG_PAX_SEGMEXEC
2428+ if (vma_m) {
2429+ *vma_m = *vma;
2430+ vma_m->vm_start += SEGMEXEC_TASK_SIZE;
2431+ vma_m->vm_end += SEGMEXEC_TASK_SIZE;
2432+ ret = insert_vm_struct(mm, vma_m);
2433+ if (unlikely(ret)) {
2434+ kmem_cache_free(vm_area_cachep, vma_m);
2435+ goto up_fail;
2436+ }
2437+ vma_m->vm_flags |= VM_MIRROR;
2438+ vma->vm_flags |= VM_MIRROR;
2439+ vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
2440+ vma->vm_mirror = vma_m->vm_start - vma->vm_start;
2441+ vma_m->vm_pgoff = vma->vm_pgoff;
2442+ mm->total_vm++;
2443+ }
2444+#endif
2445+
2446+ current->mm->context.vdso = addr;
2447 current_thread_info()->sysenter_return =
2448 (void *)VDSO_SYM(&SYSENTER_RETURN);
2449 mm->total_vm++;
2450@@ -164,8 +215,17 @@ up_fail:
2451
2452 const char *arch_vma_name(struct vm_area_struct *vma)
2453 {
2454- if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
2455+ if (vma->vm_start == vma->vm_mm->context.vdso)
2456 return "[vdso]";
2457+
2458+#ifdef CONFIG_PAX_SEGMEXEC
2459+ if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_MIRROR))
2460+ return NULL;
2461+
2462+ if (vma->vm_start + vma->vm_mirror == vma->vm_mm->context.vdso)
2463+ return "[vdso]";
2464+#endif
2465+
2466 return NULL;
2467 }
2468
2469diff -urNp linux-2.6.19.1/arch/i386/kernel/sys_i386.c linux-2.6.19.1/arch/i386/kernel/sys_i386.c
2470--- linux-2.6.19.1/arch/i386/kernel/sys_i386.c 2006-11-29 16:57:37.000000000 -0500
2471+++ linux-2.6.19.1/arch/i386/kernel/sys_i386.c 2006-12-03 15:15:45.000000000 -0500
2472@@ -100,6 +100,191 @@ out:
2473 return err;
2474 }
2475
2476+unsigned long
2477+arch_get_unmapped_area(struct file *filp, unsigned long addr,
2478+ unsigned long len, unsigned long pgoff, unsigned long flags)
2479+{
2480+ struct mm_struct *mm = current->mm;
2481+ struct vm_area_struct *vma;
2482+ unsigned long start_addr, task_size = TASK_SIZE;
2483+
2484+#ifdef CONFIG_PAX_SEGMEXEC
2485+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
2486+ task_size = SEGMEXEC_TASK_SIZE;
2487+#endif
2488+
2489+ if (len > task_size)
2490+ return -ENOMEM;
2491+
2492+#ifdef CONFIG_PAX_RANDMMAP
2493+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2494+#endif
2495+
2496+ if (addr) {
2497+ addr = PAGE_ALIGN(addr);
2498+ vma = find_vma(mm, addr);
2499+ if (task_size - len >= addr &&
2500+ (!vma || addr + len <= vma->vm_start))
2501+ return addr;
2502+ }
2503+ if (len > mm->cached_hole_size) {
2504+ start_addr = addr = mm->free_area_cache;
2505+ } else {
2506+ start_addr = addr = mm->mmap_base;
2507+ mm->cached_hole_size = 0;
2508+ }
2509+
2510+#ifdef CONFIG_PAX_PAGEEXEC
2511+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
2512+ start_addr = 0x00110000UL;
2513+
2514+#ifdef CONFIG_PAX_RANDMMAP
2515+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2516+ start_addr += mm->delta_mmap & 0x03FFF000UL;
2517+#endif
2518+
2519+ if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
2520+ start_addr = addr = mm->mmap_base;
2521+ else
2522+ addr = start_addr;
2523+ }
2524+#endif
2525+
2526+full_search:
2527+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
2528+ /* At this point: (!vma || addr < vma->vm_end). */
2529+ if (task_size - len < addr) {
2530+ /*
2531+ * Start a new search - just in case we missed
2532+ * some holes.
2533+ */
2534+ if (start_addr != mm->mmap_base) {
2535+ start_addr = addr = mm->mmap_base;
2536+ mm->cached_hole_size = 0;
2537+ goto full_search;
2538+ }
2539+ return -ENOMEM;
2540+ }
2541+ if (!vma || addr + len <= vma->vm_start) {
2542+ /*
2543+ * Remember the place where we stopped the search:
2544+ */
2545+ mm->free_area_cache = addr + len;
2546+ return addr;
2547+ }
2548+ if (addr + mm->cached_hole_size < vma->vm_start)
2549+ mm->cached_hole_size = vma->vm_start - addr;
2550+ addr = vma->vm_end;
2551+ if (mm->start_brk <= addr && addr < mm->mmap_base) {
2552+ start_addr = addr = mm->mmap_base;
2553+ goto full_search;
2554+ }
2555+ }
2556+}
2557+
2558+unsigned long
2559+arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
2560+ const unsigned long len, const unsigned long pgoff,
2561+ const unsigned long flags)
2562+{
2563+ struct vm_area_struct *vma;
2564+ struct mm_struct *mm = current->mm;
2565+ unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
2566+
2567+#ifdef CONFIG_PAX_SEGMEXEC
2568+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
2569+ task_size = SEGMEXEC_TASK_SIZE;
2570+#endif
2571+
2572+ /* requested length too big for entire address space */
2573+ if (len > task_size)
2574+ return -ENOMEM;
2575+
2576+#ifdef CONFIG_PAX_PAGEEXEC
2577+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
2578+ goto bottomup;
2579+#endif
2580+
2581+#ifdef CONFIG_PAX_RANDMMAP
2582+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2583+#endif
2584+
2585+ /* requesting a specific address */
2586+ if (addr) {
2587+ addr = PAGE_ALIGN(addr);
2588+ vma = find_vma(mm, addr);
2589+ if (task_size - len >= addr &&
2590+ (!vma || addr + len <= vma->vm_start))
2591+ return addr;
2592+ }
2593+
2594+ /* check if free_area_cache is useful for us */
2595+ if (len <= mm->cached_hole_size) {
2596+ mm->cached_hole_size = 0;
2597+ mm->free_area_cache = mm->mmap_base;
2598+ }
2599+
2600+ /* either no address requested or can't fit in requested address hole */
2601+ addr = mm->free_area_cache;
2602+
2603+ /* make sure it can fit in the remaining address space */
2604+ if (addr > len) {
2605+ vma = find_vma(mm, addr-len);
2606+ if (!vma || addr <= vma->vm_start)
2607+ /* remember the address as a hint for next time */
2608+ return (mm->free_area_cache = addr-len);
2609+ }
2610+
2611+ if (mm->mmap_base < len)
2612+ goto bottomup;
2613+
2614+ addr = mm->mmap_base-len;
2615+
2616+ do {
2617+ /*
2618+ * Lookup failure means no vma is above this address,
2619+ * else if new region fits below vma->vm_start,
2620+ * return with success:
2621+ */
2622+ vma = find_vma(mm, addr);
2623+ if (!vma || addr+len <= vma->vm_start)
2624+ /* remember the address as a hint for next time */
2625+ return (mm->free_area_cache = addr);
2626+
2627+ /* remember the largest hole we saw so far */
2628+ if (addr + mm->cached_hole_size < vma->vm_start)
2629+ mm->cached_hole_size = vma->vm_start - addr;
2630+
2631+ /* try just below the current vma->vm_start */
2632+ addr = vma->vm_start-len;
2633+ } while (len < vma->vm_start);
2634+
2635+bottomup:
2636+ /*
2637+ * A failed mmap() very likely causes application failure,
2638+ * so fall back to the bottom-up function here. This scenario
2639+ * can happen with large stack limits and large mmap()
2640+ * allocations.
2641+ */
2642+ mm->mmap_base = TASK_UNMAPPED_BASE;
2643+
2644+#ifdef CONFIG_PAX_RANDMMAP
2645+ if (mm->pax_flags & MF_PAX_RANDMMAP)
2646+ mm->mmap_base += mm->delta_mmap;
2647+#endif
2648+
2649+ mm->free_area_cache = mm->mmap_base;
2650+ mm->cached_hole_size = ~0UL;
2651+ addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
2652+ /*
2653+ * Restore the topdown base:
2654+ */
2655+ mm->mmap_base = base;
2656+ mm->free_area_cache = base;
2657+ mm->cached_hole_size = ~0UL;
2658+
2659+ return addr;
2660+}
2661
2662 struct sel_arg_struct {
2663 unsigned long n;
2664diff -urNp linux-2.6.19.1/arch/i386/kernel/time.c linux-2.6.19.1/arch/i386/kernel/time.c
2665--- linux-2.6.19.1/arch/i386/kernel/time.c 2006-11-29 16:57:37.000000000 -0500
2666+++ linux-2.6.19.1/arch/i386/kernel/time.c 2006-12-10 21:43:36.000000000 -0500
2667@@ -133,7 +133,7 @@ unsigned long profile_pc(struct pt_regs
2668 unsigned long pc = instruction_pointer(regs);
2669
2670 #ifdef CONFIG_SMP
2671- if (!user_mode_vm(regs) && in_lock_functions(pc)) {
2672+ if (!user_mode(regs) && in_lock_functions(pc)) {
2673 #ifdef CONFIG_FRAME_POINTER
2674 return *(unsigned long *)(regs->ebp + 4);
2675 #else
2676@@ -345,7 +345,7 @@ static struct sys_device device_timer =
2677 .cls = &timer_sysclass,
2678 };
2679
2680-static int time_init_device(void)
2681+static int __init time_init_device(void)
2682 {
2683 int error = sysdev_class_register(&timer_sysclass);
2684 if (!error)
2685diff -urNp linux-2.6.19.1/arch/i386/kernel/traps.c linux-2.6.19.1/arch/i386/kernel/traps.c
2686--- linux-2.6.19.1/arch/i386/kernel/traps.c 2006-11-29 16:57:37.000000000 -0500
2687+++ linux-2.6.19.1/arch/i386/kernel/traps.c 2006-12-03 15:15:45.000000000 -0500
2688@@ -29,6 +29,7 @@
2689 #include <linux/kexec.h>
2690 #include <linux/unwind.h>
2691 #include <linux/uaccess.h>
2692+#include <linux/binfmts.h>
2693
2694 #ifdef CONFIG_EISA
2695 #include <linux/ioport.h>
2696@@ -61,18 +62,10 @@ int panic_on_unrecovered_nmi;
2697
2698 asmlinkage int system_call(void);
2699
2700-struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 },
2701- { 0, 0 }, { 0, 0 } };
2702-
2703 /* Do we ignore FPU interrupts ? */
2704 char ignore_fpu_irq = 0;
2705
2706-/*
2707- * The IDT has to be page-aligned to simplify the Pentium
2708- * F0 0F bug workaround.. We have a special link segment
2709- * for this.
2710- */
2711-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
2712+extern struct desc_struct idt_table[256];
2713
2714 asmlinkage void divide_error(void);
2715 asmlinkage void debug(void);
2716@@ -146,7 +139,7 @@ static inline unsigned long print_contex
2717 #else
2718 while (valid_stack_ptr(tinfo, stack)) {
2719 addr = *stack++;
2720- if (__kernel_text_address(addr))
2721+ if (__kernel_text_address(addr + __KERNEL_TEXT_OFFSET))
2722 ops->address(data, addr);
2723 }
2724 #endif
2725@@ -351,7 +344,7 @@ void show_registers(struct pt_regs *regs
2726
2727 esp = (unsigned long) (&regs->esp);
2728 savesegment(ss, ss);
2729- if (user_mode_vm(regs)) {
2730+ if (user_mode(regs)) {
2731 in_kernel = 0;
2732 esp = regs->esp;
2733 ss = regs->xss & 0xffff;
2734@@ -382,13 +375,15 @@ void show_registers(struct pt_regs *regs
2735 u8 __user *eip;
2736 int code_bytes = 64;
2737 unsigned char c;
2738+ mm_segment_t old_fs = get_fs();
2739
2740 printk("\n" KERN_EMERG "Stack: ");
2741 show_stack_log_lvl(NULL, regs, (unsigned long *)esp, KERN_EMERG);
2742
2743 printk(KERN_EMERG "Code: ");
2744
2745- eip = (u8 __user *)regs->eip - 43;
2746+ set_fs(KERNEL_DS);
2747+ eip = (u8 __user *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
2748 if (eip < (u8 __user *)PAGE_OFFSET || __get_user(c, eip)) {
2749 /* try starting at EIP */
2750 eip = (u8 __user *)regs->eip;
2751@@ -399,26 +394,29 @@ void show_registers(struct pt_regs *regs
2752 printk(" Bad EIP value.");
2753 break;
2754 }
2755- if (eip == (u8 __user *)regs->eip)
2756+ if (eip == (u8 __user *)regs->eip + __KERNEL_TEXT_OFFSET)
2757 printk("<%02x> ", c);
2758 else
2759 printk("%02x ", c);
2760 }
2761+ set_fs(old_fs);
2762 }
2763 printk("\n");
2764 }
2765
2766 static void handle_BUG(struct pt_regs *regs)
2767 {
2768- unsigned long eip = regs->eip;
2769+ unsigned long eip = regs->eip + __KERNEL_TEXT_OFFSET;
2770 unsigned short ud2;
2771+ mm_segment_t old_fs = get_fs();
2772
2773+ set_fs(KERNEL_DS);
2774 if (eip < PAGE_OFFSET)
2775- return;
2776+ goto out;
2777 if (probe_kernel_address((unsigned short __user *)eip, ud2))
2778- return;
2779+ goto out;
2780 if (ud2 != 0x0b0f)
2781- return;
2782+ goto out;
2783
2784 printk(KERN_EMERG "------------[ cut here ]------------\n");
2785
2786@@ -428,18 +426,21 @@ static void handle_BUG(struct pt_regs *r
2787 char *file;
2788 char c;
2789
2790- if (probe_kernel_address((unsigned short __user *)(eip + 2),
2791- line))
2792+ if (probe_kernel_address((unsigned short __user *)(eip + 7), line))
2793 break;
2794- if (__get_user(file, (char * __user *)(eip + 4)) ||
2795- (unsigned long)file < PAGE_OFFSET || __get_user(c, file))
2796+ if (probe_kernel_address((char * __user *)(eip + 3), file) ||
2797+ file < _text + __KERNEL_TEXT_OFFSET)
2798+ break;
2799+ if (probe_kernel_address(file, c))
2800 file = "<bad filename>";
2801-
2802 printk(KERN_EMERG "kernel BUG at %s:%d!\n", file, line);
2803- return;
2804+ goto out;
2805 } while (0);
2806 #endif
2807 printk(KERN_EMERG "Kernel BUG at [verbose debug info unavailable]\n");
2808+
2809+out:
2810+ set_fs(old_fs);
2811 }
2812
2813 /* This is gone through when something in the kernel
2814@@ -538,7 +539,7 @@ void die(const char * str, struct pt_reg
2815
2816 static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
2817 {
2818- if (!user_mode_vm(regs))
2819+ if (!user_mode(regs))
2820 die(str, regs, err);
2821 }
2822
2823@@ -556,7 +557,7 @@ static void __kprobes do_trap(int trapnr
2824 goto trap_signal;
2825 }
2826
2827- if (!user_mode(regs))
2828+ if (!user_mode_novm(regs))
2829 goto kernel_trap;
2830
2831 trap_signal: {
2832@@ -644,7 +645,7 @@ fastcall void __kprobes do_general_prote
2833 long error_code)
2834 {
2835 int cpu = get_cpu();
2836- struct tss_struct *tss = &per_cpu(init_tss, cpu);
2837+ struct tss_struct *tss = &init_tss[cpu];
2838 struct thread_struct *thread = &current->thread;
2839
2840 /*
2841@@ -680,9 +681,25 @@ fastcall void __kprobes do_general_prote
2842 if (regs->eflags & VM_MASK)
2843 goto gp_in_vm86;
2844
2845- if (!user_mode(regs))
2846+ if (!user_mode_novm(regs))
2847 goto gp_in_kernel;
2848
2849+#ifdef CONFIG_PAX_PAGEEXEC
2850+ if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
2851+ struct mm_struct *mm = current->mm;
2852+ unsigned long limit;
2853+
2854+ down_write(&mm->mmap_sem);
2855+ limit = mm->context.user_cs_limit;
2856+ if (limit < TASK_SIZE) {
2857+ track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
2858+ up_write(&mm->mmap_sem);
2859+ return;
2860+ }
2861+ up_write(&mm->mmap_sem);
2862+ }
2863+#endif
2864+
2865 current->thread.error_code = error_code;
2866 current->thread.trap_no = 13;
2867 force_sig(SIGSEGV, current);
2868@@ -698,6 +715,13 @@ gp_in_kernel:
2869 if (notify_die(DIE_GPF, "general protection fault", regs,
2870 error_code, 13, SIGSEGV) == NOTIFY_STOP)
2871 return;
2872+
2873+#ifdef CONFIG_PAX_KERNEXEC
2874+ if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
2875+ die("PAX: suspicious general protection fault", regs, error_code);
2876+ else
2877+#endif
2878+
2879 die("general protection fault", regs, error_code);
2880 }
2881 }
2882@@ -781,7 +805,7 @@ void __kprobes die_nmi(struct pt_regs *r
2883 /* If we are in kernel we are probably nested up pretty bad
2884 * and might aswell get out now while we still can.
2885 */
2886- if (!user_mode_vm(regs)) {
2887+ if (!user_mode(regs)) {
2888 current->thread.trap_no = 2;
2889 crash_kexec(regs);
2890 }
2891@@ -913,7 +937,7 @@ fastcall void __kprobes do_debug(struct
2892 * check for kernel mode by just checking the CPL
2893 * of CS.
2894 */
2895- if (!user_mode(regs))
2896+ if (!user_mode_novm(regs))
2897 goto clear_TF_reenable;
2898 }
2899
2900@@ -1189,7 +1213,19 @@ void __init trap_init_f00f_bug(void)
2901 */
2902 void set_intr_gate(unsigned int n, void *addr)
2903 {
2904+
2905+#ifdef CONFIG_PAX_KERNEXEC
2906+ unsigned long cr0;
2907+
2908+ pax_open_kernel(cr0);
2909+#endif
2910+
2911 _set_gate(n, DESCTYPE_INT, addr, __KERNEL_CS);
2912+
2913+#ifdef CONFIG_PAX_KERNEXEC
2914+ pax_close_kernel(cr0);
2915+#endif
2916+
2917 }
2918
2919 /*
2920diff -urNp linux-2.6.19.1/arch/i386/kernel/vm86.c linux-2.6.19.1/arch/i386/kernel/vm86.c
2921--- linux-2.6.19.1/arch/i386/kernel/vm86.c 2006-11-29 16:57:37.000000000 -0500
2922+++ linux-2.6.19.1/arch/i386/kernel/vm86.c 2006-12-03 15:15:45.000000000 -0500
2923@@ -122,7 +122,7 @@ struct pt_regs * fastcall save_v86_state
2924 do_exit(SIGSEGV);
2925 }
2926
2927- tss = &per_cpu(init_tss, get_cpu());
2928+ tss = init_tss + get_cpu();
2929 current->thread.esp0 = current->thread.saved_esp0;
2930 current->thread.sysenter_cs = __KERNEL_CS;
2931 load_esp0(tss, &current->thread);
2932@@ -296,7 +296,7 @@ static void do_sys_vm86(struct kernel_vm
2933 savesegment(fs, tsk->thread.saved_fs);
2934 savesegment(gs, tsk->thread.saved_gs);
2935
2936- tss = &per_cpu(init_tss, get_cpu());
2937+ tss = init_tss + get_cpu();
2938 tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
2939 if (cpu_has_sep)
2940 tsk->thread.sysenter_cs = 0;
2941diff -urNp linux-2.6.19.1/arch/i386/kernel/vmlinux.lds.S linux-2.6.19.1/arch/i386/kernel/vmlinux.lds.S
2942--- linux-2.6.19.1/arch/i386/kernel/vmlinux.lds.S 2006-11-29 16:57:37.000000000 -0500
2943+++ linux-2.6.19.1/arch/i386/kernel/vmlinux.lds.S 2006-12-03 15:15:45.000000000 -0500
2944@@ -8,6 +8,13 @@
2945 #include <asm/thread_info.h>
2946 #include <asm/page.h>
2947 #include <asm/cache.h>
2948+#include <asm/segment.h>
2949+
2950+#ifdef CONFIG_X86_PAE
2951+#define PMD_SHIFT 21
2952+#else
2953+#define PMD_SHIFT 22
2954+#endif
2955
2956 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
2957 OUTPUT_ARCH(i386)
2958@@ -16,31 +23,133 @@ jiffies = jiffies_64;
2959
2960 PHDRS {
2961 text PT_LOAD FLAGS(5); /* R_E */
2962- data PT_LOAD FLAGS(7); /* RWE */
2963+ data PT_LOAD FLAGS(6); /* RW_ */
2964 note PT_NOTE FLAGS(4); /* R__ */
2965 }
2966 SECTIONS
2967 {
2968 . = __KERNEL_START;
2969- phys_startup_32 = startup_32 - LOAD_OFFSET;
2970+ phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
2971+
2972+ .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
2973+ BYTE(0xEA) /* jmp far */
2974+ LONG(phys_startup_32)
2975+ SHORT(__BOOT_CS)
2976+ } :text = 0x9090
2977+
2978+ /* might get freed after init */
2979+ . = ALIGN(4096);
2980+ __smp_alt_begin = .;
2981+ __smp_alt_instructions = .;
2982+ .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
2983+ *(.smp_altinstructions)
2984+ }
2985+ __smp_alt_instructions_end = .;
2986+ . = ALIGN(4);
2987+ __smp_locks = .;
2988+ .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
2989+ *(.smp_locks)
2990+ }
2991+ __smp_locks_end = .;
2992+ .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
2993+ *(.smp_altinstr_replacement)
2994+ }
2995+ . = ALIGN(4096);
2996+ __smp_alt_end = .;
2997+
2998+ /* will be freed after init */
2999+ . = ALIGN(4096); /* Init code and data */
3000+ __init_begin = .;
3001+ .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
3002+ . = ALIGN(16);
3003+ __setup_start = .;
3004+ .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
3005+ __setup_end = .;
3006+ __initcall_start = .;
3007+ .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
3008+ INITCALLS
3009+ }
3010+ __initcall_end = .;
3011+ __con_initcall_start = .;
3012+ .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
3013+ *(.con_initcall.init)
3014+ }
3015+ __con_initcall_end = .;
3016+ SECURITY_INIT
3017+ . = ALIGN(4);
3018+ __alt_instructions = .;
3019+ .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
3020+ *(.altinstructions)
3021+ }
3022+ __alt_instructions_end = .;
3023+ .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
3024+ *(.altinstr_replacement)
3025+ }
3026+
3027+ .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3028+ . = ALIGN(4096);
3029+ __initramfs_start = .;
3030+ .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
3031+ __initramfs_end = .;
3032+ . = ALIGN(L1_CACHE_BYTES);
3033+ __per_cpu_start = .;
3034+ .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
3035+ __per_cpu_end = .;
3036+
3037 /* read-only */
3038+
3039+ . = ALIGN(4096);
3040+ .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3041+ _sinittext = .;
3042+ *(.init.text)
3043+ _einittext = .;
3044+ }
3045+
3046+ /* .exit.text is discard at runtime, not link time, to deal with references
3047+ from .altinstructions and .eh_frame */
3048+ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
3049+
3050+#ifdef CONFIG_PAX_KERNEXEC
3051+ .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3052+ . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
3053+ BYTE(0)
3054+ }
3055+#else
3056+ . = ALIGN(4096);
3057+#endif
3058+
3059+ __init_end = . + __KERNEL_TEXT_OFFSET;
3060+ /* freed after init ends here */
3061+
3062 _text = .; /* Text and read-only data */
3063- .text : AT(ADDR(.text) - LOAD_OFFSET) {
3064+ .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3065 *(.text)
3066 SCHED_TEXT
3067 LOCK_TEXT
3068 KPROBES_TEXT
3069 *(.fixup)
3070 *(.gnu.warning)
3071- } :text = 0x9090
3072+ }
3073
3074 _etext = .; /* End of text section */
3075-
3076+ . += __KERNEL_TEXT_OFFSET;
3077 . = ALIGN(16); /* Exception table */
3078 __start___ex_table = .;
3079 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
3080 __stop___ex_table = .;
3081
3082+ . = ALIGN(4096);
3083+ .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
3084+ *(.empty_zero_page)
3085+
3086+#ifdef CONFIG_X86_PAE
3087+ *(.swapper_pm_dir)
3088+#endif
3089+
3090+ *(.swapper_pg_dir)
3091+ *(.idt)
3092+ }
3093+
3094 RODATA
3095
3096 . = ALIGN(4);
3097@@ -50,9 +159,25 @@ SECTIONS
3098 }
3099 __tracedata_end = .;
3100
3101+#ifdef CONFIG_PAX_KERNEXEC
3102+ . = ALIGN(4096);
3103+ MODULES_VADDR = .;
3104+
3105+ .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
3106+ . += (4 * 1024 * 1024);
3107+ . = ALIGN(1 << PMD_SHIFT) - 1;
3108+ BYTE(0)
3109+ }
3110+
3111+ MODULES_END = .;
3112+#else
3113+ . = ALIGN(32);
3114+#endif
3115+
3116 /* writeable */
3117 . = ALIGN(4096);
3118 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
3119+ _data = .;
3120 *(.data)
3121 CONSTRUCTORS
3122 } :data
3123@@ -63,11 +188,6 @@ SECTIONS
3124 . = ALIGN(4096);
3125 __nosave_end = .;
3126
3127- . = ALIGN(4096);
3128- .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
3129- *(.data.idt)
3130- }
3131-
3132 . = ALIGN(32);
3133 .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3134 *(.data.cacheline_aligned)
3135@@ -76,7 +196,6 @@ SECTIONS
3136 /* rarely changed data like cpu maps */
3137 . = ALIGN(32);
3138 .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) { *(.data.read_mostly) }
3139- _edata = .; /* End of data section */
3140
3141 #ifdef CONFIG_STACK_UNWIND
3142 . = ALIGN(4);
3143@@ -92,75 +211,9 @@ SECTIONS
3144 *(.data.init_task)
3145 }
3146
3147- /* might get freed after init */
3148- . = ALIGN(4096);
3149- __smp_alt_begin = .;
3150- __smp_alt_instructions = .;
3151- .smp_altinstructions : AT(ADDR(.smp_altinstructions) - LOAD_OFFSET) {
3152- *(.smp_altinstructions)
3153- }
3154- __smp_alt_instructions_end = .;
3155- . = ALIGN(4);
3156- __smp_locks = .;
3157- .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
3158- *(.smp_locks)
3159- }
3160- __smp_locks_end = .;
3161- .smp_altinstr_replacement : AT(ADDR(.smp_altinstr_replacement) - LOAD_OFFSET) {
3162- *(.smp_altinstr_replacement)
3163- }
3164- . = ALIGN(4096);
3165- __smp_alt_end = .;
3166+ _edata = .; /* End of data section */
3167
3168- /* will be freed after init */
3169- . = ALIGN(4096); /* Init code and data */
3170- __init_begin = .;
3171- .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
3172- _sinittext = .;
3173- *(.init.text)
3174- _einittext = .;
3175- }
3176- .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
3177- . = ALIGN(16);
3178- __setup_start = .;
3179- .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
3180- __setup_end = .;
3181- __initcall_start = .;
3182- .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
3183- INITCALLS
3184- }
3185- __initcall_end = .;
3186- __con_initcall_start = .;
3187- .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
3188- *(.con_initcall.init)
3189- }
3190- __con_initcall_end = .;
3191- SECURITY_INIT
3192- . = ALIGN(4);
3193- __alt_instructions = .;
3194- .altinstructions : AT(ADDR(.altinstructions) - LOAD_OFFSET) {
3195- *(.altinstructions)
3196- }
3197- __alt_instructions_end = .;
3198- .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) {
3199- *(.altinstr_replacement)
3200- }
3201- /* .exit.text is discard at runtime, not link time, to deal with references
3202- from .altinstructions and .eh_frame */
3203- .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
3204- .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3205- . = ALIGN(4096);
3206- __initramfs_start = .;
3207- .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) }
3208- __initramfs_end = .;
3209- . = ALIGN(L1_CACHE_BYTES);
3210- __per_cpu_start = .;
3211- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) }
3212- __per_cpu_end = .;
3213 . = ALIGN(4096);
3214- __init_end = .;
3215- /* freed after init ends here */
3216-
3217 __bss_start = .; /* BSS */
3218 .bss.page_aligned : AT(ADDR(.bss.page_aligned) - LOAD_OFFSET) {
3219 *(.bss.page_aligned)
3220diff -urNp linux-2.6.19.1/arch/i386/lib/checksum.S linux-2.6.19.1/arch/i386/lib/checksum.S
3221--- linux-2.6.19.1/arch/i386/lib/checksum.S 2006-11-29 16:57:37.000000000 -0500
3222+++ linux-2.6.19.1/arch/i386/lib/checksum.S 2006-12-03 15:15:45.000000000 -0500
3223@@ -26,7 +26,8 @@
3224 */
3225
3226 #include <asm/errno.h>
3227-
3228+#include <asm/segment.h>
3229+
3230 /*
3231 * computes a partial checksum, e.g. for TCP/UDP fragments
3232 */
3233@@ -280,12 +281,23 @@ unsigned int csum_partial_copy_generic (
3234
3235 .align 4
3236 .globl csum_partial_copy_generic
3237-
3238+.globl csum_partial_copy_generic_to_user
3239+.globl csum_partial_copy_generic_from_user
3240+
3241 #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
3242
3243 #define ARGBASE 16
3244 #define FP 12
3245-
3246+
3247+csum_partial_copy_generic_to_user:
3248+ pushl $(__USER_DS)
3249+ popl %es
3250+ jmp csum_partial_copy_generic
3251+
3252+csum_partial_copy_generic_from_user:
3253+ pushl $(__USER_DS)
3254+ popl %ds
3255+
3256 csum_partial_copy_generic:
3257 subl $4,%esp
3258 pushl %edi
3259@@ -304,7 +316,7 @@ csum_partial_copy_generic:
3260 jmp 4f
3261 SRC(1: movw (%esi), %bx )
3262 addl $2, %esi
3263-DST( movw %bx, (%edi) )
3264+DST( movw %bx, %es:(%edi) )
3265 addl $2, %edi
3266 addw %bx, %ax
3267 adcl $0, %eax
3268@@ -316,30 +328,30 @@ DST( movw %bx, (%edi) )
3269 SRC(1: movl (%esi), %ebx )
3270 SRC( movl 4(%esi), %edx )
3271 adcl %ebx, %eax
3272-DST( movl %ebx, (%edi) )
3273+DST( movl %ebx, %es:(%edi) )
3274 adcl %edx, %eax
3275-DST( movl %edx, 4(%edi) )
3276+DST( movl %edx, %es:4(%edi) )
3277
3278 SRC( movl 8(%esi), %ebx )
3279 SRC( movl 12(%esi), %edx )
3280 adcl %ebx, %eax
3281-DST( movl %ebx, 8(%edi) )
3282+DST( movl %ebx, %es:8(%edi) )
3283 adcl %edx, %eax
3284-DST( movl %edx, 12(%edi) )
3285+DST( movl %edx, %es:12(%edi) )
3286
3287 SRC( movl 16(%esi), %ebx )
3288 SRC( movl 20(%esi), %edx )
3289 adcl %ebx, %eax
3290-DST( movl %ebx, 16(%edi) )
3291+DST( movl %ebx, %es:16(%edi) )
3292 adcl %edx, %eax
3293-DST( movl %edx, 20(%edi) )
3294+DST( movl %edx, %es:20(%edi) )
3295
3296 SRC( movl 24(%esi), %ebx )
3297 SRC( movl 28(%esi), %edx )
3298 adcl %ebx, %eax
3299-DST( movl %ebx, 24(%edi) )
3300+DST( movl %ebx, %es:24(%edi) )
3301 adcl %edx, %eax
3302-DST( movl %edx, 28(%edi) )
3303+DST( movl %edx, %es:28(%edi) )
3304
3305 lea 32(%esi), %esi
3306 lea 32(%edi), %edi
3307@@ -353,7 +365,7 @@ DST( movl %edx, 28(%edi) )
3308 shrl $2, %edx # This clears CF
3309 SRC(3: movl (%esi), %ebx )
3310 adcl %ebx, %eax
3311-DST( movl %ebx, (%edi) )
3312+DST( movl %ebx, %es:(%edi) )
3313 lea 4(%esi), %esi
3314 lea 4(%edi), %edi
3315 dec %edx
3316@@ -365,12 +377,12 @@ DST( movl %ebx, (%edi) )
3317 jb 5f
3318 SRC( movw (%esi), %cx )
3319 leal 2(%esi), %esi
3320-DST( movw %cx, (%edi) )
3321+DST( movw %cx, %es:(%edi) )
3322 leal 2(%edi), %edi
3323 je 6f
3324 shll $16,%ecx
3325 SRC(5: movb (%esi), %cl )
3326-DST( movb %cl, (%edi) )
3327+DST( movb %cl, %es:(%edi) )
3328 6: addl %ecx, %eax
3329 adcl $0, %eax
3330 7:
3331@@ -381,7 +393,7 @@ DST( movb %cl, (%edi) )
3332
3333 6001:
3334 movl ARGBASE+20(%esp), %ebx # src_err_ptr
3335- movl $-EFAULT, (%ebx)
3336+ movl $-EFAULT, %ss:(%ebx)
3337
3338 # zero the complete destination - computing the rest
3339 # is too much work
3340@@ -394,11 +406,15 @@ DST( movb %cl, (%edi) )
3341
3342 6002:
3343 movl ARGBASE+24(%esp), %ebx # dst_err_ptr
3344- movl $-EFAULT,(%ebx)
3345+ movl $-EFAULT,%ss:(%ebx)
3346 jmp 5000b
3347
3348 .previous
3349
3350+ pushl %ss
3351+ popl %ds
3352+ pushl %ss
3353+ popl %es
3354 popl %ebx
3355 popl %esi
3356 popl %edi
3357@@ -410,17 +426,28 @@ DST( movb %cl, (%edi) )
3358 /* Version for PentiumII/PPro */
3359
3360 #define ROUND1(x) \
3361+ nop; nop; nop; \
3362 SRC(movl x(%esi), %ebx ) ; \
3363 addl %ebx, %eax ; \
3364- DST(movl %ebx, x(%edi) ) ;
3365+ DST(movl %ebx, %es:x(%edi));
3366
3367 #define ROUND(x) \
3368+ nop; nop; nop; \
3369 SRC(movl x(%esi), %ebx ) ; \
3370 adcl %ebx, %eax ; \
3371- DST(movl %ebx, x(%edi) ) ;
3372+ DST(movl %ebx, %es:x(%edi));
3373
3374 #define ARGBASE 12
3375-
3376+
3377+csum_partial_copy_generic_to_user:
3378+ pushl $(__USER_DS)
3379+ popl %es
3380+ jmp csum_partial_copy_generic
3381+
3382+csum_partial_copy_generic_from_user:
3383+ pushl $(__USER_DS)
3384+ popl %ds
3385+
3386 csum_partial_copy_generic:
3387 pushl %ebx
3388 pushl %edi
3389@@ -439,7 +466,7 @@ csum_partial_copy_generic:
3390 subl %ebx, %edi
3391 lea -1(%esi),%edx
3392 andl $-32,%edx
3393- lea 3f(%ebx,%ebx), %ebx
3394+ lea 3f(%ebx,%ebx,2), %ebx
3395 testl %esi, %esi
3396 jmp *%ebx
3397 1: addl $64,%esi
3398@@ -460,19 +487,19 @@ csum_partial_copy_generic:
3399 jb 5f
3400 SRC( movw (%esi), %dx )
3401 leal 2(%esi), %esi
3402-DST( movw %dx, (%edi) )
3403+DST( movw %dx, %es:(%edi) )
3404 leal 2(%edi), %edi
3405 je 6f
3406 shll $16,%edx
3407 5:
3408 SRC( movb (%esi), %dl )
3409-DST( movb %dl, (%edi) )
3410+DST( movb %dl, %es:(%edi) )
3411 6: addl %edx, %eax
3412 adcl $0, %eax
3413 7:
3414 .section .fixup, "ax"
3415 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr
3416- movl $-EFAULT, (%ebx)
3417+ movl $-EFAULT, %ss:(%ebx)
3418 # zero the complete destination (computing the rest is too much work)
3419 movl ARGBASE+8(%esp),%edi # dst
3420 movl ARGBASE+12(%esp),%ecx # len
3421@@ -480,10 +507,14 @@ DST( movb %dl, (%edi) )
3422 rep; stosb
3423 jmp 7b
3424 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr
3425- movl $-EFAULT, (%ebx)
3426+ movl $-EFAULT, %ss:(%ebx)
3427 jmp 7b
3428 .previous
3429
3430+ pushl %ss
3431+ popl %ds
3432+ pushl %ss
3433+ popl %es
3434 popl %esi
3435 popl %edi
3436 popl %ebx
3437diff -urNp linux-2.6.19.1/arch/i386/lib/getuser.S linux-2.6.19.1/arch/i386/lib/getuser.S
3438--- linux-2.6.19.1/arch/i386/lib/getuser.S 2006-11-29 16:57:37.000000000 -0500
3439+++ linux-2.6.19.1/arch/i386/lib/getuser.S 2006-12-03 15:15:45.000000000 -0500
3440@@ -9,6 +9,7 @@
3441 * return value.
3442 */
3443 #include <asm/thread_info.h>
3444+#include <asm/segment.h>
3445
3446
3447 /*
3448@@ -30,8 +31,12 @@ __get_user_1:
3449 GET_THREAD_INFO(%edx)
3450 cmpl TI_addr_limit(%edx),%eax
3451 jae bad_get_user
3452+ pushl $(__USER_DS)
3453+ popl %ds
3454 1: movzbl (%eax),%edx
3455 xorl %eax,%eax
3456+ pushl %ss
3457+ pop %ds
3458 ret
3459
3460 .align 4
3461@@ -42,7 +47,11 @@ __get_user_2:
3462 GET_THREAD_INFO(%edx)
3463 cmpl TI_addr_limit(%edx),%eax
3464 jae bad_get_user
3465+ pushl $(__USER_DS)
3466+ popl %ds
3467 2: movzwl -1(%eax),%edx
3468+ pushl %ss
3469+ pop %ds
3470 xorl %eax,%eax
3471 ret
3472
3473@@ -54,11 +63,17 @@ __get_user_4:
3474 GET_THREAD_INFO(%edx)
3475 cmpl TI_addr_limit(%edx),%eax
3476 jae bad_get_user
3477+ pushl $(__USER_DS)
3478+ popl %ds
3479 3: movl -3(%eax),%edx
3480+ pushl %ss
3481+ pop %ds
3482 xorl %eax,%eax
3483 ret
3484
3485 bad_get_user:
3486+ pushl %ss
3487+ pop %ds
3488 xorl %edx,%edx
3489 movl $-14,%eax
3490 ret
3491diff -urNp linux-2.6.19.1/arch/i386/lib/mmx.c linux-2.6.19.1/arch/i386/lib/mmx.c
3492--- linux-2.6.19.1/arch/i386/lib/mmx.c 2006-11-29 16:57:37.000000000 -0500
3493+++ linux-2.6.19.1/arch/i386/lib/mmx.c 2006-12-03 15:15:45.000000000 -0500
3494@@ -47,14 +47,30 @@ void *_mmx_memcpy(void *to, const void *
3495 " prefetch 256(%0)\n"
3496 "2: \n"
3497 ".section .fixup, \"ax\"\n"
3498- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3499+ "3: \n"
3500+
3501+#ifdef CONFIG_PAX_KERNEXEC
3502+ " cli\n"
3503+ " movl %%cr0, %%eax\n"
3504+ " andl $0xFFFEFFFF, %%eax\n"
3505+ " movl %%eax, %%cr0\n"
3506+#endif
3507+
3508+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3509+
3510+#ifdef CONFIG_PAX_KERNEXEC
3511+ " orl $0x00010000, %%eax\n"
3512+ " movl %%eax, %%cr0\n"
3513+ " sti\n"
3514+#endif
3515+
3516 " jmp 2b\n"
3517 ".previous\n"
3518 ".section __ex_table,\"a\"\n"
3519 " .align 4\n"
3520 " .long 1b, 3b\n"
3521 ".previous"
3522- : : "r" (from) );
3523+ : : "r" (from) : "ax");
3524
3525
3526 for(; i>5; i--)
3527@@ -78,14 +94,30 @@ void *_mmx_memcpy(void *to, const void *
3528 " movq %%mm2, 48(%1)\n"
3529 " movq %%mm3, 56(%1)\n"
3530 ".section .fixup, \"ax\"\n"
3531- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3532+ "3:\n"
3533+
3534+#ifdef CONFIG_PAX_KERNEXEC
3535+ " cli\n"
3536+ " movl %%cr0, %%eax\n"
3537+ " andl $0xFFFEFFFF, %%eax\n"
3538+ " movl %%eax, %%cr0\n"
3539+#endif
3540+
3541+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3542+
3543+#ifdef CONFIG_PAX_KERNEXEC
3544+ " orl $0x00010000, %%eax\n"
3545+ " movl %%eax, %%cr0\n"
3546+ " sti\n"
3547+#endif
3548+
3549 " jmp 2b\n"
3550 ".previous\n"
3551 ".section __ex_table,\"a\"\n"
3552 " .align 4\n"
3553 " .long 1b, 3b\n"
3554 ".previous"
3555- : : "r" (from), "r" (to) : "memory");
3556+ : : "r" (from), "r" (to) : "memory", "ax");
3557 from+=64;
3558 to+=64;
3559 }
3560@@ -178,14 +210,30 @@ static void fast_copy_page(void *to, voi
3561 " prefetch 256(%0)\n"
3562 "2: \n"
3563 ".section .fixup, \"ax\"\n"
3564- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3565+ "3: \n"
3566+
3567+#ifdef CONFIG_PAX_KERNEXEC
3568+ " cli\n"
3569+ " movl %%cr0, %%eax\n"
3570+ " andl $0xFFFEFFFF, %%eax\n"
3571+ " movl %%eax, %%cr0\n"
3572+#endif
3573+
3574+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3575+
3576+#ifdef CONFIG_PAX_KERNEXEC
3577+ " orl $0x00010000, %%eax\n"
3578+ " movl %%eax, %%cr0\n"
3579+ " sti\n"
3580+#endif
3581+
3582 " jmp 2b\n"
3583 ".previous\n"
3584 ".section __ex_table,\"a\"\n"
3585 " .align 4\n"
3586 " .long 1b, 3b\n"
3587 ".previous"
3588- : : "r" (from) );
3589+ : : "r" (from) : "ax");
3590
3591 for(i=0; i<(4096-320)/64; i++)
3592 {
3593@@ -208,14 +256,30 @@ static void fast_copy_page(void *to, voi
3594 " movq 56(%0), %%mm7\n"
3595 " movntq %%mm7, 56(%1)\n"
3596 ".section .fixup, \"ax\"\n"
3597- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3598+ "3:\n"
3599+
3600+#ifdef CONFIG_PAX_KERNEXEC
3601+ " cli\n"
3602+ " movl %%cr0, %%eax\n"
3603+ " andl $0xFFFEFFFF, %%eax\n"
3604+ " movl %%eax, %%cr0\n"
3605+#endif
3606+
3607+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3608+
3609+#ifdef CONFIG_PAX_KERNEXEC
3610+ " orl $0x00010000, %%eax\n"
3611+ " movl %%eax, %%cr0\n"
3612+ " sti\n"
3613+#endif
3614+
3615 " jmp 2b\n"
3616 ".previous\n"
3617 ".section __ex_table,\"a\"\n"
3618 " .align 4\n"
3619 " .long 1b, 3b\n"
3620 ".previous"
3621- : : "r" (from), "r" (to) : "memory");
3622+ : : "r" (from), "r" (to) : "memory", "ax");
3623 from+=64;
3624 to+=64;
3625 }
3626@@ -308,14 +372,30 @@ static void fast_copy_page(void *to, voi
3627 " prefetch 256(%0)\n"
3628 "2: \n"
3629 ".section .fixup, \"ax\"\n"
3630- "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3631+ "3: \n"
3632+
3633+#ifdef CONFIG_PAX_KERNEXEC
3634+ " cli\n"
3635+ " movl %%cr0, %%eax\n"
3636+ " andl $0xFFFEFFFF, %%eax\n"
3637+ " movl %%eax, %%cr0\n"
3638+#endif
3639+
3640+ " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
3641+
3642+#ifdef CONFIG_PAX_KERNEXEC
3643+ " orl $0x00010000, %%eax\n"
3644+ " movl %%eax, %%cr0\n"
3645+ " sti\n"
3646+#endif
3647+
3648 " jmp 2b\n"
3649 ".previous\n"
3650 ".section __ex_table,\"a\"\n"
3651 " .align 4\n"
3652 " .long 1b, 3b\n"
3653 ".previous"
3654- : : "r" (from) );
3655+ : : "r" (from) : "ax");
3656
3657 for(i=0; i<4096/64; i++)
3658 {
3659@@ -338,14 +418,30 @@ static void fast_copy_page(void *to, voi
3660 " movq %%mm2, 48(%1)\n"
3661 " movq %%mm3, 56(%1)\n"
3662 ".section .fixup, \"ax\"\n"
3663- "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3664+ "3:\n"
3665+
3666+#ifdef CONFIG_PAX_KERNEXEC
3667+ " cli\n"
3668+ " movl %%cr0, %%eax\n"
3669+ " andl $0xFFFEFFFF, %%eax\n"
3670+ " movl %%eax, %%cr0\n"
3671+#endif
3672+
3673+ " movw $0x05EB, 1b\n" /* jmp on 5 bytes */
3674+
3675+#ifdef CONFIG_PAX_KERNEXEC
3676+ " orl $0x00010000, %%eax\n"
3677+ " movl %%eax, %%cr0\n"
3678+ " sti\n"
3679+#endif
3680+
3681 " jmp 2b\n"
3682 ".previous\n"
3683 ".section __ex_table,\"a\"\n"
3684 " .align 4\n"
3685 " .long 1b, 3b\n"
3686 ".previous"
3687- : : "r" (from), "r" (to) : "memory");
3688+ : : "r" (from), "r" (to) : "memory", "ax");
3689 from+=64;
3690 to+=64;
3691 }
3692diff -urNp linux-2.6.19.1/arch/i386/lib/putuser.S linux-2.6.19.1/arch/i386/lib/putuser.S
3693--- linux-2.6.19.1/arch/i386/lib/putuser.S 2006-11-29 16:57:37.000000000 -0500
3694+++ linux-2.6.19.1/arch/i386/lib/putuser.S 2006-12-03 15:15:45.000000000 -0500
3695@@ -9,6 +9,7 @@
3696 * return value.
3697 */
3698 #include <asm/thread_info.h>
3699+#include <asm/segment.h>
3700
3701
3702 /*
3703@@ -33,7 +34,11 @@ __put_user_1:
3704 ENTER
3705 cmpl TI_addr_limit(%ebx),%ecx
3706 jae bad_put_user
3707+ pushl $(__USER_DS)
3708+ popl %ds
3709 1: movb %al,(%ecx)
3710+ pushl %ss
3711+ popl %ds
3712 xorl %eax,%eax
3713 EXIT
3714
3715@@ -45,7 +50,11 @@ __put_user_2:
3716 subl $1,%ebx
3717 cmpl %ebx,%ecx
3718 jae bad_put_user
3719+ pushl $(__USER_DS)
3720+ popl %ds
3721 2: movw %ax,(%ecx)
3722+ pushl %ss
3723+ popl %ds
3724 xorl %eax,%eax
3725 EXIT
3726
3727@@ -57,7 +66,11 @@ __put_user_4:
3728 subl $3,%ebx
3729 cmpl %ebx,%ecx
3730 jae bad_put_user
3731+ pushl $(__USER_DS)
3732+ popl %ds
3733 3: movl %eax,(%ecx)
3734+ pushl %ss
3735+ popl %ds
3736 xorl %eax,%eax
3737 EXIT
3738
3739@@ -69,12 +82,18 @@ __put_user_8:
3740 subl $7,%ebx
3741 cmpl %ebx,%ecx
3742 jae bad_put_user
3743+ pushl $(__USER_DS)
3744+ popl %ds
3745 4: movl %eax,(%ecx)
3746 5: movl %edx,4(%ecx)
3747+ pushl %ss
3748+ popl %ds
3749 xorl %eax,%eax
3750 EXIT
3751
3752 bad_put_user:
3753+ pushl %ss
3754+ popl %ds
3755 movl $-14,%eax
3756 EXIT
3757
3758diff -urNp linux-2.6.19.1/arch/i386/lib/usercopy.c linux-2.6.19.1/arch/i386/lib/usercopy.c
3759--- linux-2.6.19.1/arch/i386/lib/usercopy.c 2006-11-29 16:57:37.000000000 -0500
3760+++ linux-2.6.19.1/arch/i386/lib/usercopy.c 2006-12-03 15:15:45.000000000 -0500
3761@@ -28,34 +28,41 @@ static inline int __movsl_is_ok(unsigned
3762 * Copy a null terminated string from userspace.
3763 */
3764
3765-#define __do_strncpy_from_user(dst,src,count,res) \
3766-do { \
3767- int __d0, __d1, __d2; \
3768- might_sleep(); \
3769- __asm__ __volatile__( \
3770- " testl %1,%1\n" \
3771- " jz 2f\n" \
3772- "0: lodsb\n" \
3773- " stosb\n" \
3774- " testb %%al,%%al\n" \
3775- " jz 1f\n" \
3776- " decl %1\n" \
3777- " jnz 0b\n" \
3778- "1: subl %1,%0\n" \
3779- "2:\n" \
3780- ".section .fixup,\"ax\"\n" \
3781- "3: movl %5,%0\n" \
3782- " jmp 2b\n" \
3783- ".previous\n" \
3784- ".section __ex_table,\"a\"\n" \
3785- " .align 4\n" \
3786- " .long 0b,3b\n" \
3787- ".previous" \
3788- : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
3789- "=&D" (__d2) \
3790- : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
3791- : "memory"); \
3792-} while (0)
3793+static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
3794+{
3795+ int __d0, __d1, __d2;
3796+ long res = -EFAULT;
3797+
3798+ might_sleep();
3799+ __asm__ __volatile__(
3800+ " movw %w10,%%ds\n"
3801+ " testl %1,%1\n"
3802+ " jz 2f\n"
3803+ "0: lodsb\n"
3804+ " stosb\n"
3805+ " testb %%al,%%al\n"
3806+ " jz 1f\n"
3807+ " decl %1\n"
3808+ " jnz 0b\n"
3809+ "1: subl %1,%0\n"
3810+ "2:\n"
3811+ " pushl %%ss\n"
3812+ " popl %%ds\n"
3813+ ".section .fixup,\"ax\"\n"
3814+ "3: movl %5,%0\n"
3815+ " jmp 2b\n"
3816+ ".previous\n"
3817+ ".section __ex_table,\"a\"\n"
3818+ " .align 4\n"
3819+ " .long 0b,3b\n"
3820+ ".previous"
3821+ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
3822+ "=&D" (__d2)
3823+ : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
3824+ "r"(__USER_DS)
3825+ : "memory");
3826+ return res;
3827+}
3828
3829 /**
3830 * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
3831@@ -80,9 +87,7 @@ do { \
3832 long
3833 __strncpy_from_user(char *dst, const char __user *src, long count)
3834 {
3835- long res;
3836- __do_strncpy_from_user(dst, src, count, res);
3837- return res;
3838+ return __do_strncpy_from_user(dst, src, count);
3839 }
3840 EXPORT_SYMBOL(__strncpy_from_user);
3841
3842@@ -109,7 +114,7 @@ strncpy_from_user(char *dst, const char
3843 {
3844 long res = -EFAULT;
3845 if (access_ok(VERIFY_READ, src, 1))
3846- __do_strncpy_from_user(dst, src, count, res);
3847+ res = __do_strncpy_from_user(dst, src, count);
3848 return res;
3849 }
3850 EXPORT_SYMBOL(strncpy_from_user);
3851@@ -118,27 +123,33 @@ EXPORT_SYMBOL(strncpy_from_user);
3852 * Zero Userspace
3853 */
3854
3855-#define __do_clear_user(addr,size) \
3856-do { \
3857- int __d0; \
3858- might_sleep(); \
3859- __asm__ __volatile__( \
3860- "0: rep; stosl\n" \
3861- " movl %2,%0\n" \
3862- "1: rep; stosb\n" \
3863- "2:\n" \
3864- ".section .fixup,\"ax\"\n" \
3865- "3: lea 0(%2,%0,4),%0\n" \
3866- " jmp 2b\n" \
3867- ".previous\n" \
3868- ".section __ex_table,\"a\"\n" \
3869- " .align 4\n" \
3870- " .long 0b,3b\n" \
3871- " .long 1b,2b\n" \
3872- ".previous" \
3873- : "=&c"(size), "=&D" (__d0) \
3874- : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
3875-} while (0)
3876+static unsigned long __do_clear_user(void __user *addr, unsigned long size)
3877+{
3878+ int __d0;
3879+
3880+ might_sleep();
3881+ __asm__ __volatile__(
3882+ " movw %w6,%%es\n"
3883+ "0: rep; stosl\n"
3884+ " movl %2,%0\n"
3885+ "1: rep; stosb\n"
3886+ "2:\n"
3887+ " pushl %%ss\n"
3888+ " popl %%es\n"
3889+ ".section .fixup,\"ax\"\n"
3890+ "3: lea 0(%2,%0,4),%0\n"
3891+ " jmp 2b\n"
3892+ ".previous\n"
3893+ ".section __ex_table,\"a\"\n"
3894+ " .align 4\n"
3895+ " .long 0b,3b\n"
3896+ " .long 1b,2b\n"
3897+ ".previous"
3898+ : "=&c"(size), "=&D" (__d0)
3899+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
3900+ "r"(__USER_DS));
3901+ return size;
3902+}
3903
3904 /**
3905 * clear_user: - Zero a block of memory in user space.
3906@@ -155,7 +166,7 @@ clear_user(void __user *to, unsigned lon
3907 {
3908 might_sleep();
3909 if (access_ok(VERIFY_WRITE, to, n))
3910- __do_clear_user(to, n);
3911+ n = __do_clear_user(to, n);
3912 return n;
3913 }
3914 EXPORT_SYMBOL(clear_user);
3915@@ -174,8 +185,7 @@ EXPORT_SYMBOL(clear_user);
3916 unsigned long
3917 __clear_user(void __user *to, unsigned long n)
3918 {
3919- __do_clear_user(to, n);
3920- return n;
3921+ return __do_clear_user(to, n);
3922 }
3923 EXPORT_SYMBOL(__clear_user);
3924
3925@@ -198,14 +208,17 @@ long strnlen_user(const char __user *s,
3926 might_sleep();
3927
3928 __asm__ __volatile__(
3929+ " movw %w8,%%es\n"
3930 " testl %0, %0\n"
3931 " jz 3f\n"
3932- " andl %0,%%ecx\n"
3933+ " movl %0,%%ecx\n"
3934 "0: repne; scasb\n"
3935 " setne %%al\n"
3936 " subl %%ecx,%0\n"
3937 " addl %0,%%eax\n"
3938 "1:\n"
3939+ " pushl %%ss\n"
3940+ " popl %%es\n"
3941 ".section .fixup,\"ax\"\n"
3942 "2: xorl %%eax,%%eax\n"
3943 " jmp 1b\n"
3944@@ -217,7 +230,7 @@ long strnlen_user(const char __user *s,
3945 " .long 0b,2b\n"
3946 ".previous"
3947 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
3948- :"0" (n), "1" (s), "2" (0), "3" (mask)
3949+ :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
3950 :"cc");
3951 return res & mask;
3952 }
3953@@ -225,10 +238,121 @@ EXPORT_SYMBOL(strnlen_user);
3954
3955 #ifdef CONFIG_X86_INTEL_USERCOPY
3956 static unsigned long
3957-__copy_user_intel(void __user *to, const void *from, unsigned long size)
3958+__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
3959+{
3960+ int d0, d1;
3961+ __asm__ __volatile__(
3962+ " movw %w6, %%es\n"
3963+ " .align 2,0x90\n"
3964+ "1: movl 32(%4), %%eax\n"
3965+ " cmpl $67, %0\n"
3966+ " jbe 3f\n"
3967+ "2: movl 64(%4), %%eax\n"
3968+ " .align 2,0x90\n"
3969+ "3: movl 0(%4), %%eax\n"
3970+ "4: movl 4(%4), %%edx\n"
3971+ "5: movl %%eax, %%es:0(%3)\n"
3972+ "6: movl %%edx, %%es:4(%3)\n"
3973+ "7: movl 8(%4), %%eax\n"
3974+ "8: movl 12(%4),%%edx\n"
3975+ "9: movl %%eax, %%es:8(%3)\n"
3976+ "10: movl %%edx, %%es:12(%3)\n"
3977+ "11: movl 16(%4), %%eax\n"
3978+ "12: movl 20(%4), %%edx\n"
3979+ "13: movl %%eax, %%es:16(%3)\n"
3980+ "14: movl %%edx, %%es:20(%3)\n"
3981+ "15: movl 24(%4), %%eax\n"
3982+ "16: movl 28(%4), %%edx\n"
3983+ "17: movl %%eax, %%es:24(%3)\n"
3984+ "18: movl %%edx, %%es:28(%3)\n"
3985+ "19: movl 32(%4), %%eax\n"
3986+ "20: movl 36(%4), %%edx\n"
3987+ "21: movl %%eax, %%es:32(%3)\n"
3988+ "22: movl %%edx, %%es:36(%3)\n"
3989+ "23: movl 40(%4), %%eax\n"
3990+ "24: movl 44(%4), %%edx\n"
3991+ "25: movl %%eax, %%es:40(%3)\n"
3992+ "26: movl %%edx, %%es:44(%3)\n"
3993+ "27: movl 48(%4), %%eax\n"
3994+ "28: movl 52(%4), %%edx\n"
3995+ "29: movl %%eax, %%es:48(%3)\n"
3996+ "30: movl %%edx, %%es:52(%3)\n"
3997+ "31: movl 56(%4), %%eax\n"
3998+ "32: movl 60(%4), %%edx\n"
3999+ "33: movl %%eax, %%es:56(%3)\n"
4000+ "34: movl %%edx, %%es:60(%3)\n"
4001+ " addl $-64, %0\n"
4002+ " addl $64, %4\n"
4003+ " addl $64, %3\n"
4004+ " cmpl $63, %0\n"
4005+ " ja 1b\n"
4006+ "35: movl %0, %%eax\n"
4007+ " shrl $2, %0\n"
4008+ " andl $3, %%eax\n"
4009+ " cld\n"
4010+ "99: rep; movsl\n"
4011+ "36: movl %%eax, %0\n"
4012+ "37: rep; movsb\n"
4013+ "100:\n"
4014+ " pushl %%ss\n"
4015+ " popl %%es\n"
4016+ ".section .fixup,\"ax\"\n"
4017+ "101: lea 0(%%eax,%0,4),%0\n"
4018+ " jmp 100b\n"
4019+ ".previous\n"
4020+ ".section __ex_table,\"a\"\n"
4021+ " .align 4\n"
4022+ " .long 1b,100b\n"
4023+ " .long 2b,100b\n"
4024+ " .long 3b,100b\n"
4025+ " .long 4b,100b\n"
4026+ " .long 5b,100b\n"
4027+ " .long 6b,100b\n"
4028+ " .long 7b,100b\n"
4029+ " .long 8b,100b\n"
4030+ " .long 9b,100b\n"
4031+ " .long 10b,100b\n"
4032+ " .long 11b,100b\n"
4033+ " .long 12b,100b\n"
4034+ " .long 13b,100b\n"
4035+ " .long 14b,100b\n"
4036+ " .long 15b,100b\n"
4037+ " .long 16b,100b\n"
4038+ " .long 17b,100b\n"
4039+ " .long 18b,100b\n"
4040+ " .long 19b,100b\n"
4041+ " .long 20b,100b\n"
4042+ " .long 21b,100b\n"
4043+ " .long 22b,100b\n"
4044+ " .long 23b,100b\n"
4045+ " .long 24b,100b\n"
4046+ " .long 25b,100b\n"
4047+ " .long 26b,100b\n"
4048+ " .long 27b,100b\n"
4049+ " .long 28b,100b\n"
4050+ " .long 29b,100b\n"
4051+ " .long 30b,100b\n"
4052+ " .long 31b,100b\n"
4053+ " .long 32b,100b\n"
4054+ " .long 33b,100b\n"
4055+ " .long 34b,100b\n"
4056+ " .long 35b,100b\n"
4057+ " .long 36b,100b\n"
4058+ " .long 37b,100b\n"
4059+ " .long 99b,101b\n"
4060+ ".previous"
4061+ : "=&c"(size), "=&D" (d0), "=&S" (d1)
4062+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4063+ : "eax", "edx", "memory");
4064+ return size;
4065+}
4066+
4067+static unsigned long
4068+__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
4069 {
4070 int d0, d1;
4071 __asm__ __volatile__(
4072+ " movw %w6, %%ds\n"
4073 " .align 2,0x90\n"
4074 "1: movl 32(%4), %%eax\n"
4075 " cmpl $67, %0\n"
4076@@ -237,36 +361,36 @@ __copy_user_intel(void __user *to, const
4077 " .align 2,0x90\n"
4078 "3: movl 0(%4), %%eax\n"
4079 "4: movl 4(%4), %%edx\n"
4080- "5: movl %%eax, 0(%3)\n"
4081- "6: movl %%edx, 4(%3)\n"
4082+ "5: movl %%eax, %%es:0(%3)\n"
4083+ "6: movl %%edx, %%es:4(%3)\n"
4084 "7: movl 8(%4), %%eax\n"
4085 "8: movl 12(%4),%%edx\n"
4086- "9: movl %%eax, 8(%3)\n"
4087- "10: movl %%edx, 12(%3)\n"
4088+ "9: movl %%eax, %%es:8(%3)\n"
4089+ "10: movl %%edx, %%es:12(%3)\n"
4090 "11: movl 16(%4), %%eax\n"
4091 "12: movl 20(%4), %%edx\n"
4092- "13: movl %%eax, 16(%3)\n"
4093- "14: movl %%edx, 20(%3)\n"
4094+ "13: movl %%eax, %%es:16(%3)\n"
4095+ "14: movl %%edx, %%es:20(%3)\n"
4096 "15: movl 24(%4), %%eax\n"
4097 "16: movl 28(%4), %%edx\n"
4098- "17: movl %%eax, 24(%3)\n"
4099- "18: movl %%edx, 28(%3)\n"
4100+ "17: movl %%eax, %%es:24(%3)\n"
4101+ "18: movl %%edx, %%es:28(%3)\n"
4102 "19: movl 32(%4), %%eax\n"
4103 "20: movl 36(%4), %%edx\n"
4104- "21: movl %%eax, 32(%3)\n"
4105- "22: movl %%edx, 36(%3)\n"
4106+ "21: movl %%eax, %%es:32(%3)\n"
4107+ "22: movl %%edx, %%es:36(%3)\n"
4108 "23: movl 40(%4), %%eax\n"
4109 "24: movl 44(%4), %%edx\n"
4110- "25: movl %%eax, 40(%3)\n"
4111- "26: movl %%edx, 44(%3)\n"
4112+ "25: movl %%eax, %%es:40(%3)\n"
4113+ "26: movl %%edx, %%es:44(%3)\n"
4114 "27: movl 48(%4), %%eax\n"
4115 "28: movl 52(%4), %%edx\n"
4116- "29: movl %%eax, 48(%3)\n"
4117- "30: movl %%edx, 52(%3)\n"
4118+ "29: movl %%eax, %%es:48(%3)\n"
4119+ "30: movl %%edx, %%es:52(%3)\n"
4120 "31: movl 56(%4), %%eax\n"
4121 "32: movl 60(%4), %%edx\n"
4122- "33: movl %%eax, 56(%3)\n"
4123- "34: movl %%edx, 60(%3)\n"
4124+ "33: movl %%eax, %%es:56(%3)\n"
4125+ "34: movl %%edx, %%es:60(%3)\n"
4126 " addl $-64, %0\n"
4127 " addl $64, %4\n"
4128 " addl $64, %3\n"
4129@@ -280,6 +404,8 @@ __copy_user_intel(void __user *to, const
4130 "36: movl %%eax, %0\n"
4131 "37: rep; movsb\n"
4132 "100:\n"
4133+ " pushl %%ss\n"
4134+ " popl %%ds\n"
4135 ".section .fixup,\"ax\"\n"
4136 "101: lea 0(%%eax,%0,4),%0\n"
4137 " jmp 100b\n"
4138@@ -326,7 +452,7 @@ __copy_user_intel(void __user *to, const
4139 " .long 99b,101b\n"
4140 ".previous"
4141 : "=&c"(size), "=&D" (d0), "=&S" (d1)
4142- : "1"(to), "2"(from), "0"(size)
4143+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4144 : "eax", "edx", "memory");
4145 return size;
4146 }
4147@@ -336,6 +462,7 @@ __copy_user_zeroing_intel(void *to, cons
4148 {
4149 int d0, d1;
4150 __asm__ __volatile__(
4151+ " movw %w6, %%ds\n"
4152 " .align 2,0x90\n"
4153 "0: movl 32(%4), %%eax\n"
4154 " cmpl $67, %0\n"
4155@@ -344,36 +471,36 @@ __copy_user_zeroing_intel(void *to, cons
4156 " .align 2,0x90\n"
4157 "2: movl 0(%4), %%eax\n"
4158 "21: movl 4(%4), %%edx\n"
4159- " movl %%eax, 0(%3)\n"
4160- " movl %%edx, 4(%3)\n"
4161+ " movl %%eax, %%es:0(%3)\n"
4162+ " movl %%edx, %%es:4(%3)\n"
4163 "3: movl 8(%4), %%eax\n"
4164 "31: movl 12(%4),%%edx\n"
4165- " movl %%eax, 8(%3)\n"
4166- " movl %%edx, 12(%3)\n"
4167+ " movl %%eax, %%es:8(%3)\n"
4168+ " movl %%edx, %%es:12(%3)\n"
4169 "4: movl 16(%4), %%eax\n"
4170 "41: movl 20(%4), %%edx\n"
4171- " movl %%eax, 16(%3)\n"
4172- " movl %%edx, 20(%3)\n"
4173+ " movl %%eax, %%es:16(%3)\n"
4174+ " movl %%edx, %%es:20(%3)\n"
4175 "10: movl 24(%4), %%eax\n"
4176 "51: movl 28(%4), %%edx\n"
4177- " movl %%eax, 24(%3)\n"
4178- " movl %%edx, 28(%3)\n"
4179+ " movl %%eax, %%es:24(%3)\n"
4180+ " movl %%edx, %%es:28(%3)\n"
4181 "11: movl 32(%4), %%eax\n"
4182 "61: movl 36(%4), %%edx\n"
4183- " movl %%eax, 32(%3)\n"
4184- " movl %%edx, 36(%3)\n"
4185+ " movl %%eax, %%es:32(%3)\n"
4186+ " movl %%edx, %%es:36(%3)\n"
4187 "12: movl 40(%4), %%eax\n"
4188 "71: movl 44(%4), %%edx\n"
4189- " movl %%eax, 40(%3)\n"
4190- " movl %%edx, 44(%3)\n"
4191+ " movl %%eax, %%es:40(%3)\n"
4192+ " movl %%edx, %%es:44(%3)\n"
4193 "13: movl 48(%4), %%eax\n"
4194 "81: movl 52(%4), %%edx\n"
4195- " movl %%eax, 48(%3)\n"
4196- " movl %%edx, 52(%3)\n"
4197+ " movl %%eax, %%es:48(%3)\n"
4198+ " movl %%edx, %%es:52(%3)\n"
4199 "14: movl 56(%4), %%eax\n"
4200 "91: movl 60(%4), %%edx\n"
4201- " movl %%eax, 56(%3)\n"
4202- " movl %%edx, 60(%3)\n"
4203+ " movl %%eax, %%es:56(%3)\n"
4204+ " movl %%edx, %%es:60(%3)\n"
4205 " addl $-64, %0\n"
4206 " addl $64, %4\n"
4207 " addl $64, %3\n"
4208@@ -387,6 +514,8 @@ __copy_user_zeroing_intel(void *to, cons
4209 " movl %%eax,%0\n"
4210 "7: rep; movsb\n"
4211 "8:\n"
4212+ " pushl %%ss\n"
4213+ " popl %%ds\n"
4214 ".section .fixup,\"ax\"\n"
4215 "9: lea 0(%%eax,%0,4),%0\n"
4216 "16: pushl %0\n"
4217@@ -421,7 +550,7 @@ __copy_user_zeroing_intel(void *to, cons
4218 " .long 7b,16b\n"
4219 ".previous"
4220 : "=&c"(size), "=&D" (d0), "=&S" (d1)
4221- : "1"(to), "2"(from), "0"(size)
4222+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4223 : "eax", "edx", "memory");
4224 return size;
4225 }
4226@@ -437,6 +566,7 @@ static unsigned long __copy_user_zeroing
4227 int d0, d1;
4228
4229 __asm__ __volatile__(
4230+ " movw %w6, %%ds\n"
4231 " .align 2,0x90\n"
4232 "0: movl 32(%4), %%eax\n"
4233 " cmpl $67, %0\n"
4234@@ -445,36 +575,36 @@ static unsigned long __copy_user_zeroing
4235 " .align 2,0x90\n"
4236 "2: movl 0(%4), %%eax\n"
4237 "21: movl 4(%4), %%edx\n"
4238- " movnti %%eax, 0(%3)\n"
4239- " movnti %%edx, 4(%3)\n"
4240+ " movnti %%eax, %%es:0(%3)\n"
4241+ " movnti %%edx, %%es:4(%3)\n"
4242 "3: movl 8(%4), %%eax\n"
4243 "31: movl 12(%4),%%edx\n"
4244- " movnti %%eax, 8(%3)\n"
4245- " movnti %%edx, 12(%3)\n"
4246+ " movnti %%eax, %%es:8(%3)\n"
4247+ " movnti %%edx, %%es:12(%3)\n"
4248 "4: movl 16(%4), %%eax\n"
4249 "41: movl 20(%4), %%edx\n"
4250- " movnti %%eax, 16(%3)\n"
4251- " movnti %%edx, 20(%3)\n"
4252+ " movnti %%eax, %%es:16(%3)\n"
4253+ " movnti %%edx, %%es:20(%3)\n"
4254 "10: movl 24(%4), %%eax\n"
4255 "51: movl 28(%4), %%edx\n"
4256- " movnti %%eax, 24(%3)\n"
4257- " movnti %%edx, 28(%3)\n"
4258+ " movnti %%eax, %%es:24(%3)\n"
4259+ " movnti %%edx, %%es:28(%3)\n"
4260 "11: movl 32(%4), %%eax\n"
4261 "61: movl 36(%4), %%edx\n"
4262- " movnti %%eax, 32(%3)\n"
4263- " movnti %%edx, 36(%3)\n"
4264+ " movnti %%eax, %%es:32(%3)\n"
4265+ " movnti %%edx, %%es:36(%3)\n"
4266 "12: movl 40(%4), %%eax\n"
4267 "71: movl 44(%4), %%edx\n"
4268- " movnti %%eax, 40(%3)\n"
4269- " movnti %%edx, 44(%3)\n"
4270+ " movnti %%eax, %%es:40(%3)\n"
4271+ " movnti %%edx, %%es:44(%3)\n"
4272 "13: movl 48(%4), %%eax\n"
4273 "81: movl 52(%4), %%edx\n"
4274- " movnti %%eax, 48(%3)\n"
4275- " movnti %%edx, 52(%3)\n"
4276+ " movnti %%eax, %%es:48(%3)\n"
4277+ " movnti %%edx, %%es:52(%3)\n"
4278 "14: movl 56(%4), %%eax\n"
4279 "91: movl 60(%4), %%edx\n"
4280- " movnti %%eax, 56(%3)\n"
4281- " movnti %%edx, 60(%3)\n"
4282+ " movnti %%eax, %%es:56(%3)\n"
4283+ " movnti %%edx, %%es:60(%3)\n"
4284 " addl $-64, %0\n"
4285 " addl $64, %4\n"
4286 " addl $64, %3\n"
4287@@ -489,6 +619,8 @@ static unsigned long __copy_user_zeroing
4288 " movl %%eax,%0\n"
4289 "7: rep; movsb\n"
4290 "8:\n"
4291+ " pushl %%ss\n"
4292+ " popl %%ds\n"
4293 ".section .fixup,\"ax\"\n"
4294 "9: lea 0(%%eax,%0,4),%0\n"
4295 "16: pushl %0\n"
4296@@ -523,7 +655,7 @@ static unsigned long __copy_user_zeroing
4297 " .long 7b,16b\n"
4298 ".previous"
4299 : "=&c"(size), "=&D" (d0), "=&S" (d1)
4300- : "1"(to), "2"(from), "0"(size)
4301+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4302 : "eax", "edx", "memory");
4303 return size;
4304 }
4305@@ -534,6 +666,7 @@ static unsigned long __copy_user_intel_n
4306 int d0, d1;
4307
4308 __asm__ __volatile__(
4309+ " movw %w6, %%ds\n"
4310 " .align 2,0x90\n"
4311 "0: movl 32(%4), %%eax\n"
4312 " cmpl $67, %0\n"
4313@@ -542,36 +675,36 @@ static unsigned long __copy_user_intel_n
4314 " .align 2,0x90\n"
4315 "2: movl 0(%4), %%eax\n"
4316 "21: movl 4(%4), %%edx\n"
4317- " movnti %%eax, 0(%3)\n"
4318- " movnti %%edx, 4(%3)\n"
4319+ " movnti %%eax, %%es:0(%3)\n"
4320+ " movnti %%edx, %%es:4(%3)\n"
4321 "3: movl 8(%4), %%eax\n"
4322 "31: movl 12(%4),%%edx\n"
4323- " movnti %%eax, 8(%3)\n"
4324- " movnti %%edx, 12(%3)\n"
4325+ " movnti %%eax, %%es:8(%3)\n"
4326+ " movnti %%edx, %%es:12(%3)\n"
4327 "4: movl 16(%4), %%eax\n"
4328 "41: movl 20(%4), %%edx\n"
4329- " movnti %%eax, 16(%3)\n"
4330- " movnti %%edx, 20(%3)\n"
4331+ " movnti %%eax, %%es:16(%3)\n"
4332+ " movnti %%edx, %%es:20(%3)\n"
4333 "10: movl 24(%4), %%eax\n"
4334 "51: movl 28(%4), %%edx\n"
4335- " movnti %%eax, 24(%3)\n"
4336- " movnti %%edx, 28(%3)\n"
4337+ " movnti %%eax, %%es:24(%3)\n"
4338+ " movnti %%edx, %%es:28(%3)\n"
4339 "11: movl 32(%4), %%eax\n"
4340 "61: movl 36(%4), %%edx\n"
4341- " movnti %%eax, 32(%3)\n"
4342- " movnti %%edx, 36(%3)\n"
4343+ " movnti %%eax, %%es:32(%3)\n"
4344+ " movnti %%edx, %%es:36(%3)\n"
4345 "12: movl 40(%4), %%eax\n"
4346 "71: movl 44(%4), %%edx\n"
4347- " movnti %%eax, 40(%3)\n"
4348- " movnti %%edx, 44(%3)\n"
4349+ " movnti %%eax, %%es:40(%3)\n"
4350+ " movnti %%edx, %%es:44(%3)\n"
4351 "13: movl 48(%4), %%eax\n"
4352 "81: movl 52(%4), %%edx\n"
4353- " movnti %%eax, 48(%3)\n"
4354- " movnti %%edx, 52(%3)\n"
4355+ " movnti %%eax, %%es:48(%3)\n"
4356+ " movnti %%edx, %%es:52(%3)\n"
4357 "14: movl 56(%4), %%eax\n"
4358 "91: movl 60(%4), %%edx\n"
4359- " movnti %%eax, 56(%3)\n"
4360- " movnti %%edx, 60(%3)\n"
4361+ " movnti %%eax, %%es:56(%3)\n"
4362+ " movnti %%edx, %%es:60(%3)\n"
4363 " addl $-64, %0\n"
4364 " addl $64, %4\n"
4365 " addl $64, %3\n"
4366@@ -586,6 +719,8 @@ static unsigned long __copy_user_intel_n
4367 " movl %%eax,%0\n"
4368 "7: rep; movsb\n"
4369 "8:\n"
4370+ " pushl %%ss\n"
4371+ " popl %%ds\n"
4372 ".section .fixup,\"ax\"\n"
4373 "9: lea 0(%%eax,%0,4),%0\n"
4374 "16: jmp 8b\n"
4375@@ -614,7 +749,7 @@ static unsigned long __copy_user_intel_n
4376 " .long 7b,16b\n"
4377 ".previous"
4378 : "=&c"(size), "=&D" (d0), "=&S" (d1)
4379- : "1"(to), "2"(from), "0"(size)
4380+ : "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4381 : "eax", "edx", "memory");
4382 return size;
4383 }
4384@@ -627,90 +762,146 @@ static unsigned long __copy_user_intel_n
4385 */
4386 unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
4387 unsigned long size);
4388-unsigned long __copy_user_intel(void __user *to, const void *from,
4389+unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
4390+ unsigned long size);
4391+unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
4392 unsigned long size);
4393 unsigned long __copy_user_zeroing_intel_nocache(void *to,
4394 const void __user *from, unsigned long size);
4395 #endif /* CONFIG_X86_INTEL_USERCOPY */
4396
4397 /* Generic arbitrary sized copy. */
4398-#define __copy_user(to,from,size) \
4399-do { \
4400- int __d0, __d1, __d2; \
4401- __asm__ __volatile__( \
4402- " cmp $7,%0\n" \
4403- " jbe 1f\n" \
4404- " movl %1,%0\n" \
4405- " negl %0\n" \
4406- " andl $7,%0\n" \
4407- " subl %0,%3\n" \
4408- "4: rep; movsb\n" \
4409- " movl %3,%0\n" \
4410- " shrl $2,%0\n" \
4411- " andl $3,%3\n" \
4412- " .align 2,0x90\n" \
4413- "0: rep; movsl\n" \
4414- " movl %3,%0\n" \
4415- "1: rep; movsb\n" \
4416- "2:\n" \
4417- ".section .fixup,\"ax\"\n" \
4418- "5: addl %3,%0\n" \
4419- " jmp 2b\n" \
4420- "3: lea 0(%3,%0,4),%0\n" \
4421- " jmp 2b\n" \
4422- ".previous\n" \
4423- ".section __ex_table,\"a\"\n" \
4424- " .align 4\n" \
4425- " .long 4b,5b\n" \
4426- " .long 0b,3b\n" \
4427- " .long 1b,2b\n" \
4428- ".previous" \
4429- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
4430- : "3"(size), "0"(size), "1"(to), "2"(from) \
4431- : "memory"); \
4432-} while (0)
4433-
4434-#define __copy_user_zeroing(to,from,size) \
4435-do { \
4436- int __d0, __d1, __d2; \
4437- __asm__ __volatile__( \
4438- " cmp $7,%0\n" \
4439- " jbe 1f\n" \
4440- " movl %1,%0\n" \
4441- " negl %0\n" \
4442- " andl $7,%0\n" \
4443- " subl %0,%3\n" \
4444- "4: rep; movsb\n" \
4445- " movl %3,%0\n" \
4446- " shrl $2,%0\n" \
4447- " andl $3,%3\n" \
4448- " .align 2,0x90\n" \
4449- "0: rep; movsl\n" \
4450- " movl %3,%0\n" \
4451- "1: rep; movsb\n" \
4452- "2:\n" \
4453- ".section .fixup,\"ax\"\n" \
4454- "5: addl %3,%0\n" \
4455- " jmp 6f\n" \
4456- "3: lea 0(%3,%0,4),%0\n" \
4457- "6: pushl %0\n" \
4458- " pushl %%eax\n" \
4459- " xorl %%eax,%%eax\n" \
4460- " rep; stosb\n" \
4461- " popl %%eax\n" \
4462- " popl %0\n" \
4463- " jmp 2b\n" \
4464- ".previous\n" \
4465- ".section __ex_table,\"a\"\n" \
4466- " .align 4\n" \
4467- " .long 4b,5b\n" \
4468- " .long 0b,3b\n" \
4469- " .long 1b,6b\n" \
4470- ".previous" \
4471- : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2) \
4472- : "3"(size), "0"(size), "1"(to), "2"(from) \
4473- : "memory"); \
4474-} while (0)
4475+static unsigned long
4476+__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
4477+{
4478+ int __d0, __d1, __d2;
4479+
4480+ __asm__ __volatile__(
4481+ " movw %w8,%%es\n"
4482+ " cmp $7,%0\n"
4483+ " jbe 1f\n"
4484+ " movl %1,%0\n"
4485+ " negl %0\n"
4486+ " andl $7,%0\n"
4487+ " subl %0,%3\n"
4488+ "4: rep; movsb\n"
4489+ " movl %3,%0\n"
4490+ " shrl $2,%0\n"
4491+ " andl $3,%3\n"
4492+ " .align 2,0x90\n"
4493+ "0: rep; movsl\n"
4494+ " movl %3,%0\n"
4495+ "1: rep; movsb\n"
4496+ "2:\n"
4497+ " pushl %%ss\n"
4498+ " popl %%es\n"
4499+ ".section .fixup,\"ax\"\n"
4500+ "5: addl %3,%0\n"
4501+ " jmp 2b\n"
4502+ "3: lea 0(%3,%0,4),%0\n"
4503+ " jmp 2b\n"
4504+ ".previous\n"
4505+ ".section __ex_table,\"a\"\n"
4506+ " .align 4\n"
4507+ " .long 4b,5b\n"
4508+ " .long 0b,3b\n"
4509+ " .long 1b,2b\n"
4510+ ".previous"
4511+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
4512+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
4513+ : "memory");
4514+ return size;
4515+}
4516+
4517+static unsigned long
4518+__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
4519+{
4520+ int __d0, __d1, __d2;
4521+
4522+ __asm__ __volatile__(
4523+ " movw %w8,%%ds\n"
4524+ " cmp $7,%0\n"
4525+ " jbe 1f\n"
4526+ " movl %1,%0\n"
4527+ " negl %0\n"
4528+ " andl $7,%0\n"
4529+ " subl %0,%3\n"
4530+ "4: rep; movsb\n"
4531+ " movl %3,%0\n"
4532+ " shrl $2,%0\n"
4533+ " andl $3,%3\n"
4534+ " .align 2,0x90\n"
4535+ "0: rep; movsl\n"
4536+ " movl %3,%0\n"
4537+ "1: rep; movsb\n"
4538+ "2:\n"
4539+ " pushl %%ss\n"
4540+ " popl %%ds\n"
4541+ ".section .fixup,\"ax\"\n"
4542+ "5: addl %3,%0\n"
4543+ " jmp 2b\n"
4544+ "3: lea 0(%3,%0,4),%0\n"
4545+ " jmp 2b\n"
4546+ ".previous\n"
4547+ ".section __ex_table,\"a\"\n"
4548+ " .align 4\n"
4549+ " .long 4b,5b\n"
4550+ " .long 0b,3b\n"
4551+ " .long 1b,2b\n"
4552+ ".previous"
4553+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
4554+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
4555+ : "memory");
4556+ return size;
4557+}
4558+
4559+static unsigned long
4560+__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
4561+{
4562+ int __d0, __d1, __d2;
4563+
4564+ __asm__ __volatile__(
4565+ " movw %w8,%%ds\n"
4566+ " cmp $7,%0\n"
4567+ " jbe 1f\n"
4568+ " movl %1,%0\n"
4569+ " negl %0\n"
4570+ " andl $7,%0\n"
4571+ " subl %0,%3\n"
4572+ "4: rep; movsb\n"
4573+ " movl %3,%0\n"
4574+ " shrl $2,%0\n"
4575+ " andl $3,%3\n"
4576+ " .align 2,0x90\n"
4577+ "0: rep; movsl\n"
4578+ " movl %3,%0\n"
4579+ "1: rep; movsb\n"
4580+ "2:\n"
4581+ " pushl %%ss\n"
4582+ " popl %%ds\n"
4583+ ".section .fixup,\"ax\"\n"
4584+ "5: addl %3,%0\n"
4585+ " jmp 6f\n"
4586+ "3: lea 0(%3,%0,4),%0\n"
4587+ "6: pushl %0\n"
4588+ " pushl %%eax\n"
4589+ " xorl %%eax,%%eax\n"
4590+ " rep; stosb\n"
4591+ " popl %%eax\n"
4592+ " popl %0\n"
4593+ " jmp 2b\n"
4594+ ".previous\n"
4595+ ".section __ex_table,\"a\"\n"
4596+ " .align 4\n"
4597+ " .long 4b,5b\n"
4598+ " .long 0b,3b\n"
4599+ " .long 1b,6b\n"
4600+ ".previous"
4601+ : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
4602+ : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
4603+ : "memory");
4604+ return size;
4605+}
4606
4607 unsigned long __copy_to_user_ll(void __user *to, const void *from,
4608 unsigned long n)
4609@@ -766,9 +957,9 @@ survive:
4610 }
4611 #endif
4612 if (movsl_is_ok(to, from, n))
4613- __copy_user(to, from, n);
4614+ n = __generic_copy_to_user(to, from, n);
4615 else
4616- n = __copy_user_intel(to, from, n);
4617+ n = __generic_copy_to_user_intel(to, from, n);
4618 return n;
4619 }
4620 EXPORT_SYMBOL(__copy_to_user_ll);
4621@@ -778,7 +969,7 @@ unsigned long __copy_from_user_ll(void *
4622 {
4623 BUG_ON((long)n < 0);
4624 if (movsl_is_ok(to, from, n))
4625- __copy_user_zeroing(to, from, n);
4626+ n = __copy_user_zeroing(to, from, n);
4627 else
4628 n = __copy_user_zeroing_intel(to, from, n);
4629 return n;
4630@@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
4631 {
4632 BUG_ON((long)n < 0);
4633 if (movsl_is_ok(to, from, n))
4634- __copy_user(to, from, n);
4635+ n = __generic_copy_from_user(to, from, n);
4636 else
4637- n = __copy_user_intel((void __user *)to,
4638- (const void *)from, n);
4639+ n = __generic_copy_from_user_intel(to, from, n);
4640 return n;
4641 }
4642 EXPORT_SYMBOL(__copy_from_user_ll_nozero);
4643@@ -804,11 +994,11 @@ unsigned long __copy_from_user_ll_nocach
4644 BUG_ON((long)n < 0);
4645 #ifdef CONFIG_X86_INTEL_USERCOPY
4646 if ( n > 64 && cpu_has_xmm2)
4647- n = __copy_user_zeroing_intel_nocache(to, from, n);
4648+ n = __copy_user_zeroing_intel_nocache(to, from, n);
4649 else
4650- __copy_user_zeroing(to, from, n);
4651+ n = __copy_user_zeroing(to, from, n);
4652 #else
4653- __copy_user_zeroing(to, from, n);
4654+ n = __copy_user_zeroing(to, from, n);
4655 #endif
4656 return n;
4657 }
4658@@ -819,11 +1009,11 @@ unsigned long __copy_from_user_ll_nocach
4659 BUG_ON((long)n < 0);
4660 #ifdef CONFIG_X86_INTEL_USERCOPY
4661 if ( n > 64 && cpu_has_xmm2)
4662- n = __copy_user_intel_nocache(to, from, n);
4663+ n = __copy_user_intel_nocache(to, from, n);
4664 else
4665- __copy_user(to, from, n);
4666+ n = __generic_copy_from_user(to, from, n);
4667 #else
4668- __copy_user(to, from, n);
4669+ n = __generic_copy_from_user(to, from, n);
4670 #endif
4671 return n;
4672 }
4673@@ -878,3 +1068,44 @@ copy_from_user(void *to, const void __us
4674 return n;
4675 }
4676 EXPORT_SYMBOL(copy_from_user);
4677+
4678+#ifdef CONFIG_PAX_MEMORY_UDEREF
4679+void __set_fs(mm_segment_t x, int cpu)
4680+{
4681+ unsigned long limit = x.seg;
4682+ __u32 a, b;
4683+
4684+ current_thread_info()->addr_limit = x;
4685+ if (likely(limit))
4686+ limit -= 1UL;
4687+
4688+ pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
4689+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
4690+}
4691+
4692+void set_fs(mm_segment_t x)
4693+{
4694+ int cpu = get_cpu();
4695+
4696+#ifdef CONFIG_PAX_KERNEXEC
4697+ unsigned long cr0;
4698+
4699+ pax_open_kernel(cr0);
4700+#endif
4701+
4702+ __set_fs(x, cpu);
4703+
4704+#ifdef CONFIG_PAX_KERNEXEC
4705+ pax_close_kernel(cr0);
4706+#endif
4707+
4708+ put_cpu_no_resched();
4709+}
4710+#else
4711+void set_fs(mm_segment_t x)
4712+{
4713+ current_thread_info()->addr_limit = x;
4714+}
4715+#endif
4716+
4717+EXPORT_SYMBOL(set_fs);
4718diff -urNp linux-2.6.19.1/arch/i386/mach-voyager/voyager_smp.c linux-2.6.19.1/arch/i386/mach-voyager/voyager_smp.c
4719--- linux-2.6.19.1/arch/i386/mach-voyager/voyager_smp.c 2006-11-29 16:57:37.000000000 -0500
4720+++ linux-2.6.19.1/arch/i386/mach-voyager/voyager_smp.c 2006-12-03 15:15:45.000000000 -0500
4721@@ -1305,7 +1305,7 @@ smp_local_timer_interrupt(void)
4722 per_cpu(prof_counter, cpu);
4723 }
4724
4725- update_process_times(user_mode_vm(get_irq_regs()));
4726+ update_process_times(user_mode(get_irq_regs()));
4727 }
4728
4729 if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
4730diff -urNp linux-2.6.19.1/arch/i386/mm/boot_ioremap.c linux-2.6.19.1/arch/i386/mm/boot_ioremap.c
4731--- linux-2.6.19.1/arch/i386/mm/boot_ioremap.c 2006-11-29 16:57:37.000000000 -0500
4732+++ linux-2.6.19.1/arch/i386/mm/boot_ioremap.c 2006-12-03 15:15:45.000000000 -0500
4733@@ -7,56 +7,35 @@
4734 * Written by Dave Hansen <haveblue@us.ibm.com>
4735 */
4736
4737-
4738-/*
4739- * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
4740- * keeps that from happenning. If anyone has a better way, I'm listening.
4741- *
4742- * boot_pte_t is defined only if this all works correctly
4743- */
4744-
4745-#undef CONFIG_X86_PAE
4746 #include <asm/page.h>
4747 #include <asm/pgtable.h>
4748 #include <asm/tlbflush.h>
4749 #include <linux/init.h>
4750 #include <linux/stddef.h>
4751
4752-/*
4753- * I'm cheating here. It is known that the two boot PTE pages are
4754- * allocated next to each other. I'm pretending that they're just
4755- * one big array.
4756- */
4757-
4758-#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
4759-
4760-static unsigned long boot_pte_index(unsigned long vaddr)
4761-{
4762- return __pa(vaddr) >> PAGE_SHIFT;
4763-}
4764-
4765-static inline boot_pte_t* boot_vaddr_to_pte(void *address)
4766-{
4767- boot_pte_t* boot_pg = (boot_pte_t*)pg0;
4768- return &boot_pg[boot_pte_index((unsigned long)address)];
4769-}
4770-
4771 /*
4772 * This is only for a caller who is clever enough to page-align
4773 * phys_addr and virtual_source, and who also has a preference
4774 * about which virtual address from which to steal ptes
4775 */
4776-static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
4777- void* virtual_source)
4778+static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages,
4779+ char* virtual_source)
4780 {
4781- boot_pte_t* pte;
4782- int i;
4783- char *vaddr = virtual_source;
4784+ pgd_t *pgd;
4785+ pud_t *pud;
4786+ pmd_t *pmd;
4787+ pte_t* pte;
4788+ unsigned int i;
4789+ unsigned long vaddr = (unsigned long)virtual_source;
4790+
4791+ pgd = pgd_offset_k(vaddr);
4792+ pud = pud_offset(pgd, vaddr);
4793+ pmd = pmd_offset(pud, vaddr);
4794+ pte = pte_offset_kernel(pmd, vaddr);
4795
4796- pte = boot_vaddr_to_pte(virtual_source);
4797 for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
4798 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
4799- __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
4800+ __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
4801 }
4802 }
4803
4804diff -urNp linux-2.6.19.1/arch/i386/mm/extable.c linux-2.6.19.1/arch/i386/mm/extable.c
4805--- linux-2.6.19.1/arch/i386/mm/extable.c 2006-11-29 16:57:37.000000000 -0500
4806+++ linux-2.6.19.1/arch/i386/mm/extable.c 2006-12-03 15:15:45.000000000 -0500
4807@@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
4808 const struct exception_table_entry *fixup;
4809
4810 #ifdef CONFIG_PNPBIOS
4811- if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
4812+ if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
4813 {
4814 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
4815 extern u32 pnp_bios_is_utter_crap;
4816diff -urNp linux-2.6.19.1/arch/i386/mm/fault.c linux-2.6.19.1/arch/i386/mm/fault.c
4817--- linux-2.6.19.1/arch/i386/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
4818+++ linux-2.6.19.1/arch/i386/mm/fault.c 2006-12-03 15:15:45.000000000 -0500
4819@@ -22,6 +22,9 @@
4820 #include <linux/highmem.h>
4821 #include <linux/module.h>
4822 #include <linux/kprobes.h>
4823+#include <linux/unistd.h>
4824+#include <linux/compiler.h>
4825+#include <linux/binfmts.h>
4826
4827 #include <asm/system.h>
4828 #include <asm/uaccess.h>
4829@@ -104,7 +107,8 @@ static inline unsigned long get_segment_
4830 {
4831 unsigned long eip = regs->eip;
4832 unsigned seg = regs->xcs & 0xffff;
4833- u32 seg_ar, seg_limit, base, *desc;
4834+ u32 seg_ar, seg_limit, base;
4835+ struct desc_struct *desc;
4836
4837 /* Unlikely, but must come before segment checks. */
4838 if (unlikely(regs->eflags & VM_MASK)) {
4839@@ -118,7 +122,7 @@ static inline unsigned long get_segment_
4840
4841 /* By far the most common cases. */
4842 if (likely(SEGMENT_IS_FLAT_CODE(seg)))
4843- return eip;
4844+ return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
4845
4846 /* Check the segment exists, is within the current LDT/GDT size,
4847 that kernel/user (ring 0..3) has the appropriate privilege,
4848@@ -136,16 +140,14 @@ static inline unsigned long get_segment_
4849 if (seg & (1<<2)) {
4850 /* Must lock the LDT while reading it. */
4851 down(&current->mm->context.sem);
4852- desc = current->mm->context.ldt;
4853- desc = (void *)desc + (seg & ~7);
4854+ desc = &current->mm->context.ldt[seg >> 3];
4855 } else {
4856 /* Must disable preemption while reading the GDT. */
4857- desc = (u32 *)get_cpu_gdt_table(get_cpu());
4858- desc = (void *)desc + (seg & ~7);
4859+ desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
4860 }
4861
4862 /* Decode the code segment base from the descriptor */
4863- base = get_desc_base((unsigned long *)desc);
4864+ base = get_desc_base(desc);
4865
4866 if (seg & (1<<2)) {
4867 up(&current->mm->context.sem);
4868@@ -246,6 +248,30 @@ static noinline void force_sig_info_faul
4869
4870 fastcall void do_invalid_op(struct pt_regs *, unsigned long);
4871
4872+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
4873+static int pax_handle_fetch_fault(struct pt_regs *regs);
4874+#endif
4875+
4876+#ifdef CONFIG_PAX_PAGEEXEC
4877+static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
4878+{
4879+ pgd_t *pgd;
4880+ pud_t *pud;
4881+ pmd_t *pmd;
4882+
4883+ pgd = pgd_offset(mm, address);
4884+ if (!pgd_present(*pgd))
4885+ return NULL;
4886+ pud = pud_offset(pgd, address);
4887+ if (!pud_present(*pud))
4888+ return NULL;
4889+ pmd = pmd_offset(pud, address);
4890+ if (!pmd_present(*pmd))
4891+ return NULL;
4892+ return pmd;
4893+}
4894+#endif
4895+
4896 static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
4897 {
4898 unsigned index = pgd_index(address);
4899@@ -326,14 +352,20 @@ fastcall void __kprobes do_page_fault(st
4900 struct task_struct *tsk;
4901 struct mm_struct *mm;
4902 struct vm_area_struct * vma;
4903- unsigned long address;
4904- unsigned long page;
4905 int write, si_code;
4906
4907+#ifdef CONFIG_PAX_PAGEEXEC
4908+ pmd_t *pmd;
4909+ pte_t *pte;
4910+ spinlock_t *ptl;
4911+ unsigned char pte_mask;
4912+#endif
4913+
4914 /* get the address */
4915- address = read_cr2();
4916+ const unsigned long address = read_cr2();
4917
4918 tsk = current;
4919+ mm = tsk->mm;
4920
4921 si_code = SEGV_MAPERR;
4922
4923@@ -372,14 +404,12 @@ fastcall void __kprobes do_page_fault(st
4924 if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
4925 local_irq_enable();
4926
4927- mm = tsk->mm;
4928-
4929 /*
4930 * If we're in an interrupt, have no user context or are running in an
4931 * atomic region then we must not take the fault..
4932 */
4933 if (in_atomic() || !mm)
4934- goto bad_area_nosemaphore;
4935+ goto bad_area_nopax;
4936
4937 /* When running in the kernel we expect faults to occur only to
4938 * addresses in user space. All other faults represent errors in the
4939@@ -399,10 +429,101 @@ fastcall void __kprobes do_page_fault(st
4940 if (!down_read_trylock(&mm->mmap_sem)) {
4941 if ((error_code & 4) == 0 &&
4942 !search_exception_tables(regs->eip))
4943- goto bad_area_nosemaphore;
4944+ goto bad_area_nopax;
4945 down_read(&mm->mmap_sem);
4946 }
4947
4948+#ifdef CONFIG_PAX_PAGEEXEC
4949+ if (unlikely((error_code & 5) != 5 ||
4950+ (regs->eflags & X86_EFLAGS_VM) ||
4951+ !(mm->pax_flags & MF_PAX_PAGEEXEC)))
4952+ goto not_pax_fault;
4953+
4954+ /* PaX: it's our fault, let's handle it if we can */
4955+
4956+ /* PaX: take a look at read faults before acquiring any locks */
4957+ if (unlikely(!(error_code & 2) && (regs->eip == address))) {
4958+ /* instruction fetch attempt from a protected page in user mode */
4959+ up_read(&mm->mmap_sem);
4960+
4961+#ifdef CONFIG_PAX_EMUTRAMP
4962+ switch (pax_handle_fetch_fault(regs)) {
4963+ case 2:
4964+ return;
4965+ }
4966+#endif
4967+
4968+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
4969+ do_exit(SIGKILL);
4970+ }
4971+
4972+ pmd = pax_get_pmd(mm, address);
4973+ if (unlikely(!pmd))
4974+ goto not_pax_fault;
4975+
4976+ pte = pte_offset_map_lock(mm, pmd, address, &ptl);
4977+ if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
4978+ pte_unmap_unlock(pte, ptl);
4979+ goto not_pax_fault;
4980+ }
4981+
4982+ if (unlikely((error_code & 2) && !pte_write(*pte))) {
4983+ /* write attempt to a protected page in user mode */
4984+ pte_unmap_unlock(pte, ptl);
4985+ goto not_pax_fault;
4986+ }
4987+
4988+#ifdef CONFIG_SMP
4989+ if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
4990+#else
4991+ if (likely(address > get_limit(regs->xcs)))
4992+#endif
4993+ {
4994+ set_pte(pte, pte_mkread(*pte));
4995+ __flush_tlb_one(address);
4996+ pte_unmap_unlock(pte, ptl);
4997+ up_read(&mm->mmap_sem);
4998+ return;
4999+ }
5000+
5001+ pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
5002+
5003+ /*
5004+ * PaX: fill DTLB with user rights and retry
5005+ */
5006+ __asm__ __volatile__ (
5007+ "movw %w4,%%ds\n"
5008+ "orb %2,%%ss:(%1)\n"
5009+#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
5010+/*
5011+ * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
5012+ * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
5013+ * page fault when examined during a TLB load attempt. this is true not only
5014+ * for PTEs holding a non-present entry but also present entries that will
5015+ * raise a page fault (such as those set up by PaX, or the copy-on-write
5016+ * mechanism). in effect it means that we do *not* need to flush the TLBs
5017+ * for our target pages since their PTEs are simply not in the TLBs at all.
5018+
5019+ * the best thing in omitting it is that we gain around 15-20% speed in the
5020+ * fast path of the page fault handler and can get rid of tracing since we
5021+ * can no longer flush unintended entries.
5022+ */
5023+ "invlpg (%0)\n"
5024+#endif
5025+ "testb $0,(%0)\n"
5026+ "xorb %3,%%ss:(%1)\n"
5027+ "pushl %%ss\n"
5028+ "popl %%ds\n"
5029+ :
5030+ : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
5031+ : "memory", "cc");
5032+ pte_unmap_unlock(pte, ptl);
5033+ up_read(&mm->mmap_sem);
5034+ return;
5035+
5036+not_pax_fault:
5037+#endif
5038+
5039 vma = find_vma(mm, address);
5040 if (!vma)
5041 goto bad_area;
5042@@ -484,6 +605,36 @@ bad_area:
5043 up_read(&mm->mmap_sem);
5044
5045 bad_area_nosemaphore:
5046+
5047+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5048+ if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
5049+
5050+#ifdef CONFIG_PAX_PAGEEXEC
5051+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
5052+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5053+ do_exit(SIGKILL);
5054+ }
5055+#endif
5056+
5057+#ifdef CONFIG_PAX_SEGMEXEC
5058+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
5059+
5060+#ifdef CONFIG_PAX_EMUTRAMP
5061+ switch (pax_handle_fetch_fault(regs)) {
5062+ case 2:
5063+ return;
5064+ }
5065+#endif
5066+
5067+ pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5068+ do_exit(SIGKILL);
5069+ }
5070+#endif
5071+
5072+ }
5073+#endif
5074+
5075+bad_area_nopax:
5076 /* User mode accesses just cause a SIGSEGV */
5077 if (error_code & 4) {
5078 /*
5079@@ -551,6 +702,22 @@ no_context:
5080 if (address < PAGE_SIZE)
5081 printk(KERN_ALERT "BUG: unable to handle kernel NULL "
5082 "pointer dereference");
5083+
5084+#ifdef CONFIG_PAX_KERNEXEC
5085+#ifdef CONFIG_MODULES
5086+ else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END) {
5087+#else
5088+ else if (init_mm.start_code <= address && address < init_mm.end_code) {
5089+#endif
5090+ if (tsk->signal->curr_ip)
5091+ printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5092+ NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5093+ else
5094+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5095+ tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5096+ }
5097+#endif
5098+
5099 else
5100 printk(KERN_ALERT "BUG: unable to handle kernel paging"
5101 " request");
5102@@ -558,24 +725,34 @@ no_context:
5103 printk(KERN_ALERT " printing eip:\n");
5104 printk("%08lx\n", regs->eip);
5105 }
5106- page = read_cr3();
5107- page = ((unsigned long *) __va(page))[address >> 22];
5108- if (oops_may_print())
5109- printk(KERN_ALERT "*pde = %08lx\n", page);
5110- /*
5111- * We must not directly access the pte in the highpte
5112- * case, the page table might be allocated in highmem.
5113- * And lets rather not kmap-atomic the pte, just in case
5114- * it's allocated already.
5115- */
5116+
5117+ if (oops_may_print()) {
5118+ unsigned long index = pgd_index(address);
5119+ pgd_t *pgd;
5120+ pud_t *pud;
5121+ pmd_t *pmd;
5122+ pte_t *pte;
5123+
5124+ pgd = index + (pgd_t *)__va(read_cr3());
5125+ printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
5126+ if (pgd_present(*pgd)) {
5127+ pud = pud_offset(pgd, address);
5128+ pmd = pmd_offset(pud, address);
5129+ printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
5130+ /*
5131+ * We must not directly access the pte in the highpte
5132+ * case, the page table might be allocated in highmem.
5133+ * And lets rather not kmap-atomic the pte, just in case
5134+ * it's allocated already.
5135+ */
5136 #ifndef CONFIG_HIGHPTE
5137- if ((page & 1) && oops_may_print()) {
5138- page &= PAGE_MASK;
5139- address &= 0x003ff000;
5140- page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
5141- printk(KERN_ALERT "*pte = %08lx\n", page);
5142- }
5143+ if (pmd_present(*pmd) && !pmd_large(*pmd)) {
5144+ pte = pte_offset_kernel(pmd, address);
5145+ printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
5146+ }
5147 #endif
5148+ }
5149+ }
5150 tsk->thread.cr2 = address;
5151 tsk->thread.trap_no = 14;
5152 tsk->thread.error_code = error_code;
5153@@ -652,3 +829,101 @@ void vmalloc_sync_all(void)
5154 }
5155 }
5156 #endif
5157+
5158+#ifdef CONFIG_PAX_EMUTRAMP
5159+/*
5160+ * PaX: decide what to do with offenders (regs->eip = fault address)
5161+ *
5162+ * returns 1 when task should be killed
5163+ * 2 when gcc trampoline was detected
5164+ */
5165+static int pax_handle_fetch_fault(struct pt_regs *regs)
5166+{
5167+
5168+ static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
5169+ int err;
5170+
5171+ if (regs->eflags & X86_EFLAGS_VM)
5172+ return 1;
5173+
5174+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
5175+ return 1;
5176+
5177+ do { /* PaX: gcc trampoline emulation #1 */
5178+ unsigned char mov1, mov2;
5179+ unsigned short jmp;
5180+ unsigned long addr1, addr2;
5181+
5182+ err = get_user(mov1, (unsigned char __user *)regs->eip);
5183+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
5184+ err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
5185+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
5186+ err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
5187+
5188+ if (err)
5189+ break;
5190+
5191+ if ((mov1 & 0xF8) == 0xB8 &&
5192+ (mov2 & 0xF8) == 0xB8 &&
5193+ (mov1 & 0x07) != (mov2 & 0x07) &&
5194+ (jmp & 0xF8FF) == 0xE0FF &&
5195+ (mov2 & 0x07) == ((jmp>>8) & 0x07))
5196+ {
5197+ ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
5198+ ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
5199+ regs->eip = addr2;
5200+ return 2;
5201+ }
5202+ } while (0);
5203+
5204+ do { /* PaX: gcc trampoline emulation #2 */
5205+ unsigned char mov, jmp;
5206+ unsigned long addr1, addr2;
5207+
5208+ err = get_user(mov, (unsigned char __user *)regs->eip);
5209+ err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
5210+ err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
5211+ err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
5212+
5213+ if (err)
5214+ break;
5215+
5216+ if ((mov & 0xF8) == 0xB8 &&
5217+ jmp == 0xE9)
5218+ {
5219+ ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
5220+ regs->eip += addr2 + 10;
5221+ return 2;
5222+ }
5223+ } while (0);
5224+
5225+ return 1; /* PaX in action */
5226+}
5227+#endif
5228+
5229+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5230+void pax_report_insns(void *pc, void *sp)
5231+{
5232+ long i;
5233+
5234+ printk(KERN_ERR "PAX: bytes at PC: ");
5235+ for (i = 0; i < 20; i++) {
5236+ unsigned char c;
5237+ if (get_user(c, (unsigned char __user *)pc+i))
5238+ printk("?? ");
5239+ else
5240+ printk("%02x ", c);
5241+ }
5242+ printk("\n");
5243+
5244+ printk(KERN_ERR "PAX: bytes at SP-4: ");
5245+ for (i = -1; i < 20; i++) {
5246+ unsigned long c;
5247+ if (get_user(c, (unsigned long __user *)sp+i))
5248+ printk("???????? ");
5249+ else
5250+ printk("%08lx ", c);
5251+ }
5252+ printk("\n");
5253+}
5254+#endif
5255diff -urNp linux-2.6.19.1/arch/i386/mm/hugetlbpage.c linux-2.6.19.1/arch/i386/mm/hugetlbpage.c
5256--- linux-2.6.19.1/arch/i386/mm/hugetlbpage.c 2006-11-29 16:57:37.000000000 -0500
5257+++ linux-2.6.19.1/arch/i386/mm/hugetlbpage.c 2006-12-03 15:15:45.000000000 -0500
5258@@ -120,7 +120,12 @@ static unsigned long hugetlb_get_unmappe
5259 {
5260 struct mm_struct *mm = current->mm;
5261 struct vm_area_struct *vma;
5262- unsigned long start_addr;
5263+ unsigned long start_addr, task_size = TASK_SIZE;
5264+
5265+#ifdef CONFIG_PAX_SEGMEXEC
5266+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
5267+ task_size = SEGMEXEC_TASK_SIZE;
5268+#endif
5269
5270 if (len > mm->cached_hole_size) {
5271 start_addr = mm->free_area_cache;
5272@@ -134,7 +139,7 @@ full_search:
5273
5274 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
5275 /* At this point: (!vma || addr < vma->vm_end). */
5276- if (TASK_SIZE - len < addr) {
5277+ if (task_size - len < addr) {
5278 /*
5279 * Start a new search - just in case we missed
5280 * some holes.
5281@@ -162,9 +167,8 @@ static unsigned long hugetlb_get_unmappe
5282 {
5283 struct mm_struct *mm = current->mm;
5284 struct vm_area_struct *vma, *prev_vma;
5285- unsigned long base = mm->mmap_base, addr = addr0;
5286+ unsigned long base = mm->mmap_base, addr;
5287 unsigned long largest_hole = mm->cached_hole_size;
5288- int first_time = 1;
5289
5290 /* don't allow allocations above current base */
5291 if (mm->free_area_cache > base)
5292@@ -174,7 +178,7 @@ static unsigned long hugetlb_get_unmappe
5293 largest_hole = 0;
5294 mm->free_area_cache = base;
5295 }
5296-try_again:
5297+
5298 /* make sure it can fit in the remaining address space */
5299 if (mm->free_area_cache < len)
5300 goto fail;
5301@@ -216,16 +220,6 @@ try_again:
5302
5303 fail:
5304 /*
5305- * if hint left us with no space for the requested
5306- * mapping then try again:
5307- */
5308- if (first_time) {
5309- mm->free_area_cache = base;
5310- largest_hole = 0;
5311- first_time = 0;
5312- goto try_again;
5313- }
5314- /*
5315 * A failed mmap() very likely causes application failure,
5316 * so fall back to the bottom-up function here. This scenario
5317 * can happen with large stack limits and large mmap()
5318@@ -251,16 +245,23 @@ hugetlb_get_unmapped_area(struct file *f
5319 {
5320 struct mm_struct *mm = current->mm;
5321 struct vm_area_struct *vma;
5322+ unsigned long task_size = TASK_SIZE;
5323
5324 if (len & ~HPAGE_MASK)
5325 return -EINVAL;
5326- if (len > TASK_SIZE)
5327+
5328+#ifdef CONFIG_PAX_SEGMEXEC
5329+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
5330+ task_size = SEGMEXEC_TASK_SIZE;
5331+#endif
5332+
5333+ if (len > task_size || addr > task_size - len)
5334 return -ENOMEM;
5335
5336 if (addr) {
5337 addr = ALIGN(addr, HPAGE_SIZE);
5338 vma = find_vma(mm, addr);
5339- if (TASK_SIZE - len >= addr &&
5340+ if (task_size - len >= addr &&
5341 (!vma || addr + len <= vma->vm_start))
5342 return addr;
5343 }
5344diff -urNp linux-2.6.19.1/arch/i386/mm/init.c linux-2.6.19.1/arch/i386/mm/init.c
5345--- linux-2.6.19.1/arch/i386/mm/init.c 2006-11-29 16:57:37.000000000 -0500
5346+++ linux-2.6.19.1/arch/i386/mm/init.c 2006-12-03 15:15:45.000000000 -0500
5347@@ -42,6 +42,7 @@
5348 #include <asm/tlb.h>
5349 #include <asm/tlbflush.h>
5350 #include <asm/sections.h>
5351+#include <asm/desc.h>
5352
5353 unsigned int __VMALLOC_RESERVE = 128 << 20;
5354
5355@@ -51,30 +52,6 @@ unsigned long highstart_pfn, highend_pfn
5356 static int noinline do_test_wp_bit(void);
5357
5358 /*
5359- * Creates a middle page table and puts a pointer to it in the
5360- * given global directory entry. This only returns the gd entry
5361- * in non-PAE compilation mode, since the middle layer is folded.
5362- */
5363-static pmd_t * __init one_md_table_init(pgd_t *pgd)
5364-{
5365- pud_t *pud;
5366- pmd_t *pmd_table;
5367-
5368-#ifdef CONFIG_X86_PAE
5369- pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
5370- set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
5371- pud = pud_offset(pgd, 0);
5372- if (pmd_table != pmd_offset(pud, 0))
5373- BUG();
5374-#else
5375- pud = pud_offset(pgd, 0);
5376- pmd_table = pmd_offset(pud, 0);
5377-#endif
5378-
5379- return pmd_table;
5380-}
5381-
5382-/*
5383 * Create a page table and place a pointer to it in a middle page
5384 * directory entry.
5385 */
5386@@ -82,7 +59,11 @@ static pte_t * __init one_page_table_ini
5387 {
5388 if (pmd_none(*pmd)) {
5389 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
5390+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5391+ set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
5392+#else
5393 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
5394+#endif
5395 if (page_table != pte_offset_kernel(pmd, 0))
5396 BUG();
5397
5398@@ -117,8 +98,6 @@ static void __init page_table_range_init
5399 pgd = pgd_base + pgd_idx;
5400
5401 for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
5402- if (pgd_none(*pgd))
5403- one_md_table_init(pgd);
5404 pud = pud_offset(pgd, vaddr);
5405 pmd = pmd_offset(pud, vaddr);
5406 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
5407@@ -131,11 +110,22 @@ static void __init page_table_range_init
5408 }
5409 }
5410
5411-static inline int is_kernel_text(unsigned long addr)
5412+static inline int is_kernel_text(unsigned long start, unsigned long end)
5413 {
5414- if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
5415- return 1;
5416- return 0;
5417+ unsigned long etext;
5418+
5419+#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
5420+ etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
5421+#else
5422+ etext = (unsigned long)&_etext;
5423+#endif
5424+
5425+ if ((start > etext + __KERNEL_TEXT_OFFSET ||
5426+ end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
5427+ (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
5428+ end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
5429+ return 0;
5430+ return 1;
5431 }
5432
5433 /*
5434@@ -147,26 +137,24 @@ static void __init kernel_physical_mappi
5435 {
5436 unsigned long pfn;
5437 pgd_t *pgd;
5438+ pud_t *pud;
5439 pmd_t *pmd;
5440 pte_t *pte;
5441- int pgd_idx, pmd_idx, pte_ofs;
5442+ unsigned int pgd_idx, pmd_idx, pte_ofs;
5443
5444 pgd_idx = pgd_index(PAGE_OFFSET);
5445 pgd = pgd_base + pgd_idx;
5446 pfn = 0;
5447
5448- for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
5449- pmd = one_md_table_init(pgd);
5450- if (pfn >= max_low_pfn)
5451- continue;
5452+ for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
5453+ pud = pud_offset(pgd, 0);
5454+ pmd = pmd_offset(pud, 0);
5455 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
5456- unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
5457+ unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
5458
5459 /* Map with big pages if possible, otherwise create normal page tables. */
5460 if (cpu_has_pse) {
5461- unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
5462-
5463- if (is_kernel_text(address) || is_kernel_text(address2))
5464+ if (is_kernel_text(address, address + PMD_SIZE))
5465 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
5466 else
5467 set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
5468@@ -175,7 +163,7 @@ static void __init kernel_physical_mappi
5469 pte = one_page_table_init(pmd);
5470
5471 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
5472- if (is_kernel_text(address))
5473+ if (is_kernel_text(address, address + PAGE_SIZE))
5474 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
5475 else
5476 set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
5477@@ -342,13 +330,6 @@ static void __init pagetable_init (void)
5478 unsigned long vaddr;
5479 pgd_t *pgd_base = swapper_pg_dir;
5480
5481-#ifdef CONFIG_X86_PAE
5482- int i;
5483- /* Init entries of the first-level page table to the zero page */
5484- for (i = 0; i < PTRS_PER_PGD; i++)
5485- set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
5486-#endif
5487-
5488 /* Enable PSE if available */
5489 if (cpu_has_pse) {
5490 set_in_cr4(X86_CR4_PSE);
5491@@ -372,17 +353,6 @@ static void __init pagetable_init (void)
5492 page_table_range_init(vaddr, 0, pgd_base);
5493
5494 permanent_kmaps_init(pgd_base);
5495-
5496-#ifdef CONFIG_X86_PAE
5497- /*
5498- * Add low memory identity-mappings - SMP needs it when
5499- * starting up on an AP from real-mode. In the non-PAE
5500- * case we already have these mappings through head.S.
5501- * All user-space mappings are explicitly cleared after
5502- * SMP startup.
5503- */
5504- set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
5505-#endif
5506 }
5507
5508 #if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP)
5509@@ -424,7 +394,6 @@ void zap_low_mappings (void)
5510 flush_tlb_all();
5511 }
5512
5513-static int disable_nx __initdata = 0;
5514 u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
5515
5516 /*
5517@@ -438,13 +407,10 @@ u64 __supported_pte_mask __read_mostly =
5518 static int __init noexec_setup(char *str)
5519 {
5520 if (!str || !strcmp(str, "on")) {
5521- if (cpu_has_nx) {
5522- __supported_pte_mask |= _PAGE_NX;
5523- disable_nx = 0;
5524- }
5525+ if (cpu_has_nx)
5526+ nx_enabled = 1;
5527 } else if (!strcmp(str,"off")) {
5528- disable_nx = 1;
5529- __supported_pte_mask &= ~_PAGE_NX;
5530+ nx_enabled = 0;
5531 } else
5532 return -EINVAL;
5533
5534@@ -457,17 +423,13 @@ int nx_enabled = 0;
5535
5536 static void __init set_nx(void)
5537 {
5538- unsigned int v[4], l, h;
5539+ if (!nx_enabled && cpu_has_nx) {
5540+ unsigned l, h;
5541
5542- if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
5543- cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
5544- if ((v[3] & (1 << 20)) && !disable_nx) {
5545- rdmsr(MSR_EFER, l, h);
5546- l |= EFER_NX;
5547- wrmsr(MSR_EFER, l, h);
5548- nx_enabled = 1;
5549- __supported_pte_mask |= _PAGE_NX;
5550- }
5551+ __supported_pte_mask &= ~_PAGE_NX;
5552+ rdmsr(MSR_EFER, l, h);
5553+ l &= ~EFER_NX;
5554+ wrmsr(MSR_EFER, l, h);
5555 }
5556 }
5557
5558@@ -520,14 +482,6 @@ void __init paging_init(void)
5559
5560 load_cr3(swapper_pg_dir);
5561
5562-#ifdef CONFIG_X86_PAE
5563- /*
5564- * We will bail out later - printk doesn't work right now so
5565- * the user would just see a hanging kernel.
5566- */
5567- if (cpu_has_pae)
5568- set_in_cr4(X86_CR4_PAE);
5569-#endif
5570 __flush_tlb_all();
5571
5572 kmap_init();
5573@@ -598,7 +552,7 @@ void __init mem_init(void)
5574 set_highmem_pages_init(bad_ppro);
5575
5576 codesize = (unsigned long) &_etext - (unsigned long) &_text;
5577- datasize = (unsigned long) &_edata - (unsigned long) &_etext;
5578+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
5579 initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
5580
5581 kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
5582@@ -643,10 +597,10 @@ void __init mem_init(void)
5583 (unsigned long)&__init_begin, (unsigned long)&__init_end,
5584 ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
5585
5586- (unsigned long)&_etext, (unsigned long)&_edata,
5587- ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
5588+ (unsigned long)&_data, (unsigned long)&_edata,
5589+ ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
5590
5591- (unsigned long)&_text, (unsigned long)&_etext,
5592+ (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
5593 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
5594
5595 #ifdef CONFIG_HIGHMEM
5596@@ -657,10 +611,6 @@ void __init mem_init(void)
5597 BUG_ON((unsigned long)high_memory > VMALLOC_START);
5598 #endif /* double-sanity-check paranoia */
5599
5600-#ifdef CONFIG_X86_PAE
5601- if (!cpu_has_pae)
5602- panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
5603-#endif
5604 if (boot_cpu_data.wp_works_ok < 0)
5605 test_wp_bit();
5606
5607@@ -789,6 +739,38 @@ void free_init_pages(char *what, unsigne
5608
5609 void free_initmem(void)
5610 {
5611+
5612+#ifdef CONFIG_PAX_KERNEXEC
5613+ /* PaX: limit KERNEL_CS to actual size */
5614+ unsigned long addr, limit;
5615+ __u32 a, b;
5616+ int cpu;
5617+ pgd_t *pgd;
5618+ pud_t *pud;
5619+ pmd_t *pmd;
5620+
5621+#ifdef CONFIG_MODULES
5622+ limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
5623+#else
5624+ limit = (unsigned long)&_etext;
5625+#endif
5626+ limit = (limit - 1UL) >> PAGE_SHIFT;
5627+
5628+ for (cpu = 0; cpu < NR_CPUS; cpu++) {
5629+ pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
5630+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
5631+ }
5632+
5633+ /* PaX: make KERNEL_CS read-only */
5634+ for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
5635+ pgd = pgd_offset_k(addr);
5636+ pud = pud_offset(pgd, addr);
5637+ pmd = pmd_offset(pud, addr);
5638+ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
5639+ }
5640+ flush_tlb_all();
5641+#endif
5642+
5643 free_init_pages("unused kernel memory",
5644 (unsigned long)(&__init_begin),
5645 (unsigned long)(&__init_end));
5646diff -urNp linux-2.6.19.1/arch/i386/mm/mmap.c linux-2.6.19.1/arch/i386/mm/mmap.c
5647--- linux-2.6.19.1/arch/i386/mm/mmap.c 2006-11-29 16:57:37.000000000 -0500
5648+++ linux-2.6.19.1/arch/i386/mm/mmap.c 2006-12-03 15:15:45.000000000 -0500
5649@@ -34,12 +34,18 @@
5650 * Leave an at least ~128 MB hole.
5651 */
5652 #define MIN_GAP (128*1024*1024)
5653-#define MAX_GAP (TASK_SIZE/6*5)
5654+#define MAX_GAP (task_size/6*5)
5655
5656 static inline unsigned long mmap_base(struct mm_struct *mm)
5657 {
5658 unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
5659 unsigned long random_factor = 0;
5660+ unsigned long task_size = TASK_SIZE;
5661+
5662+#ifdef CONFIG_PAX_SEGMEXEC
5663+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
5664+ task_size = SEGMEXEC_TASK_SIZE;
5665+#endif
5666
5667 if (current->flags & PF_RANDOMIZE)
5668 random_factor = get_random_int() % (1024*1024);
5669@@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
5670 else if (gap > MAX_GAP)
5671 gap = MAX_GAP;
5672
5673- return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
5674+ return PAGE_ALIGN(task_size - gap - random_factor);
5675 }
5676
5677 /*
5678@@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
5679 (current->personality & ADDR_COMPAT_LAYOUT) ||
5680 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
5681 mm->mmap_base = TASK_UNMAPPED_BASE;
5682+
5683+#ifdef CONFIG_PAX_RANDMMAP
5684+ if (mm->pax_flags & MF_PAX_RANDMMAP)
5685+ mm->mmap_base += mm->delta_mmap;
5686+#endif
5687+
5688 mm->get_unmapped_area = arch_get_unmapped_area;
5689 mm->unmap_area = arch_unmap_area;
5690 } else {
5691 mm->mmap_base = mmap_base(mm);
5692+
5693+#ifdef CONFIG_PAX_RANDMMAP
5694+ if (mm->pax_flags & MF_PAX_RANDMMAP)
5695+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
5696+#endif
5697+
5698 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
5699 mm->unmap_area = arch_unmap_area_topdown;
5700 }
5701diff -urNp linux-2.6.19.1/arch/i386/mm/pageattr.c linux-2.6.19.1/arch/i386/mm/pageattr.c
5702--- linux-2.6.19.1/arch/i386/mm/pageattr.c 2006-11-29 16:57:37.000000000 -0500
5703+++ linux-2.6.19.1/arch/i386/mm/pageattr.c 2006-12-03 15:15:45.000000000 -0500
5704@@ -13,6 +13,7 @@
5705 #include <asm/tlbflush.h>
5706 #include <asm/pgalloc.h>
5707 #include <asm/sections.h>
5708+#include <asm/desc.h>
5709
5710 static DEFINE_SPINLOCK(cpa_lock);
5711 static struct list_head df_list = LIST_HEAD_INIT(df_list);
5712@@ -83,7 +84,18 @@ static void set_pmd_pte(pte_t *kpte, uns
5713 struct page *page;
5714 unsigned long flags;
5715
5716+#ifdef CONFIG_PAX_KERNEXEC
5717+ unsigned long cr0;
5718+
5719+ pax_open_kernel(cr0);
5720+#endif
5721+
5722 set_pte_atomic(kpte, pte); /* change init_mm */
5723+
5724+#ifdef CONFIG_PAX_KERNEXEC
5725+ pax_close_kernel(cr0);
5726+#endif
5727+
5728 if (PTRS_PER_PMD > 1)
5729 return;
5730
5731@@ -110,7 +122,7 @@ static inline void revert_page(struct pa
5732 pte_t *linear;
5733
5734 ref_prot =
5735- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
5736+ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
5737 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
5738
5739 linear = (pte_t *)
5740@@ -142,7 +154,7 @@ __change_page_attr(struct page *page, pg
5741 struct page *split;
5742
5743 ref_prot =
5744- ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
5745+ ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
5746 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
5747 split = split_large_page(address, prot, ref_prot);
5748 if (!split)
5749diff -urNp linux-2.6.19.1/arch/i386/oprofile/backtrace.c linux-2.6.19.1/arch/i386/oprofile/backtrace.c
5750--- linux-2.6.19.1/arch/i386/oprofile/backtrace.c 2006-11-29 16:57:37.000000000 -0500
5751+++ linux-2.6.19.1/arch/i386/oprofile/backtrace.c 2006-12-03 15:15:45.000000000 -0500
5752@@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
5753 head = (struct frame_head *)regs->ebp;
5754 #endif
5755
5756- if (!user_mode_vm(regs)) {
5757+ if (!user_mode(regs)) {
5758 while (depth-- && valid_kernel_stack(head, regs))
5759 head = dump_kernel_backtrace(head);
5760 return;
5761diff -urNp linux-2.6.19.1/arch/i386/oprofile/op_model_p4.c linux-2.6.19.1/arch/i386/oprofile/op_model_p4.c
5762--- linux-2.6.19.1/arch/i386/oprofile/op_model_p4.c 2006-11-29 16:57:37.000000000 -0500
5763+++ linux-2.6.19.1/arch/i386/oprofile/op_model_p4.c 2006-12-03 15:15:45.000000000 -0500
5764@@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
5765 #endif
5766 }
5767
5768-static int inline addr_increment(void)
5769+static inline int addr_increment(void)
5770 {
5771 #ifdef CONFIG_SMP
5772 return smp_num_siblings == 2 ? 2 : 1;
5773diff -urNp linux-2.6.19.1/arch/i386/pci/early.c linux-2.6.19.1/arch/i386/pci/early.c
5774--- linux-2.6.19.1/arch/i386/pci/early.c 2006-11-29 16:57:37.000000000 -0500
5775+++ linux-2.6.19.1/arch/i386/pci/early.c 2006-12-03 15:15:45.000000000 -0500
5776@@ -7,7 +7,7 @@
5777 /* Direct PCI access. This is used for PCI accesses in early boot before
5778 the PCI subsystem works. */
5779
5780-#define PDprintk(x...)
5781+#define PDprintk(x...) do {} while (0)
5782
5783 u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
5784 {
5785diff -urNp linux-2.6.19.1/arch/i386/power/cpu.c linux-2.6.19.1/arch/i386/power/cpu.c
5786--- linux-2.6.19.1/arch/i386/power/cpu.c 2006-11-29 16:57:37.000000000 -0500
5787+++ linux-2.6.19.1/arch/i386/power/cpu.c 2006-12-03 15:15:45.000000000 -0500
5788@@ -63,7 +63,7 @@ static void do_fpu_end(void)
5789 static void fix_processor_context(void)
5790 {
5791 int cpu = smp_processor_id();
5792- struct tss_struct * t = &per_cpu(init_tss, cpu);
5793+ struct tss_struct * t = init_tss + cpu;
5794
5795 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. */
5796
5797diff -urNp linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c
5798--- linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c 2006-11-29 16:57:37.000000000 -0500
5799+++ linux-2.6.19.1/arch/ia64/ia32/binfmt_elf32.c 2006-12-03 15:15:45.000000000 -0500
5800@@ -45,6 +45,17 @@ randomize_stack_top(unsigned long stack_
5801
5802 #define elf_read_implies_exec(ex, have_pt_gnu_stack) (!(have_pt_gnu_stack))
5803
5804+#ifdef CONFIG_PAX_ASLR
5805+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
5806+
5807+#define PAX_DELTA_MMAP_LSB(tsk) IA32_PAGE_SHIFT
5808+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5809+#define PAX_DELTA_EXEC_LSB(tsk) IA32_PAGE_SHIFT
5810+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5811+#define PAX_DELTA_STACK_LSB(tsk) IA32_PAGE_SHIFT
5812+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
5813+#endif
5814+
5815 /* Ugly but avoids duplication */
5816 #include "../../../fs/binfmt_elf.c"
5817
5818diff -urNp linux-2.6.19.1/arch/ia64/ia32/ia32priv.h linux-2.6.19.1/arch/ia64/ia32/ia32priv.h
5819--- linux-2.6.19.1/arch/ia64/ia32/ia32priv.h 2006-11-29 16:57:37.000000000 -0500
5820+++ linux-2.6.19.1/arch/ia64/ia32/ia32priv.h 2006-12-03 15:15:46.000000000 -0500
5821@@ -304,7 +304,14 @@ struct old_linux32_dirent {
5822 #define ELF_DATA ELFDATA2LSB
5823 #define ELF_ARCH EM_386
5824
5825-#define IA32_STACK_TOP IA32_PAGE_OFFSET
5826+#ifdef CONFIG_PAX_RANDUSTACK
5827+#define __IA32_DELTA_STACK (current->mm->delta_stack)
5828+#else
5829+#define __IA32_DELTA_STACK 0UL
5830+#endif
5831+
5832+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
5833+
5834 #define IA32_GATE_OFFSET IA32_PAGE_OFFSET
5835 #define IA32_GATE_END IA32_PAGE_OFFSET + PAGE_SIZE
5836
5837diff -urNp linux-2.6.19.1/arch/ia64/kernel/module.c linux-2.6.19.1/arch/ia64/kernel/module.c
5838--- linux-2.6.19.1/arch/ia64/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
5839+++ linux-2.6.19.1/arch/ia64/kernel/module.c 2006-12-03 15:15:46.000000000 -0500
5840@@ -321,7 +321,7 @@ module_alloc (unsigned long size)
5841 void
5842 module_free (struct module *mod, void *module_region)
5843 {
5844- if (mod->arch.init_unw_table && module_region == mod->module_init) {
5845+ if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
5846 unw_remove_unwind_table(mod->arch.init_unw_table);
5847 mod->arch.init_unw_table = NULL;
5848 }
5849@@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
5850 }
5851
5852 static inline int
5853+in_init_rx (const struct module *mod, uint64_t addr)
5854+{
5855+ return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
5856+}
5857+
5858+static inline int
5859+in_init_rw (const struct module *mod, uint64_t addr)
5860+{
5861+ return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
5862+}
5863+
5864+static inline int
5865 in_init (const struct module *mod, uint64_t addr)
5866 {
5867- return addr - (uint64_t) mod->module_init < mod->init_size;
5868+ return in_init_rx(mod, value) || in_init_rw(mod, value);
5869+}
5870+
5871+static inline int
5872+in_core_rx (const struct module *mod, uint64_t addr)
5873+{
5874+ return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
5875+}
5876+
5877+static inline int
5878+in_core_rw (const struct module *mod, uint64_t addr)
5879+{
5880+ return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
5881 }
5882
5883 static inline int
5884 in_core (const struct module *mod, uint64_t addr)
5885 {
5886- return addr - (uint64_t) mod->module_core < mod->core_size;
5887+ return in_core_rx(mod, value) || in_core_rw(mod, value);
5888 }
5889
5890 static inline int
5891@@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
5892 break;
5893
5894 case RV_BDREL:
5895- val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
5896+ if (in_init_rx(mod, val))
5897+ val -= (uint64_t) mod->module_init_rx;
5898+ else if (in_init_rw(mod, val))
5899+ val -= (uint64_t) mod->module_init_rw;
5900+ else if (in_core_rx(mod, val))
5901+ val -= (uint64_t) mod->module_core_rx;
5902+ else if (in_core_rw(mod, val))
5903+ val -= (uint64_t) mod->module_core_rw;
5904 break;
5905
5906 case RV_LTV:
5907@@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
5908 * addresses have been selected...
5909 */
5910 uint64_t gp;
5911- if (mod->core_size > MAX_LTOFF)
5912+ if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
5913 /*
5914 * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
5915 * at the end of the module.
5916 */
5917- gp = mod->core_size - MAX_LTOFF / 2;
5918+ gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
5919 else
5920- gp = mod->core_size / 2;
5921- gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
5922+ gp = (mod->core_size_rx + mod->core_size_rw) / 2;
5923+ gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
5924 mod->arch.gp = gp;
5925 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
5926 }
5927diff -urNp linux-2.6.19.1/arch/ia64/kernel/ptrace.c linux-2.6.19.1/arch/ia64/kernel/ptrace.c
5928--- linux-2.6.19.1/arch/ia64/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
5929+++ linux-2.6.19.1/arch/ia64/kernel/ptrace.c 2006-12-03 15:15:46.000000000 -0500
5930@@ -17,6 +17,7 @@
c3e8c1b5 5931 #include <linux/audit.h>
5932 #include <linux/signal.h>
b6fa5d20 5933 #include <linux/vs_base.h>
c3e8c1b5 5934+#include <linux/grsecurity.h>
5935
5936 #include <asm/pgtable.h>
5937 #include <asm/processor.h>
5938@@ -1446,6 +1447,9 @@ sys_ptrace (long request, pid_t pid, uns
5939 if (pid == 1) /* no messing around with init! */
5940 goto out_tsk;
5941
5942+ if (gr_handle_ptrace(child, request))
5943+ goto out_tsk;
5944+
5945 if (request == PTRACE_ATTACH) {
5946 ret = ptrace_attach(child);
5947 goto out_tsk;
5948diff -urNp linux-2.6.19.1/arch/ia64/kernel/sys_ia64.c linux-2.6.19.1/arch/ia64/kernel/sys_ia64.c
5949--- linux-2.6.19.1/arch/ia64/kernel/sys_ia64.c 2006-11-29 16:57:37.000000000 -0500
5950+++ linux-2.6.19.1/arch/ia64/kernel/sys_ia64.c 2006-12-03 15:15:46.000000000 -0500
5951@@ -37,6 +37,13 @@ arch_get_unmapped_area (struct file *fil
5952 if (REGION_NUMBER(addr) == RGN_HPAGE)
5953 addr = 0;
5954 #endif
5955+
5956+#ifdef CONFIG_PAX_RANDMMAP
5957+ if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
5958+ addr = mm->free_area_cache;
5959+ else
5960+#endif
5961+
5962 if (!addr)
5963 addr = mm->free_area_cache;
5964
5965@@ -55,9 +62,9 @@ arch_get_unmapped_area (struct file *fil
5966 for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
5967 /* At this point: (!vma || addr < vma->vm_end). */
5968 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
5969- if (start_addr != TASK_UNMAPPED_BASE) {
5970+ if (start_addr != mm->mmap_base) {
5971 /* Start a new search --- just in case we missed some holes. */
5972- addr = TASK_UNMAPPED_BASE;
5973+ addr = mm->mmap_base;
5974 goto full_search;
5975 }
5976 return -ENOMEM;
5977diff -urNp linux-2.6.19.1/arch/ia64/mm/fault.c linux-2.6.19.1/arch/ia64/mm/fault.c
5978--- linux-2.6.19.1/arch/ia64/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
5979+++ linux-2.6.19.1/arch/ia64/mm/fault.c 2006-12-03 15:15:46.000000000 -0500
5980@@ -10,6 +10,7 @@
c3e8c1b5 5981 #include <linux/interrupt.h>
5982 #include <linux/kprobes.h>
b6fa5d20 5983 #include <linux/vs_memory.h>
c3e8c1b5 5984+#include <linux/binfmts.h>
5985
5986 #include <asm/pgtable.h>
5987 #include <asm/processor.h>
5988@@ -85,6 +86,23 @@ mapped_kernel_page_is_present (unsigned
5989 return pte_present(pte);
5990 }
5991
5992+#ifdef CONFIG_PAX_PAGEEXEC
5993+void pax_report_insns(void *pc, void *sp)
5994+{
5995+ unsigned long i;
5996+
5997+ printk(KERN_ERR "PAX: bytes at PC: ");
5998+ for (i = 0; i < 8; i++) {
5999+ unsigned int c;
6000+ if (get_user(c, (unsigned int*)pc+i))
6001+ printk("???????? ");
6002+ else
6003+ printk("%08x ", c);
6004+ }
6005+ printk("\n");
6006+}
6007+#endif
6008+
6009 void __kprobes
6010 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
6011 {
6012@@ -152,9 +170,23 @@ ia64_do_page_fault (unsigned long addres
6013 mask = ( (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
6014 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
6015
6016- if ((vma->vm_flags & mask) != mask)
6017+ if ((vma->vm_flags & mask) != mask) {
6018+
6019+#ifdef CONFIG_PAX_PAGEEXEC
6020+ if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
6021+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
6022+ goto bad_area;
6023+
6024+ up_read(&mm->mmap_sem);
6025+ pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
6026+ do_exit(SIGKILL);
6027+ }
6028+#endif
6029+
6030 goto bad_area;
6031
6032+ }
6033+
6034 survive:
6035 /*
6036 * If for any reason at all we couldn't handle the fault, make
6037diff -urNp linux-2.6.19.1/arch/ia64/mm/init.c linux-2.6.19.1/arch/ia64/mm/init.c
6038--- linux-2.6.19.1/arch/ia64/mm/init.c 2006-11-29 16:57:37.000000000 -0500
6039+++ linux-2.6.19.1/arch/ia64/mm/init.c 2006-12-03 15:15:46.000000000 -0500
6040@@ -19,8 +19,8 @@
6041 #include <linux/swap.h>
6042 #include <linux/proc_fs.h>
6043 #include <linux/bitops.h>
6044+#include <linux/a.out.h>
6045
6046-#include <asm/a.out.h>
6047 #include <asm/dma.h>
6048 #include <asm/ia32.h>
6049 #include <asm/io.h>
6050diff -urNp linux-2.6.19.1/arch/mips/kernel/binfmt_elfn32.c linux-2.6.19.1/arch/mips/kernel/binfmt_elfn32.c
6051--- linux-2.6.19.1/arch/mips/kernel/binfmt_elfn32.c 2006-11-29 16:57:37.000000000 -0500
6052+++ linux-2.6.19.1/arch/mips/kernel/binfmt_elfn32.c 2006-12-03 15:15:49.000000000 -0500
6053@@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6054 #undef ELF_ET_DYN_BASE
6055 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6056
6057+#ifdef CONFIG_PAX_ASLR
6058+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6059+
6060+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
6061+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6062+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
6063+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6064+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
6065+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6066+#endif
6067+
6068 #include <asm/processor.h>
6069 #include <linux/module.h>
6070 #include <linux/elfcore.h>
6071diff -urNp linux-2.6.19.1/arch/mips/kernel/binfmt_elfo32.c linux-2.6.19.1/arch/mips/kernel/binfmt_elfo32.c
6072--- linux-2.6.19.1/arch/mips/kernel/binfmt_elfo32.c 2006-11-29 16:57:37.000000000 -0500
6073+++ linux-2.6.19.1/arch/mips/kernel/binfmt_elfo32.c 2006-12-03 15:15:49.000000000 -0500
6074@@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6075 #undef ELF_ET_DYN_BASE
6076 #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2)
6077
6078+#ifdef CONFIG_PAX_ASLR
6079+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6080+
6081+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
6082+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6083+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
6084+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6085+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
6086+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6087+#endif
6088+
6089 #include <asm/processor.h>
6090 #include <linux/module.h>
6091 #include <linux/elfcore.h>
6092diff -urNp linux-2.6.19.1/arch/mips/kernel/syscall.c linux-2.6.19.1/arch/mips/kernel/syscall.c
6093--- linux-2.6.19.1/arch/mips/kernel/syscall.c 2006-11-29 16:57:37.000000000 -0500
6094+++ linux-2.6.19.1/arch/mips/kernel/syscall.c 2006-12-03 15:15:49.000000000 -0500
6095@@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
6096 do_color_align = 0;
6097 if (filp || (flags & MAP_SHARED))
6098 do_color_align = 1;
6099+
6100+#ifdef CONFIG_PAX_RANDMMAP
6101+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6102+#endif
6103+
6104 if (addr) {
6105 if (do_color_align)
6106 addr = COLOUR_ALIGN(addr, pgoff);
6107@@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
6108 (!vmm || addr + len <= vmm->vm_start))
6109 return addr;
6110 }
6111- addr = TASK_UNMAPPED_BASE;
6112+ addr = current->mm->mmap_base;
6113 if (do_color_align)
6114 addr = COLOUR_ALIGN(addr, pgoff);
6115 else
6116diff -urNp linux-2.6.19.1/arch/mips/mm/fault.c linux-2.6.19.1/arch/mips/mm/fault.c
6117--- linux-2.6.19.1/arch/mips/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
6118+++ linux-2.6.19.1/arch/mips/mm/fault.c 2006-12-03 15:15:49.000000000 -0500
6119@@ -27,6 +27,23 @@
6120 #include <asm/ptrace.h>
6121 #include <asm/highmem.h> /* For VMALLOC_END */
6122
6123+#ifdef CONFIG_PAX_PAGEEXEC
6124+void pax_report_insns(void *pc)
6125+{
6126+ unsigned long i;
6127+
6128+ printk(KERN_ERR "PAX: bytes at PC: ");
6129+ for (i = 0; i < 5; i++) {
6130+ unsigned int c;
6131+ if (get_user(c, (unsigned int*)pc+i))
6132+ printk("???????? ");
6133+ else
6134+ printk("%08x ", c);
6135+ }
6136+ printk("\n");
6137+}
6138+#endif
6139+
6140 /*
6141 * This routine handles page faults. It determines the address,
6142 * and the problem, and then passes it off to one of the appropriate
6143diff -urNp linux-2.6.19.1/arch/parisc/kernel/module.c linux-2.6.19.1/arch/parisc/kernel/module.c
6144--- linux-2.6.19.1/arch/parisc/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
6145+++ linux-2.6.19.1/arch/parisc/kernel/module.c 2006-12-03 15:15:50.000000000 -0500
6146@@ -72,16 +72,38 @@
6147
6148 /* three functions to determine where in the module core
6149 * or init pieces the location is */
6150+static inline int in_init_rx(struct module *me, void *loc)
6151+{
6152+ return (loc >= me->module_init_rx &&
6153+ loc < (me->module_init_rx + me->init_size_rx));
6154+}
6155+
6156+static inline int in_init_rw(struct module *me, void *loc)
6157+{
6158+ return (loc >= me->module_init_rw &&
6159+ loc < (me->module_init_rw + me->init_size_rw));
6160+}
6161+
6162 static inline int in_init(struct module *me, void *loc)
6163 {
6164- return (loc >= me->module_init &&
6165- loc <= (me->module_init + me->init_size));
6166+ return in_init_rx(me, loc) || in_init_rw(me, loc);
6167+}
6168+
6169+static inline int in_core_rx(struct module *me, void *loc)
6170+{
6171+ return (loc >= me->module_core_rx &&
6172+ loc < (me->module_core_rx + me->core_size_rx));
6173+}
6174+
6175+static inline int in_core_rw(struct module *me, void *loc)
6176+{
6177+ return (loc >= me->module_core_rw &&
6178+ loc < (me->module_core_rw + me->core_size_rw));
6179 }
6180
6181 static inline int in_core(struct module *me, void *loc)
6182 {
6183- return (loc >= me->module_core &&
6184- loc <= (me->module_core + me->core_size));
6185+ return in_core_rx(me, loc) || in_core_rw(me, loc);
6186 }
6187
6188 static inline int in_local(struct module *me, void *loc)
6189@@ -295,21 +317,21 @@ int module_frob_arch_sections(CONST Elf_
6190 }
6191
6192 /* align things a bit */
6193- me->core_size = ALIGN(me->core_size, 16);
6194- me->arch.got_offset = me->core_size;
6195- me->core_size += gots * sizeof(struct got_entry);
6196-
6197- me->core_size = ALIGN(me->core_size, 16);
6198- me->arch.fdesc_offset = me->core_size;
6199- me->core_size += fdescs * sizeof(Elf_Fdesc);
6200-
6201- me->core_size = ALIGN(me->core_size, 16);
6202- me->arch.stub_offset = me->core_size;
6203- me->core_size += stubs * sizeof(struct stub_entry);
6204-
6205- me->init_size = ALIGN(me->init_size, 16);
6206- me->arch.init_stub_offset = me->init_size;
6207- me->init_size += init_stubs * sizeof(struct stub_entry);
6208+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
6209+ me->arch.got_offset = me->core_size_rw;
6210+ me->core_size_rw += gots * sizeof(struct got_entry);
6211+
6212+ me->core_size_rw = ALIGN(me->core_size_rw, 16);
6213+ me->arch.fdesc_offset = me->core_size_rw;
6214+ me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
6215+
6216+ me->core_size_rx = ALIGN(me->core_size_rx, 16);
6217+ me->arch.stub_offset = me->core_size_rx;
6218+ me->core_size_rx += stubs * sizeof(struct stub_entry);
6219+
6220+ me->init_size_rx = ALIGN(me->init_size_rx, 16);
6221+ me->arch.init_stub_offset = me->init_size_rx;
6222+ me->init_size_rx += init_stubs * sizeof(struct stub_entry);
6223
6224 me->arch.got_max = gots;
6225 me->arch.fdesc_max = fdescs;
6226@@ -329,7 +351,7 @@ static Elf64_Word get_got(struct module
6227
6228 BUG_ON(value == 0);
6229
6230- got = me->module_core + me->arch.got_offset;
6231+ got = me->module_core_rw + me->arch.got_offset;
6232 for (i = 0; got[i].addr; i++)
6233 if (got[i].addr == value)
6234 goto out;
6235@@ -347,7 +369,7 @@ static Elf64_Word get_got(struct module
6236 #ifdef __LP64__
6237 static Elf_Addr get_fdesc(struct module *me, unsigned long value)
6238 {
6239- Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
6240+ Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
6241
6242 if (!value) {
6243 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
6244@@ -365,7 +387,7 @@ static Elf_Addr get_fdesc(struct module
6245
6246 /* Create new one */
6247 fdesc->addr = value;
6248- fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6249+ fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6250 return (Elf_Addr)fdesc;
6251 }
6252 #endif /* __LP64__ */
6253@@ -385,12 +407,12 @@ static Elf_Addr get_stub(struct module *
6254 if(init_section) {
6255 i = me->arch.init_stub_count++;
6256 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
6257- stub = me->module_init + me->arch.init_stub_offset +
6258+ stub = me->module_init_rx + me->arch.init_stub_offset +
6259 i * sizeof(struct stub_entry);
6260 } else {
6261 i = me->arch.stub_count++;
6262 BUG_ON(me->arch.stub_count > me->arch.stub_max);
6263- stub = me->module_core + me->arch.stub_offset +
6264+ stub = me->module_core_rx + me->arch.stub_offset +
6265 i * sizeof(struct stub_entry);
6266 }
6267
6268@@ -758,7 +780,7 @@ register_unwind_table(struct module *me,
6269
6270 table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
6271 end = table + sechdrs[me->arch.unwind_section].sh_size;
6272- gp = (Elf_Addr)me->module_core + me->arch.got_offset;
6273+ gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
6274
6275 DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
6276 me->arch.unwind_section, table, end, gp);
6277diff -urNp linux-2.6.19.1/arch/parisc/kernel/ptrace.c linux-2.6.19.1/arch/parisc/kernel/ptrace.c
6278--- linux-2.6.19.1/arch/parisc/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
6279+++ linux-2.6.19.1/arch/parisc/kernel/ptrace.c 2006-12-03 15:15:50.000000000 -0500
6280@@ -18,6 +18,7 @@
6281 #include <linux/security.h>
6282 #include <linux/compat.h>
6283 #include <linux/signal.h>
6284+#include <linux/grsecurity.h>
6285
6286 #include <asm/uaccess.h>
6287 #include <asm/pgtable.h>
6288diff -urNp linux-2.6.19.1/arch/parisc/kernel/sys_parisc.c linux-2.6.19.1/arch/parisc/kernel/sys_parisc.c
6289--- linux-2.6.19.1/arch/parisc/kernel/sys_parisc.c 2006-11-29 16:57:37.000000000 -0500
6290+++ linux-2.6.19.1/arch/parisc/kernel/sys_parisc.c 2006-12-03 15:15:50.000000000 -0500
6291@@ -107,7 +107,7 @@ unsigned long arch_get_unmapped_area(str
6292 if (len > TASK_SIZE)
6293 return -ENOMEM;
6294 if (!addr)
6295- addr = TASK_UNMAPPED_BASE;
6296+ addr = current->mm->mmap_base;
6297
6298 if (filp) {
6299 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
6300diff -urNp linux-2.6.19.1/arch/parisc/kernel/traps.c linux-2.6.19.1/arch/parisc/kernel/traps.c
6301--- linux-2.6.19.1/arch/parisc/kernel/traps.c 2006-11-29 16:57:37.000000000 -0500
6302+++ linux-2.6.19.1/arch/parisc/kernel/traps.c 2006-12-03 15:15:50.000000000 -0500
6303@@ -716,9 +716,7 @@ void handle_interruption(int code, struc
6304
6305 down_read(&current->mm->mmap_sem);
6306 vma = find_vma(current->mm,regs->iaoq[0]);
6307- if (vma && (regs->iaoq[0] >= vma->vm_start)
6308- && (vma->vm_flags & VM_EXEC)) {
6309-
6310+ if (vma && (regs->iaoq[0] >= vma->vm_start)) {
6311 fault_address = regs->iaoq[0];
6312 fault_space = regs->iasq[0];
6313
6314diff -urNp linux-2.6.19.1/arch/parisc/mm/fault.c linux-2.6.19.1/arch/parisc/mm/fault.c
6315--- linux-2.6.19.1/arch/parisc/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
6316+++ linux-2.6.19.1/arch/parisc/mm/fault.c 2006-12-03 15:15:50.000000000 -0500
6317@@ -16,6 +16,8 @@
6318 #include <linux/sched.h>
6319 #include <linux/interrupt.h>
6320 #include <linux/module.h>
6321+#include <linux/unistd.h>
6322+#include <linux/binfmts.h>
6323
6324 #include <asm/uaccess.h>
6325 #include <asm/traps.h>
6326@@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
6327 static unsigned long
6328 parisc_acctyp(unsigned long code, unsigned int inst)
6329 {
6330- if (code == 6 || code == 16)
6331+ if (code == 6 || code == 7 || code == 16)
6332 return VM_EXEC;
6333
6334 switch (inst & 0xf0000000) {
6335@@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
6336 }
6337 #endif
6338
6339+#ifdef CONFIG_PAX_PAGEEXEC
6340+/*
6341+ * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
6342+ *
6343+ * returns 1 when task should be killed
6344+ * 2 when rt_sigreturn trampoline was detected
6345+ * 3 when unpatched PLT trampoline was detected
6346+ */
6347+static int pax_handle_fetch_fault(struct pt_regs *regs)
6348+{
6349+
6350+#ifdef CONFIG_PAX_EMUPLT
6351+ int err;
6352+
6353+ do { /* PaX: unpatched PLT emulation */
6354+ unsigned int bl, depwi;
6355+
6356+ err = get_user(bl, (unsigned int*)instruction_pointer(regs));
6357+ err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
6358+
6359+ if (err)
6360+ break;
6361+
6362+ if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
6363+ unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
6364+
6365+ err = get_user(ldw, (unsigned int*)addr);
6366+ err |= get_user(bv, (unsigned int*)(addr+4));
6367+ err |= get_user(ldw2, (unsigned int*)(addr+8));
6368+
6369+ if (err)
6370+ break;
6371+
6372+ if (ldw == 0x0E801096U &&
6373+ bv == 0xEAC0C000U &&
6374+ ldw2 == 0x0E881095U)
6375+ {
6376+ unsigned int resolver, map;
6377+
6378+ err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
6379+ err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
6380+ if (err)
6381+ break;
6382+
6383+ regs->gr[20] = instruction_pointer(regs)+8;
6384+ regs->gr[21] = map;
6385+ regs->gr[22] = resolver;
6386+ regs->iaoq[0] = resolver | 3UL;
6387+ regs->iaoq[1] = regs->iaoq[0] + 4;
6388+ return 3;
6389+ }
6390+ }
6391+ } while (0);
6392+#endif
6393+
6394+#ifdef CONFIG_PAX_EMUTRAMP
6395+
6396+#ifndef CONFIG_PAX_EMUSIGRT
6397+ if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6398+ return 1;
6399+#endif
6400+
6401+ do { /* PaX: rt_sigreturn emulation */
6402+ unsigned int ldi1, ldi2, bel, nop;
6403+
6404+ err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
6405+ err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
6406+ err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
6407+ err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
6408+
6409+ if (err)
6410+ break;
6411+
6412+ if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
6413+ ldi2 == 0x3414015AU &&
6414+ bel == 0xE4008200U &&
6415+ nop == 0x08000240U)
6416+ {
6417+ regs->gr[25] = (ldi1 & 2) >> 1;
6418+ regs->gr[20] = __NR_rt_sigreturn;
6419+ regs->gr[31] = regs->iaoq[1] + 16;
6420+ regs->sr[0] = regs->iasq[1];
6421+ regs->iaoq[0] = 0x100UL;
6422+ regs->iaoq[1] = regs->iaoq[0] + 4;
6423+ regs->iasq[0] = regs->sr[2];
6424+ regs->iasq[1] = regs->sr[2];
6425+ return 2;
6426+ }
6427+ } while (0);
6428+#endif
6429+
6430+ return 1;
6431+}
6432+
6433+void pax_report_insns(void *pc, void *sp)
6434+{
6435+ unsigned long i;
6436+
6437+ printk(KERN_ERR "PAX: bytes at PC: ");
6438+ for (i = 0; i < 5; i++) {
6439+ unsigned int c;
6440+ if (get_user(c, (unsigned int*)pc+i))
6441+ printk("???????? ");
6442+ else
6443+ printk("%08x ", c);
6444+ }
6445+ printk("\n");
6446+}
6447+#endif
6448+
6449 void do_page_fault(struct pt_regs *regs, unsigned long code,
6450 unsigned long address)
6451 {
6452@@ -168,8 +280,33 @@ good_area:
6453
6454 acc_type = parisc_acctyp(code,regs->iir);
6455
6456- if ((vma->vm_flags & acc_type) != acc_type)
6457+ if ((vma->vm_flags & acc_type) != acc_type) {
6458+
6459+#ifdef CONFIG_PAX_PAGEEXEC
6460+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
6461+ (address & ~3UL) == instruction_pointer(regs))
6462+ {
6463+ up_read(&mm->mmap_sem);
6464+ switch(pax_handle_fetch_fault(regs)) {
6465+
6466+#ifdef CONFIG_PAX_EMUPLT
6467+ case 3:
6468+ return;
6469+#endif
6470+
6471+#ifdef CONFIG_PAX_EMUTRAMP
6472+ case 2:
6473+ return;
6474+#endif
6475+
6476+ }
6477+ pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
6478+ do_exit(SIGKILL);
6479+ }
6480+#endif
6481+
6482 goto bad_area;
6483+ }
6484
6485 /*
6486 * If for any reason at all we couldn't handle the fault, make
6487diff -urNp linux-2.6.19.1/arch/powerpc/kernel/module_32.c linux-2.6.19.1/arch/powerpc/kernel/module_32.c
6488--- linux-2.6.19.1/arch/powerpc/kernel/module_32.c 2006-11-29 16:57:37.000000000 -0500
6489+++ linux-2.6.19.1/arch/powerpc/kernel/module_32.c 2006-12-03 15:15:50.000000000 -0500
6490@@ -125,7 +125,7 @@ int module_frob_arch_sections(Elf32_Ehdr
6491 me->arch.core_plt_section = i;
6492 }
6493 if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
6494- printk("Module doesn't contain .plt or .init.plt sections.\n");
6495+ printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
6496 return -ENOEXEC;
6497 }
6498
6499@@ -166,11 +166,16 @@ static uint32_t do_plt_call(void *locati
6500
6501 DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
6502 /* Init, or core PLT? */
6503- if (location >= mod->module_core
6504- && location < mod->module_core + mod->core_size)
6505+ if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
6506+ (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
6507 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
6508- else
6509+ else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
6510+ (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
6511 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
6512+ else {
6513+ printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
6514+ return ~0UL;
6515+ }
6516
6517 /* Find this entry, or if that fails, the next avail. entry */
6518 while (entry->jump[0]) {
6519diff -urNp linux-2.6.19.1/arch/powerpc/kernel/signal_32.c linux-2.6.19.1/arch/powerpc/kernel/signal_32.c
6520--- linux-2.6.19.1/arch/powerpc/kernel/signal_32.c 2006-11-29 16:57:37.000000000 -0500
6521+++ linux-2.6.19.1/arch/powerpc/kernel/signal_32.c 2006-12-03 15:15:50.000000000 -0500
6522@@ -759,7 +759,7 @@ static int handle_rt_signal(unsigned lon
6523
6524 /* Save user registers on the stack */
6525 frame = &rt_sf->uc.uc_mcontext;
6526- if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
6527+ if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
6528 if (save_user_regs(regs, frame, 0))
6529 goto badframe;
6530 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
6531diff -urNp linux-2.6.19.1/arch/powerpc/kernel/signal_64.c linux-2.6.19.1/arch/powerpc/kernel/signal_64.c
6532--- linux-2.6.19.1/arch/powerpc/kernel/signal_64.c 2006-11-29 16:57:37.000000000 -0500
6533+++ linux-2.6.19.1/arch/powerpc/kernel/signal_64.c 2006-12-03 15:15:50.000000000 -0500
6534@@ -397,7 +397,7 @@ static int setup_rt_frame(int signr, str
6535 current->thread.fpscr.val = 0;
6536
6537 /* Set up to return from userspace. */
6538- if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
6539+ if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
6540 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
6541 } else {
6542 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
6543diff -urNp linux-2.6.19.1/arch/powerpc/kernel/vdso.c linux-2.6.19.1/arch/powerpc/kernel/vdso.c
6544--- linux-2.6.19.1/arch/powerpc/kernel/vdso.c 2006-11-29 16:57:37.000000000 -0500
6545+++ linux-2.6.19.1/arch/powerpc/kernel/vdso.c 2006-12-03 15:15:50.000000000 -0500
6546@@ -239,7 +239,7 @@ int arch_setup_additional_pages(struct l
6547 vdso_base = VDSO32_MBASE;
6548 #endif
6549
6550- current->mm->context.vdso_base = 0;
6551+ current->mm->context.vdso_base = ~0UL;
6552
6553 /* vDSO has a problem and was disabled, just don't "enable" it for the
6554 * process
6555@@ -256,7 +256,7 @@ int arch_setup_additional_pages(struct l
6556 */
6557 down_write(&mm->mmap_sem);
6558 vdso_base = get_unmapped_area(NULL, vdso_base,
6559- vdso_pages << PAGE_SHIFT, 0, 0);
6560+ vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
6561 if (IS_ERR_VALUE(vdso_base)) {
6562 rc = vdso_base;
6563 goto fail_mmapsem;
6564@@ -284,8 +284,14 @@ int arch_setup_additional_pages(struct l
6565 * pages though
6566 */
6567 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC;
6568+
6569+#ifdef CONFIG_PAX_MPROTECT
6570+ if (mm->pax_flags & MF_PAX_MPROTECT)
6571+ vma->vm_flags &= ~VM_MAYWRITE;
6572+#endif
6573+
6574 vma->vm_flags |= mm->def_flags;
6575- vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
6576+ vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
6577 vma->vm_ops = &vdso_vmops;
6578
6579 /* Insert new VMA */
6580diff -urNp linux-2.6.19.1/arch/powerpc/mm/fault.c linux-2.6.19.1/arch/powerpc/mm/fault.c
6581--- linux-2.6.19.1/arch/powerpc/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
6582+++ linux-2.6.19.1/arch/powerpc/mm/fault.c 2006-12-03 15:15:50.000000000 -0500
6583@@ -28,6 +28,12 @@
6584 #include <linux/highmem.h>
6585 #include <linux/module.h>
6586 #include <linux/kprobes.h>
6587+#include <linux/binfmts.h>
6588+#include <linux/slab.h>
6589+#include <linux/pagemap.h>
6590+#include <linux/compiler.h>
6591+#include <linux/binfmts.h>
6592+#include <linux/unistd.h>
6593
6594 #include <asm/page.h>
6595 #include <asm/pgtable.h>
6596@@ -73,6 +79,364 @@ static inline int notify_page_fault(enum
6597 }
6598 #endif
6599
6600+#ifdef CONFIG_PAX_EMUSIGRT
6601+void pax_syscall_close(struct vm_area_struct * vma)
6602+{
6603+ vma->vm_mm->call_syscall = 0UL;
6604+}
6605+
6606+static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
6607+{
6608+ struct page* page;
6609+ unsigned int *kaddr;
6610+
6611+ page = alloc_page(GFP_HIGHUSER);
6612+ if (!page)
6613+ return NOPAGE_OOM;
6614+
6615+ kaddr = kmap(page);
6616+ memset(kaddr, 0, PAGE_SIZE);
6617+ kaddr[0] = 0x44000002U; /* sc */
6618+ __flush_dcache_icache(kaddr);
6619+ kunmap(page);
6620+ if (type)
6621+ *type = VM_FAULT_MAJOR;
6622+ return page;
6623+}
6624+
6625+static struct vm_operations_struct pax_vm_ops = {
6626+ .close = pax_syscall_close,
6627+ .nopage = pax_syscall_nopage,
6628+};
6629+
6630+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
6631+{
6632+ int ret;
6633+
6634+ memset(vma, 0, sizeof(*vma));
6635+ vma->vm_mm = current->mm;
6636+ vma->vm_start = addr;
6637+ vma->vm_end = addr + PAGE_SIZE;
6638+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
6639+ vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
6640+ vma->vm_ops = &pax_vm_ops;
6641+
6642+ ret = insert_vm_struct(current->mm, vma);
6643+ if (ret)
6644+ return ret;
6645+
6646+ ++current->mm->total_vm;
6647+ return 0;
6648+}
6649+#endif
6650+
6651+#ifdef CONFIG_PAX_PAGEEXEC
6652+/*
6653+ * PaX: decide what to do with offenders (regs->nip = fault address)
6654+ *
6655+ * returns 1 when task should be killed
6656+ * 2 when patched GOT trampoline was detected
6657+ * 3 when patched PLT trampoline was detected
6658+ * 4 when unpatched PLT trampoline was detected
6659+ * 5 when sigreturn trampoline was detected
6660+ * 6 when rt_sigreturn trampoline was detected
6661+ */
6662+static int pax_handle_fetch_fault(struct pt_regs *regs)
6663+{
6664+
6665+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
6666+ int err;
6667+#endif
6668+
6669+#ifdef CONFIG_PAX_EMUPLT
6670+ do { /* PaX: patched GOT emulation */
6671+ unsigned int blrl;
6672+
6673+ err = get_user(blrl, (unsigned int*)regs->nip);
6674+
6675+ if (!err && blrl == 0x4E800021U) {
6676+ unsigned long temp = regs->nip;
6677+
6678+ regs->nip = regs->link & 0xFFFFFFFCUL;
6679+ regs->link = temp + 4UL;
6680+ return 2;
6681+ }
6682+ } while (0);
6683+
6684+ do { /* PaX: patched PLT emulation #1 */
6685+ unsigned int b;
6686+
6687+ err = get_user(b, (unsigned int *)regs->nip);
6688+
6689+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
6690+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
6691+ return 3;
6692+ }
6693+ } while (0);
6694+
6695+ do { /* PaX: unpatched PLT emulation #1 */
6696+ unsigned int li, b;
6697+
6698+ err = get_user(li, (unsigned int *)regs->nip);
6699+ err |= get_user(b, (unsigned int *)(regs->nip+4));
6700+
6701+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6702+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6703+ unsigned long addr = b | 0xFC000000UL;
6704+
6705+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6706+ err = get_user(rlwinm, (unsigned int*)addr);
6707+ err |= get_user(add, (unsigned int*)(addr+4));
6708+ err |= get_user(li2, (unsigned int*)(addr+8));
6709+ err |= get_user(addis2, (unsigned int*)(addr+12));
6710+ err |= get_user(mtctr, (unsigned int*)(addr+16));
6711+ err |= get_user(li3, (unsigned int*)(addr+20));
6712+ err |= get_user(addis3, (unsigned int*)(addr+24));
6713+ err |= get_user(bctr, (unsigned int*)(addr+28));
6714+
6715+ if (err)
6716+ break;
6717+
6718+ if (rlwinm == 0x556C083CU &&
6719+ add == 0x7D6C5A14U &&
6720+ (li2 & 0xFFFF0000U) == 0x39800000U &&
6721+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6722+ mtctr == 0x7D8903A6U &&
6723+ (li3 & 0xFFFF0000U) == 0x39800000U &&
6724+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6725+ bctr == 0x4E800420U)
6726+ {
6727+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6728+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6729+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6730+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6731+ regs->ctr += (addis2 & 0xFFFFU) << 16;
6732+ regs->nip = regs->ctr;
6733+ return 4;
6734+ }
6735+ }
6736+ } while (0);
6737+
6738+#if 0
6739+ do { /* PaX: unpatched PLT emulation #2 */
6740+ unsigned int lis, lwzu, b, bctr;
6741+
6742+ err = get_user(lis, (unsigned int *)regs->nip);
6743+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
6744+ err |= get_user(b, (unsigned int *)(regs->nip+8));
6745+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
6746+
6747+ if (err)
6748+ break;
6749+
6750+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
6751+ (lwzu & 0xU) == 0xU &&
6752+ (b & 0xFC000003U) == 0x48000000U &&
6753+ bctr == 0x4E800420U)
6754+ {
6755+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
6756+ unsigned long addr = b | 0xFC000000UL;
6757+
6758+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6759+ err = get_user(addis, (unsigned int*)addr);
6760+ err |= get_user(addi, (unsigned int*)(addr+4));
6761+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
6762+ err |= get_user(add, (unsigned int*)(addr+12));
6763+ err |= get_user(li2, (unsigned int*)(addr+16));
6764+ err |= get_user(addis2, (unsigned int*)(addr+20));
6765+ err |= get_user(mtctr, (unsigned int*)(addr+24));
6766+ err |= get_user(li3, (unsigned int*)(addr+28));
6767+ err |= get_user(addis3, (unsigned int*)(addr+32));
6768+ err |= get_user(bctr, (unsigned int*)(addr+36));
6769+
6770+ if (err)
6771+ break;
6772+
6773+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6774+ (addi & 0xFFFF0000U) == 0x396B0000U &&
6775+ rlwinm == 0x556C083CU &&
6776+ add == 0x7D6C5A14U &&
6777+ (li2 & 0xFFFF0000U) == 0x39800000U &&
6778+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
6779+ mtctr == 0x7D8903A6U &&
6780+ (li3 & 0xFFFF0000U) == 0x39800000U &&
6781+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
6782+ bctr == 0x4E800420U)
6783+ {
6784+ regs->gpr[PT_R11] =
6785+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6786+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6787+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
6788+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6789+ regs->ctr += (addis2 & 0xFFFFU) << 16;
6790+ regs->nip = regs->ctr;
6791+ return 4;
6792+ }
6793+ }
6794+ } while (0);
6795+#endif
6796+
6797+ do { /* PaX: unpatched PLT emulation #3 */
6798+ unsigned int li, b;
6799+
6800+ err = get_user(li, (unsigned int *)regs->nip);
6801+ err |= get_user(b, (unsigned int *)(regs->nip+4));
6802+
6803+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
6804+ unsigned int addis, lwz, mtctr, bctr;
6805+ unsigned long addr = b | 0xFC000000UL;
6806+
6807+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
6808+ err = get_user(addis, (unsigned int*)addr);
6809+ err |= get_user(lwz, (unsigned int*)(addr+4));
6810+ err |= get_user(mtctr, (unsigned int*)(addr+8));
6811+ err |= get_user(bctr, (unsigned int*)(addr+12));
6812+
6813+ if (err)
6814+ break;
6815+
6816+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
6817+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
6818+ mtctr == 0x7D6903A6U &&
6819+ bctr == 0x4E800420U)
6820+ {
6821+ unsigned int r11;
6822+
6823+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6824+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
6825+
6826+ err = get_user(r11, (unsigned int*)addr);
6827+ if (err)
6828+ break;
6829+
6830+ regs->gpr[PT_R11] = r11;
6831+ regs->ctr = r11;
6832+ regs->nip = r11;
6833+ return 4;
6834+ }
6835+ }
6836+ } while (0);
6837+#endif
6838+
6839+#ifdef CONFIG_PAX_EMUSIGRT
6840+ do { /* PaX: sigreturn emulation */
6841+ unsigned int li, sc;
6842+
6843+ err = get_user(li, (unsigned int *)regs->nip);
6844+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
6845+
6846+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
6847+ struct vm_area_struct *vma;
6848+ unsigned long call_syscall;
6849+
6850+ down_read(&current->mm->mmap_sem);
6851+ call_syscall = current->mm->call_syscall;
6852+ up_read(&current->mm->mmap_sem);
6853+ if (likely(call_syscall))
6854+ goto emulate;
6855+
6856+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6857+
6858+ down_write(&current->mm->mmap_sem);
6859+ if (current->mm->call_syscall) {
6860+ call_syscall = current->mm->call_syscall;
6861+ up_write(&current->mm->mmap_sem);
6862+ if (vma) kmem_cache_free(vm_area_cachep, vma);
6863+ goto emulate;
6864+ }
6865+
6866+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6867+ if (!vma || (call_syscall & ~PAGE_MASK)) {
6868+ up_write(&current->mm->mmap_sem);
6869+ if (vma) kmem_cache_free(vm_area_cachep, vma);
6870+ return 1;
6871+ }
6872+
6873+ if (pax_insert_vma(vma, call_syscall)) {
6874+ up_write(&current->mm->mmap_sem);
6875+ kmem_cache_free(vm_area_cachep, vma);
6876+ return 1;
6877+ }
6878+
6879+ current->mm->call_syscall = call_syscall;
6880+ up_write(&current->mm->mmap_sem);
6881+
6882+emulate:
6883+ regs->gpr[PT_R0] = __NR_sigreturn;
6884+ regs->nip = call_syscall;
6885+ return 5;
6886+ }
6887+ } while (0);
6888+
6889+ do { /* PaX: rt_sigreturn emulation */
6890+ unsigned int li, sc;
6891+
6892+ err = get_user(li, (unsigned int *)regs->nip);
6893+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
6894+
6895+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
6896+ struct vm_area_struct *vma;
6897+ unsigned int call_syscall;
6898+
6899+ down_read(&current->mm->mmap_sem);
6900+ call_syscall = current->mm->call_syscall;
6901+ up_read(&current->mm->mmap_sem);
6902+ if (likely(call_syscall))
6903+ goto rt_emulate;
6904+
6905+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
6906+
6907+ down_write(&current->mm->mmap_sem);
6908+ if (current->mm->call_syscall) {
6909+ call_syscall = current->mm->call_syscall;
6910+ up_write(&current->mm->mmap_sem);
6911+ if (vma) kmem_cache_free(vm_area_cachep, vma);
6912+ goto rt_emulate;
6913+ }
6914+
6915+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
6916+ if (!vma || (call_syscall & ~PAGE_MASK)) {
6917+ up_write(&current->mm->mmap_sem);
6918+ if (vma) kmem_cache_free(vm_area_cachep, vma);
6919+ return 1;
6920+ }
6921+
6922+ if (pax_insert_vma(vma, call_syscall)) {
6923+ up_write(&current->mm->mmap_sem);
6924+ kmem_cache_free(vm_area_cachep, vma);
6925+ return 1;
6926+ }
6927+
6928+ current->mm->call_syscall = call_syscall;
6929+ up_write(&current->mm->mmap_sem);
6930+
6931+rt_emulate:
6932+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
6933+ regs->nip = call_syscall;
6934+ return 6;
6935+ }
6936+ } while (0);
6937+#endif
6938+
6939+ return 1;
6940+}
6941+
6942+void pax_report_insns(void *pc, void *sp)
6943+{
6944+ unsigned long i;
6945+
6946+ printk(KERN_ERR "PAX: bytes at PC: ");
6947+ for (i = 0; i < 5; i++) {
6948+ unsigned int c;
6949+ if (get_user(c, (unsigned int*)pc+i))
6950+ printk("???????? ");
6951+ else
6952+ printk("%08x ", c);
6953+ }
6954+ printk("\n");
6955+}
6956+#endif
6957+
6958 /*
6959 * Check whether the instruction at regs->nip is a store using
6960 * an update addressing form which will update r1.
6961@@ -168,7 +532,7 @@ int __kprobes do_page_fault(struct pt_re
6962 * indicate errors in DSISR but can validly be set in SRR1.
6963 */
6964 if (trap == 0x400)
6965- error_code &= 0x48200000;
6966+ error_code &= 0x58200000;
6967 else
6968 is_write = error_code & DSISR_ISSTORE;
6969 #else
6970@@ -295,9 +659,9 @@ good_area:
6971 /* protection fault */
6972 if (error_code & DSISR_PROTFAULT)
6973 goto bad_area;
6974+#endif
6975 if (!(vma->vm_flags & VM_EXEC))
6976 goto bad_area;
6977-#endif
6978 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
6979 pte_t *ptep;
6980 pmd_t *pmdp;
6981@@ -368,6 +732,37 @@ bad_area:
6982 bad_area_nosemaphore:
6983 /* User mode accesses cause a SIGSEGV */
6984 if (user_mode(regs)) {
6985+
6986+#ifdef CONFIG_PAX_PAGEEXEC
6987+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
6988+#ifdef CONFIG_PPC64
6989+ if (is_exec && (error_code & DSISR_PROTFAULT)) {
6990+#else
6991+ if (is_exec && regs->nip == address) {
6992+#endif
6993+ switch (pax_handle_fetch_fault(regs)) {
6994+
6995+#ifdef CONFIG_PAX_EMUPLT
6996+ case 2:
6997+ case 3:
6998+ case 4:
6999+ return 0;
7000+#endif
7001+
7002+#ifdef CONFIG_PAX_EMUSIGRT
7003+ case 5:
7004+ case 6:
7005+ return 0;
7006+#endif
7007+
7008+ }
7009+
7010+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
7011+ do_exit(SIGKILL);
7012+ }
7013+ }
7014+#endif
7015+
7016 _exception(SIGSEGV, regs, code, address);
7017 return 0;
7018 }
7019diff -urNp linux-2.6.19.1/arch/powerpc/mm/hugetlbpage.c linux-2.6.19.1/arch/powerpc/mm/hugetlbpage.c
7020--- linux-2.6.19.1/arch/powerpc/mm/hugetlbpage.c 2006-11-29 16:57:37.000000000 -0500
7021+++ linux-2.6.19.1/arch/powerpc/mm/hugetlbpage.c 2006-12-03 15:15:50.000000000 -0500
7022@@ -563,6 +563,10 @@ unsigned long arch_get_unmapped_area(str
7023 if (len > TASK_SIZE)
7024 return -ENOMEM;
7025
7026+#ifdef CONFIG_PAX_RANDMMAP
7027+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
7028+#endif
7029+
7030 if (addr) {
7031 addr = PAGE_ALIGN(addr);
7032 vma = find_vma(mm, addr);
7033@@ -574,7 +578,7 @@ unsigned long arch_get_unmapped_area(str
7034 if (len > mm->cached_hole_size) {
7035 start_addr = addr = mm->free_area_cache;
7036 } else {
7037- start_addr = addr = TASK_UNMAPPED_BASE;
7038+ start_addr = addr = mm->mmap_base;
7039 mm->cached_hole_size = 0;
7040 }
7041
7042@@ -607,8 +611,8 @@ full_search:
7043 }
7044
7045 /* Make sure we didn't miss any holes */
7046- if (start_addr != TASK_UNMAPPED_BASE) {
7047- start_addr = addr = TASK_UNMAPPED_BASE;
7048+ if (start_addr != mm->mmap_base) {
7049+ start_addr = addr = mm->mmap_base;
7050 mm->cached_hole_size = 0;
7051 goto full_search;
7052 }
7053@@ -643,6 +647,11 @@ arch_get_unmapped_area_topdown(struct fi
7054 mm->free_area_cache = base;
7055
7056 /* requesting a specific address */
7057+
7058+#ifdef CONFIG_PAX_RANDMMAP
7059+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
7060+#endif
7061+
7062 if (addr) {
7063 addr = PAGE_ALIGN(addr);
7064 vma = find_vma(mm, addr);
7065@@ -722,12 +731,20 @@ fail:
7066 * can happen with large stack limits and large mmap()
7067 * allocations.
7068 */
7069- mm->free_area_cache = TASK_UNMAPPED_BASE;
7070+ mm->mmap_base = TASK_UNMAPPED_BASE;
7071+
7072+#ifdef CONFIG_PAX_RANDMMAP
7073+ if (mm->pax_flags & MF_PAX_RANDMMAP)
7074+ mm->mmap_base += mm->delta_mmap;
7075+#endif
7076+
7077+ mm->free_area_cache = mm->mmap_base;
7078 mm->cached_hole_size = ~0UL;
7079 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
7080 /*
7081 * Restore the topdown base:
7082 */
7083+ mm->mmap_base = base;
7084 mm->free_area_cache = base;
7085 mm->cached_hole_size = ~0UL;
7086
7087diff -urNp linux-2.6.19.1/arch/powerpc/mm/mmap.c linux-2.6.19.1/arch/powerpc/mm/mmap.c
7088--- linux-2.6.19.1/arch/powerpc/mm/mmap.c 2006-11-29 16:57:37.000000000 -0500
7089+++ linux-2.6.19.1/arch/powerpc/mm/mmap.c 2006-12-03 15:15:50.000000000 -0500
7090@@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
7091 */
7092 if (mmap_is_legacy()) {
7093 mm->mmap_base = TASK_UNMAPPED_BASE;
7094+
7095+#ifdef CONFIG_PAX_RANDMMAP
7096+ if (mm->pax_flags & MF_PAX_RANDMMAP)
7097+ mm->mmap_base += mm->delta_mmap;
7098+#endif
7099+
7100 mm->get_unmapped_area = arch_get_unmapped_area;
7101 mm->unmap_area = arch_unmap_area;
7102 } else {
7103 mm->mmap_base = mmap_base();
7104+
7105+#ifdef CONFIG_PAX_RANDMMAP
7106+ if (mm->pax_flags & MF_PAX_RANDMMAP)
7107+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
7108+#endif
7109+
7110 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
7111 mm->unmap_area = arch_unmap_area_topdown;
7112 }
7113diff -urNp linux-2.6.19.1/arch/ppc/mm/fault.c linux-2.6.19.1/arch/ppc/mm/fault.c
7114--- linux-2.6.19.1/arch/ppc/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
7115+++ linux-2.6.19.1/arch/ppc/mm/fault.c 2006-12-03 15:15:51.000000000 -0500
7116@@ -25,6 +25,11 @@
7117 #include <linux/interrupt.h>
7118 #include <linux/highmem.h>
7119 #include <linux/module.h>
7120+#include <linux/slab.h>
7121+#include <linux/pagemap.h>
7122+#include <linux/compiler.h>
7123+#include <linux/binfmts.h>
7124+#include <linux/unistd.h>
7125
7126 #include <asm/page.h>
7127 #include <asm/pgtable.h>
7128@@ -48,6 +53,379 @@ unsigned long pte_misses; /* updated by
7129 unsigned long pte_errors; /* updated by do_page_fault() */
7130 unsigned int probingmem;
7131
7132+#ifdef CONFIG_PAX_EMUSIGRT
7133+void pax_syscall_close(struct vm_area_struct * vma)
7134+{
7135+ vma->vm_mm->call_syscall = 0UL;
7136+}
7137+
7138+static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7139+{
7140+ struct page* page;
7141+ unsigned int *kaddr;
7142+
7143+ page = alloc_page(GFP_HIGHUSER);
7144+ if (!page)
7145+ return NOPAGE_OOM;
7146+
7147+ kaddr = kmap(page);
7148+ memset(kaddr, 0, PAGE_SIZE);
7149+ kaddr[0] = 0x44000002U; /* sc */
7150+ __flush_dcache_icache(kaddr);
7151+ kunmap(page);
7152+ if (type)
7153+ *type = VM_FAULT_MAJOR;
7154+ return page;
7155+}
7156+
7157+static struct vm_operations_struct pax_vm_ops = {
7158+ .close = pax_syscall_close,
7159+ .nopage = pax_syscall_nopage,
7160+};
7161+
7162+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7163+{
7164+ int ret;
7165+
7166+ memset(vma, 0, sizeof(*vma));
7167+ vma->vm_mm = current->mm;
7168+ vma->vm_start = addr;
7169+ vma->vm_end = addr + PAGE_SIZE;
7170+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7171+ vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
7172+ vma->vm_ops = &pax_vm_ops;
7173+
7174+ ret = insert_vm_struct(current->mm, vma);
7175+ if (ret)
7176+ return ret;
7177+
7178+ ++current->mm->total_vm;
7179+ return 0;
7180+}
7181+#endif
7182+
7183+#ifdef CONFIG_PAX_PAGEEXEC
7184+/*
7185+ * PaX: decide what to do with offenders (regs->nip = fault address)
7186+ *
7187+ * returns 1 when task should be killed
7188+ * 2 when patched GOT trampoline was detected
7189+ * 3 when patched PLT trampoline was detected
7190+ * 4 when unpatched PLT trampoline was detected
7191+ * 5 when sigreturn trampoline was detected
7192+ * 6 when rt_sigreturn trampoline was detected
7193+ */
7194+static int pax_handle_fetch_fault(struct pt_regs *regs)
7195+{
7196+
7197+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7198+ int err;
7199+#endif
7200+
7201+#ifdef CONFIG_PAX_EMUPLT
7202+ do { /* PaX: patched GOT emulation */
7203+ unsigned int blrl;
7204+
7205+ err = get_user(blrl, (unsigned int*)regs->nip);
7206+
7207+ if (!err && blrl == 0x4E800021U) {
7208+ unsigned long temp = regs->nip;
7209+
7210+ regs->nip = regs->link & 0xFFFFFFFCUL;
7211+ regs->link = temp + 4UL;
7212+ return 2;
7213+ }
7214+ } while (0);
7215+
7216+ do { /* PaX: patched PLT emulation #1 */
7217+ unsigned int b;
7218+
7219+ err = get_user(b, (unsigned int *)regs->nip);
7220+
7221+ if (!err && (b & 0xFC000003U) == 0x48000000U) {
7222+ regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
7223+ return 3;
7224+ }
7225+ } while (0);
7226+
7227+ do { /* PaX: unpatched PLT emulation #1 */
7228+ unsigned int li, b;
7229+
7230+ err = get_user(li, (unsigned int *)regs->nip);
7231+ err |= get_user(b, (unsigned int *)(regs->nip+4));
7232+
7233+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7234+ unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7235+ unsigned long addr = b | 0xFC000000UL;
7236+
7237+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7238+ err = get_user(rlwinm, (unsigned int*)addr);
7239+ err |= get_user(add, (unsigned int*)(addr+4));
7240+ err |= get_user(li2, (unsigned int*)(addr+8));
7241+ err |= get_user(addis2, (unsigned int*)(addr+12));
7242+ err |= get_user(mtctr, (unsigned int*)(addr+16));
7243+ err |= get_user(li3, (unsigned int*)(addr+20));
7244+ err |= get_user(addis3, (unsigned int*)(addr+24));
7245+ err |= get_user(bctr, (unsigned int*)(addr+28));
7246+
7247+ if (err)
7248+ break;
7249+
7250+ if (rlwinm == 0x556C083CU &&
7251+ add == 0x7D6C5A14U &&
7252+ (li2 & 0xFFFF0000U) == 0x39800000U &&
7253+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7254+ mtctr == 0x7D8903A6U &&
7255+ (li3 & 0xFFFF0000U) == 0x39800000U &&
7256+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7257+ bctr == 0x4E800420U)
7258+ {
7259+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7260+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7261+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7262+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7263+ regs->ctr += (addis2 & 0xFFFFU) << 16;
7264+ regs->nip = regs->ctr;
7265+ return 4;
7266+ }
7267+ }
7268+ } while (0);
7269+
7270+#if 0
7271+ do { /* PaX: unpatched PLT emulation #2 */
7272+ unsigned int lis, lwzu, b, bctr;
7273+
7274+ err = get_user(lis, (unsigned int *)regs->nip);
7275+ err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
7276+ err |= get_user(b, (unsigned int *)(regs->nip+8));
7277+ err |= get_user(bctr, (unsigned int *)(regs->nip+12));
7278+
7279+ if (err)
7280+ break;
7281+
7282+ if ((lis & 0xFFFF0000U) == 0x39600000U &&
7283+ (lwzu & 0xU) == 0xU &&
7284+ (b & 0xFC000003U) == 0x48000000U &&
7285+ bctr == 0x4E800420U)
7286+ {
7287+ unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7288+ unsigned long addr = b | 0xFC000000UL;
7289+
7290+ addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7291+ err = get_user(addis, (unsigned int*)addr);
7292+ err |= get_user(addi, (unsigned int*)(addr+4));
7293+ err |= get_user(rlwinm, (unsigned int*)(addr+8));
7294+ err |= get_user(add, (unsigned int*)(addr+12));
7295+ err |= get_user(li2, (unsigned int*)(addr+16));
7296+ err |= get_user(addis2, (unsigned int*)(addr+20));
7297+ err |= get_user(mtctr, (unsigned int*)(addr+24));
7298+ err |= get_user(li3, (unsigned int*)(addr+28));
7299+ err |= get_user(addis3, (unsigned int*)(addr+32));
7300+ err |= get_user(bctr, (unsigned int*)(addr+36));
7301+
7302+ if (err)
7303+ break;
7304+
7305+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7306+ (addi & 0xFFFF0000U) == 0x396B0000U &&
7307+ rlwinm == 0x556C083CU &&
7308+ add == 0x7D6C5A14U &&
7309+ (li2 & 0xFFFF0000U) == 0x39800000U &&
7310+ (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7311+ mtctr == 0x7D8903A6U &&
7312+ (li3 & 0xFFFF0000U) == 0x39800000U &&
7313+ (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7314+ bctr == 0x4E800420U)
7315+ {
7316+ regs->gpr[PT_R11] =
7317+ regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7318+ regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7319+ regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7320+ regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7321+ regs->ctr += (addis2 & 0xFFFFU) << 16;
7322+ regs->nip = regs->ctr;
7323+ return 4;
7324+ }
7325+ }
7326+ } while (0);
7327+#endif
7328+
7329+ do { /* PaX: unpatched PLT emulation #3 */
7330+ unsigned int li, b;
7331+
7332+ err = get_user(li, (unsigned int *)regs->nip);
7333+ err |= get_user(b, (unsigned int *)(regs->nip+4));
7334+
7335+ if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7336+ unsigned int addis, lwz, mtctr, bctr;
7337+ unsigned long addr = b | 0xFC000000UL;
7338+
7339+ addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7340+ err = get_user(addis, (unsigned int*)addr);
7341+ err |= get_user(lwz, (unsigned int*)(addr+4));
7342+ err |= get_user(mtctr, (unsigned int*)(addr+8));
7343+ err |= get_user(bctr, (unsigned int*)(addr+12));
7344+
7345+ if (err)
7346+ break;
7347+
7348+ if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7349+ (lwz & 0xFFFF0000U) == 0x816B0000U &&
7350+ mtctr == 0x7D6903A6U &&
7351+ bctr == 0x4E800420U)
7352+ {
7353+ unsigned int r11;
7354+
7355+ addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7356+ addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7357+
7358+ err = get_user(r11, (unsigned int*)addr);
7359+ if (err)
7360+ break;
7361+
7362+ regs->gpr[PT_R11] = r11;
7363+ regs->ctr = r11;
7364+ regs->nip = r11;
7365+ return 4;
7366+ }
7367+ }
7368+ } while (0);
7369+#endif
7370+
7371+#ifdef CONFIG_PAX_EMUSIGRT
7372+ do { /* PaX: sigreturn emulation */
7373+ unsigned int li, sc;
7374+
7375+ err = get_user(li, (unsigned int *)regs->nip);
7376+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
7377+
7378+ if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
7379+ struct vm_area_struct *vma;
7380+ unsigned long call_syscall;
7381+
7382+ down_read(&current->mm->mmap_sem);
7383+ call_syscall = current->mm->call_syscall;
7384+ up_read(&current->mm->mmap_sem);
7385+ if (likely(call_syscall))
7386+ goto emulate;
7387+
7388+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7389+
7390+ down_write(&current->mm->mmap_sem);
7391+ if (current->mm->call_syscall) {
7392+ call_syscall = current->mm->call_syscall;
7393+ up_write(&current->mm->mmap_sem);
7394+ if (vma) kmem_cache_free(vm_area_cachep, vma);
7395+ goto emulate;
7396+ }
7397+
7398+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7399+ if (!vma || (call_syscall & ~PAGE_MASK)) {
7400+ up_write(&current->mm->mmap_sem);
7401+ if (vma) kmem_cache_free(vm_area_cachep, vma);
7402+ return 1;
7403+ }
7404+
7405+ if (pax_insert_vma(vma, call_syscall)) {
7406+ up_write(&current->mm->mmap_sem);
7407+ kmem_cache_free(vm_area_cachep, vma);
7408+ return 1;
7409+ }
7410+
7411+ current->mm->call_syscall = call_syscall;
7412+ up_write(&current->mm->mmap_sem);
7413+
7414+emulate:
7415+ regs->gpr[PT_R0] = __NR_sigreturn;
7416+ regs->nip = call_syscall;
7417+ return 5;
7418+ }
7419+ } while (0);
7420+
7421+ do { /* PaX: rt_sigreturn emulation */
7422+ unsigned int li, sc;
7423+
7424+ err = get_user(li, (unsigned int *)regs->nip);
7425+ err |= get_user(sc, (unsigned int *)(regs->nip+4));
7426+
7427+ if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
7428+ struct vm_area_struct *vma;
7429+ unsigned int call_syscall;
7430+
7431+ down_read(&current->mm->mmap_sem);
7432+ call_syscall = current->mm->call_syscall;
7433+ up_read(&current->mm->mmap_sem);
7434+ if (likely(call_syscall))
7435+ goto rt_emulate;
7436+
7437+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7438+
7439+ down_write(&current->mm->mmap_sem);
7440+ if (current->mm->call_syscall) {
7441+ call_syscall = current->mm->call_syscall;
7442+ up_write(&current->mm->mmap_sem);
7443+ if (vma) kmem_cache_free(vm_area_cachep, vma);
7444+ goto rt_emulate;
7445+ }
7446+
7447+ call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7448+ if (!vma || (call_syscall & ~PAGE_MASK)) {
7449+ up_write(&current->mm->mmap_sem);
7450+ if (vma) kmem_cache_free(vm_area_cachep, vma);
7451+ return 1;
7452+ }
7453+
7454+ if (pax_insert_vma(vma, call_syscall)) {
7455+ up_write(&current->mm->mmap_sem);
7456+ kmem_cache_free(vm_area_cachep, vma);
7457+ return 1;
7458+ }
7459+
7460+ current->mm->call_syscall = call_syscall;
7461+ up_write(&current->mm->mmap_sem);
7462+
7463+rt_emulate:
7464+ regs->gpr[PT_R0] = __NR_rt_sigreturn;
7465+ regs->nip = call_syscall;
7466+ return 6;
7467+ }
7468+ } while (0);
7469+#endif
7470+
7471+ return 1;
7472+}
7473+
7474+/*
7475+ * PaX: decide what to do with offenders (regs->nip = fault address)
7476+ *
7477+ * returns 1 when task should be killed
7478+ */
7479+static int pax_handle_fetch_fault(struct pt_regs *regs)
7480+{
7481+
7482+#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7483+ int err;
7484+#endif
7485+
7486+ return 1;
7487+}
7488+
7489+void pax_report_insns(void *pc, void *sp)
7490+{
7491+ unsigned long i;
7492+
7493+ printk(KERN_ERR "PAX: bytes at PC: ");
7494+ for (i = 0; i < 5; i++) {
7495+ unsigned int c;
7496+ if (get_user(c, (unsigned int*)pc+i))
7497+ printk("???????? ");
7498+ else
7499+ printk("%08x ", c);
7500+ }
7501+ printk("\n");
7502+}
7503+#endif
7504+
7505 /*
7506 * Check whether the instruction at regs->nip is a store using
7507 * an update addressing form which will update r1.
7508@@ -108,7 +486,7 @@ int do_page_fault(struct pt_regs *regs,
7509 * indicate errors in DSISR but can validly be set in SRR1.
7510 */
7511 if (TRAP(regs) == 0x400)
7512- error_code &= 0x48200000;
7513+ error_code &= 0x58200000;
7514 else
7515 is_write = error_code & 0x02000000;
7516 #endif /* CONFIG_4xx || CONFIG_BOOKE */
7517@@ -203,15 +581,14 @@ good_area:
7518 pte_t *ptep;
7519 pmd_t *pmdp;
7520
7521-#if 0
7522+#if 1
7523 /* It would be nice to actually enforce the VM execute
7524 permission on CPUs which can do so, but far too
7525 much stuff in userspace doesn't get the permissions
7526 right, so we let any page be executed for now. */
7527 if (! (vma->vm_flags & VM_EXEC))
7528 goto bad_area;
7529-#endif
7530-
7531+#else
7532 /* Since 4xx/Book-E supports per-page execute permission,
7533 * we lazily flush dcache to icache. */
7534 ptep = NULL;
7535@@ -234,6 +611,7 @@ good_area:
7536 pte_unmap_unlock(ptep, ptl);
7537 }
7538 #endif
7539+#endif
7540 /* a read */
7541 } else {
7542 /* protection fault */
7543@@ -279,6 +657,33 @@ bad_area:
7544
7545 /* User mode accesses cause a SIGSEGV */
7546 if (user_mode(regs)) {
7547+
7548+#ifdef CONFIG_PAX_PAGEEXEC
7549+ if (mm->pax_flags & MF_PAX_PAGEEXEC) {
7550+ if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
7551+ switch (pax_handle_fetch_fault(regs)) {
7552+
7553+#ifdef CONFIG_PAX_EMUPLT
7554+ case 2:
7555+ case 3:
7556+ case 4:
7557+ return 0;
7558+#endif
7559+
7560+#ifdef CONFIG_PAX_EMUSIGRT
7561+ case 5:
7562+ case 6:
7563+ return 0;
7564+#endif
7565+
7566+ }
7567+
7568+ pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
7569+ do_exit(SIGKILL);
7570+ }
7571+ }
7572+#endif
7573+
7574 _exception(SIGSEGV, regs, code, address);
7575 return 0;
7576 }
7577diff -urNp linux-2.6.19.1/arch/s390/kernel/module.c linux-2.6.19.1/arch/s390/kernel/module.c
7578--- linux-2.6.19.1/arch/s390/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
7579+++ linux-2.6.19.1/arch/s390/kernel/module.c 2006-12-03 15:15:52.000000000 -0500
7580@@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
7581
7582 /* Increase core size by size of got & plt and set start
7583 offsets for got and plt. */
7584- me->core_size = ALIGN(me->core_size, 4);
7585- me->arch.got_offset = me->core_size;
7586- me->core_size += me->arch.got_size;
7587- me->arch.plt_offset = me->core_size;
7588- me->core_size += me->arch.plt_size;
7589+ me->core_size_rw = ALIGN(me->core_size_rw, 4);
7590+ me->arch.got_offset = me->core_size_rw;
7591+ me->core_size_rw += me->arch.got_size;
7592+ me->arch.plt_offset = me->core_size_rx;
7593+ me->core_size_rx += me->arch.plt_size;
7594 return 0;
7595 }
7596
7597@@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7598 if (info->got_initialized == 0) {
7599 Elf_Addr *gotent;
7600
7601- gotent = me->module_core + me->arch.got_offset +
7602+ gotent = me->module_core_rw + me->arch.got_offset +
7603 info->got_offset;
7604 *gotent = val;
7605 info->got_initialized = 1;
7606@@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7607 else if (r_type == R_390_GOTENT ||
7608 r_type == R_390_GOTPLTENT)
7609 *(unsigned int *) loc =
7610- (val + (Elf_Addr) me->module_core - loc) >> 1;
7611+ (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
7612 else if (r_type == R_390_GOT64 ||
7613 r_type == R_390_GOTPLT64)
7614 *(unsigned long *) loc = val;
7615@@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7616 case R_390_PLTOFF64: /* 16 bit offset from GOT to PLT. */
7617 if (info->plt_initialized == 0) {
7618 unsigned int *ip;
7619- ip = me->module_core + me->arch.plt_offset +
7620+ ip = me->module_core_rx + me->arch.plt_offset +
7621 info->plt_offset;
7622 #ifndef CONFIG_64BIT
7623 ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
7624@@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7625 val = me->arch.plt_offset - me->arch.got_offset +
7626 info->plt_offset + rela->r_addend;
7627 else
7628- val = (Elf_Addr) me->module_core +
7629+ val = (Elf_Addr) me->module_core_rx +
7630 me->arch.plt_offset + info->plt_offset +
7631 rela->r_addend - loc;
7632 if (r_type == R_390_PLT16DBL)
7633@@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7634 case R_390_GOTOFF32: /* 32 bit offset to GOT. */
7635 case R_390_GOTOFF64: /* 64 bit offset to GOT. */
7636 val = val + rela->r_addend -
7637- ((Elf_Addr) me->module_core + me->arch.got_offset);
7638+ ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
7639 if (r_type == R_390_GOTOFF16)
7640 *(unsigned short *) loc = val;
7641 else if (r_type == R_390_GOTOFF32)
7642@@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
7643 break;
7644 case R_390_GOTPC: /* 32 bit PC relative offset to GOT. */
7645 case R_390_GOTPCDBL: /* 32 bit PC rel. off. to GOT shifted by 1. */
7646- val = (Elf_Addr) me->module_core + me->arch.got_offset +
7647+ val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
7648 rela->r_addend - loc;
7649 if (r_type == R_390_GOTPC)
7650 *(unsigned int *) loc = val;
7651diff -urNp linux-2.6.19.1/arch/sparc/kernel/ptrace.c linux-2.6.19.1/arch/sparc/kernel/ptrace.c
7652--- linux-2.6.19.1/arch/sparc/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
7653+++ linux-2.6.19.1/arch/sparc/kernel/ptrace.c 2006-12-03 15:15:54.000000000 -0500
7654@@ -19,6 +19,7 @@
c3e8c1b5 7655 #include <linux/security.h>
7656 #include <linux/signal.h>
b6fa5d20 7657 #include <linux/vs_base.h>
c3e8c1b5 7658+#include <linux/grsecurity.h>
7659
7660 #include <asm/pgtable.h>
7661 #include <asm/system.h>
7662@@ -300,6 +301,11 @@ asmlinkage void do_ptrace(struct pt_regs
7663 goto out;
7664 }
7665
7666+ if (gr_handle_ptrace(child, request)) {
7667+ pt_error_return(regs, EPERM);
7668+ goto out_tsk;
7669+ }
7670+
7671 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
7672 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
7673 if (ptrace_attach(child)) {
7674diff -urNp linux-2.6.19.1/arch/sparc/kernel/sys_sparc.c linux-2.6.19.1/arch/sparc/kernel/sys_sparc.c
7675--- linux-2.6.19.1/arch/sparc/kernel/sys_sparc.c 2006-11-29 16:57:37.000000000 -0500
7676+++ linux-2.6.19.1/arch/sparc/kernel/sys_sparc.c 2006-12-03 15:15:54.000000000 -0500
7677@@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
7678 if (ARCH_SUN4C_SUN4 && len > 0x20000000)
7679 return -ENOMEM;
7680 if (!addr)
7681- addr = TASK_UNMAPPED_BASE;
7682+ addr = current->mm->mmap_base;
7683
7684 if (flags & MAP_SHARED)
7685 addr = COLOUR_ALIGN(addr);
7686diff -urNp linux-2.6.19.1/arch/sparc/Makefile linux-2.6.19.1/arch/sparc/Makefile
7687--- linux-2.6.19.1/arch/sparc/Makefile 2006-11-29 16:57:37.000000000 -0500
7688+++ linux-2.6.19.1/arch/sparc/Makefile 2006-12-03 15:15:53.000000000 -0500
7689@@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE) += arch/sparc
7690 # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
7691 INIT_Y := $(patsubst %/, %/built-in.o, $(init-y))
7692 CORE_Y := $(core-y)
7693-CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
7694+CORE_Y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
7695 CORE_Y := $(patsubst %/, %/built-in.o, $(CORE_Y))
7696 DRIVERS_Y := $(patsubst %/, %/built-in.o, $(drivers-y))
7697 NET_Y := $(patsubst %/, %/built-in.o, $(net-y))
7698diff -urNp linux-2.6.19.1/arch/sparc/mm/fault.c linux-2.6.19.1/arch/sparc/mm/fault.c
7699--- linux-2.6.19.1/arch/sparc/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
7700+++ linux-2.6.19.1/arch/sparc/mm/fault.c 2006-12-03 15:15:54.000000000 -0500
7701@@ -21,6 +21,10 @@
7702 #include <linux/smp_lock.h>
7703 #include <linux/interrupt.h>
7704 #include <linux/module.h>
7705+#include <linux/slab.h>
7706+#include <linux/pagemap.h>
7707+#include <linux/compiler.h>
7708+#include <linux/binfmts.h>
7709
7710 #include <asm/system.h>
7711 #include <asm/page.h>
7712@@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
7713 return safe_compute_effective_address(regs, insn);
7714 }
7715
7716+#ifdef CONFIG_PAX_PAGEEXEC
7717+void pax_emuplt_close(struct vm_area_struct * vma)
7718+{
7719+ vma->vm_mm->call_dl_resolve = 0UL;
7720+}
7721+
7722+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7723+{
7724+ struct page* page;
7725+ unsigned int *kaddr;
7726+
7727+ page = alloc_page(GFP_HIGHUSER);
7728+ if (!page)
7729+ return NOPAGE_OOM;
7730+
7731+ kaddr = kmap(page);
7732+ memset(kaddr, 0, PAGE_SIZE);
7733+ kaddr[0] = 0x9DE3BFA8U; /* save */
7734+ flush_dcache_page(page);
7735+ kunmap(page);
7736+ if (type)
7737+ *type = VM_FAULT_MAJOR;
7738+
7739+ return page;
7740+}
7741+
7742+static struct vm_operations_struct pax_vm_ops = {
7743+ .close = pax_emuplt_close,
7744+ .nopage = pax_emuplt_nopage,
7745+};
7746+
7747+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7748+{
7749+ int ret;
7750+
7751+ memset(vma, 0, sizeof(*vma));
7752+ vma->vm_mm = current->mm;
7753+ vma->vm_start = addr;
7754+ vma->vm_end = addr + PAGE_SIZE;
7755+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7756+ vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
7757+ vma->vm_ops = &pax_vm_ops;
7758+
7759+ ret = insert_vm_struct(current->mm, vma);
7760+ if (ret)
7761+ return ret;
7762+
7763+ ++current->mm->total_vm;
7764+ return 0;
7765+}
7766+
7767+/*
7768+ * PaX: decide what to do with offenders (regs->pc = fault address)
7769+ *
7770+ * returns 1 when task should be killed
7771+ * 2 when patched PLT trampoline was detected
7772+ * 3 when unpatched PLT trampoline was detected
7773+ */
7774+static int pax_handle_fetch_fault(struct pt_regs *regs)
7775+{
7776+
7777+#ifdef CONFIG_PAX_EMUPLT
7778+ int err;
7779+
7780+ do { /* PaX: patched PLT emulation #1 */
7781+ unsigned int sethi1, sethi2, jmpl;
7782+
7783+ err = get_user(sethi1, (unsigned int*)regs->pc);
7784+ err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
7785+ err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
7786+
7787+ if (err)
7788+ break;
7789+
7790+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
7791+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
7792+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
7793+ {
7794+ unsigned int addr;
7795+
7796+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
7797+ addr = regs->u_regs[UREG_G1];
7798+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7799+ regs->pc = addr;
7800+ regs->npc = addr+4;
7801+ return 2;
7802+ }
7803+ } while (0);
7804+
7805+ { /* PaX: patched PLT emulation #2 */
7806+ unsigned int ba;
7807+
7808+ err = get_user(ba, (unsigned int*)regs->pc);
7809+
7810+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
7811+ unsigned int addr;
7812+
7813+ addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7814+ regs->pc = addr;
7815+ regs->npc = addr+4;
7816+ return 2;
7817+ }
7818+ }
7819+
7820+ do { /* PaX: patched PLT emulation #3 */
7821+ unsigned int sethi, jmpl, nop;
7822+
7823+ err = get_user(sethi, (unsigned int*)regs->pc);
7824+ err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
7825+ err |= get_user(nop, (unsigned int*)(regs->pc+8));
7826+
7827+ if (err)
7828+ break;
7829+
7830+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
7831+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
7832+ nop == 0x01000000U)
7833+ {
7834+ unsigned int addr;
7835+
7836+ addr = (sethi & 0x003FFFFFU) << 10;
7837+ regs->u_regs[UREG_G1] = addr;
7838+ addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
7839+ regs->pc = addr;
7840+ regs->npc = addr+4;
7841+ return 2;
7842+ }
7843+ } while (0);
7844+
7845+ do { /* PaX: unpatched PLT emulation step 1 */
7846+ unsigned int sethi, ba, nop;
7847+
7848+ err = get_user(sethi, (unsigned int*)regs->pc);
7849+ err |= get_user(ba, (unsigned int*)(regs->pc+4));
7850+ err |= get_user(nop, (unsigned int*)(regs->pc+8));
7851+
7852+ if (err)
7853+ break;
7854+
7855+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
7856+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
7857+ nop == 0x01000000U)
7858+ {
7859+ unsigned int addr, save, call;
7860+
7861+ if ((ba & 0xFFC00000U) == 0x30800000U)
7862+ addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
7863+ else
7864+ addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
7865+
7866+ err = get_user(save, (unsigned int*)addr);
7867+ err |= get_user(call, (unsigned int*)(addr+4));
7868+ err |= get_user(nop, (unsigned int*)(addr+8));
7869+ if (err)
7870+ break;
7871+
7872+ if (save == 0x9DE3BFA8U &&
7873+ (call & 0xC0000000U) == 0x40000000U &&
7874+ nop == 0x01000000U)
7875+ {
7876+ struct vm_area_struct *vma;
7877+ unsigned long call_dl_resolve;
7878+
7879+ down_read(&current->mm->mmap_sem);
7880+ call_dl_resolve = current->mm->call_dl_resolve;
7881+ up_read(&current->mm->mmap_sem);
7882+ if (likely(call_dl_resolve))
7883+ goto emulate;
7884+
7885+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
7886+
7887+ down_write(&current->mm->mmap_sem);
7888+ if (current->mm->call_dl_resolve) {
7889+ call_dl_resolve = current->mm->call_dl_resolve;
7890+ up_write(&current->mm->mmap_sem);
7891+ if (vma) kmem_cache_free(vm_area_cachep, vma);
7892+ goto emulate;
7893+ }
7894+
7895+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7896+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
7897+ up_write(&current->mm->mmap_sem);
7898+ if (vma) kmem_cache_free(vm_area_cachep, vma);
7899+ return 1;
7900+ }
7901+
7902+ if (pax_insert_vma(vma, call_dl_resolve)) {
7903+ up_write(&current->mm->mmap_sem);
7904+ kmem_cache_free(vm_area_cachep, vma);
7905+ return 1;
7906+ }
7907+
7908+ current->mm->call_dl_resolve = call_dl_resolve;
7909+ up_write(&current->mm->mmap_sem);
7910+
7911+emulate:
7912+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
7913+ regs->pc = call_dl_resolve;
7914+ regs->npc = addr+4;
7915+ return 3;
7916+ }
7917+ }
7918+ } while (0);
7919+
7920+ do { /* PaX: unpatched PLT emulation step 2 */
7921+ unsigned int save, call, nop;
7922+
7923+ err = get_user(save, (unsigned int*)(regs->pc-4));
7924+ err |= get_user(call, (unsigned int*)regs->pc);
7925+ err |= get_user(nop, (unsigned int*)(regs->pc+4));
7926+ if (err)
7927+ break;
7928+
7929+ if (save == 0x9DE3BFA8U &&
7930+ (call & 0xC0000000U) == 0x40000000U &&
7931+ nop == 0x01000000U)
7932+ {
7933+ unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
7934+
7935+ regs->u_regs[UREG_RETPC] = regs->pc;
7936+ regs->pc = dl_resolve;
7937+ regs->npc = dl_resolve+4;
7938+ return 3;
7939+ }
7940+ } while (0);
7941+#endif
7942+
7943+ return 1;
7944+}
7945+
7946+void pax_report_insns(void *pc, void *sp)
7947+{
7948+ unsigned long i;
7949+
7950+ printk(KERN_ERR "PAX: bytes at PC: ");
7951+ for (i = 0; i < 5; i++) {
7952+ unsigned int c;
7953+ if (get_user(c, (unsigned int*)pc+i))
7954+ printk("???????? ");
7955+ else
7956+ printk("%08x ", c);
7957+ }
7958+ printk("\n");
7959+}
7960+#endif
7961+
7962 asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
7963 unsigned long address)
7964 {
7965@@ -280,6 +530,24 @@ good_area:
7966 if(!(vma->vm_flags & VM_WRITE))
7967 goto bad_area;
7968 } else {
7969+
7970+#ifdef CONFIG_PAX_PAGEEXEC
7971+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
7972+ up_read(&mm->mmap_sem);
7973+ switch (pax_handle_fetch_fault(regs)) {
7974+
7975+#ifdef CONFIG_PAX_EMUPLT
7976+ case 2:
7977+ case 3:
7978+ return;
7979+#endif
7980+
7981+ }
7982+ pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
7983+ do_exit(SIGKILL);
7984+ }
7985+#endif
7986+
7987 /* Allow reads even for write-only mappings */
7988 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
7989 goto bad_area;
7990diff -urNp linux-2.6.19.1/arch/sparc/mm/init.c linux-2.6.19.1/arch/sparc/mm/init.c
7991--- linux-2.6.19.1/arch/sparc/mm/init.c 2006-11-29 16:57:37.000000000 -0500
7992+++ linux-2.6.19.1/arch/sparc/mm/init.c 2006-12-03 15:15:54.000000000 -0500
7993@@ -333,17 +333,17 @@ void __init paging_init(void)
7994
7995 /* Initialize the protection map with non-constant, MMU dependent values. */
7996 protection_map[0] = PAGE_NONE;
7997- protection_map[1] = PAGE_READONLY;
7998- protection_map[2] = PAGE_COPY;
7999- protection_map[3] = PAGE_COPY;
8000+ protection_map[1] = PAGE_READONLY_NOEXEC;
8001+ protection_map[2] = PAGE_COPY_NOEXEC;
8002+ protection_map[3] = PAGE_COPY_NOEXEC;
8003 protection_map[4] = PAGE_READONLY;
8004 protection_map[5] = PAGE_READONLY;
8005 protection_map[6] = PAGE_COPY;
8006 protection_map[7] = PAGE_COPY;
8007 protection_map[8] = PAGE_NONE;
8008- protection_map[9] = PAGE_READONLY;
8009- protection_map[10] = PAGE_SHARED;
8010- protection_map[11] = PAGE_SHARED;
8011+ protection_map[9] = PAGE_READONLY_NOEXEC;
8012+ protection_map[10] = PAGE_SHARED_NOEXEC;
8013+ protection_map[11] = PAGE_SHARED_NOEXEC;
8014 protection_map[12] = PAGE_READONLY;
8015 protection_map[13] = PAGE_READONLY;
8016 protection_map[14] = PAGE_SHARED;
8017diff -urNp linux-2.6.19.1/arch/sparc/mm/srmmu.c linux-2.6.19.1/arch/sparc/mm/srmmu.c
8018--- linux-2.6.19.1/arch/sparc/mm/srmmu.c 2006-11-29 16:57:37.000000000 -0500
8019+++ linux-2.6.19.1/arch/sparc/mm/srmmu.c 2006-12-03 15:15:54.000000000 -0500
8020@@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
8021 BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
8022 BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
8023 BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
8024+
8025+#ifdef CONFIG_PAX_PAGEEXEC
8026+ BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
8027+ BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
8028+ BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
8029+#endif
8030+
8031 BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
8032 page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
8033
8034diff -urNp linux-2.6.19.1/arch/sparc64/kernel/ptrace.c linux-2.6.19.1/arch/sparc64/kernel/ptrace.c
8035--- linux-2.6.19.1/arch/sparc64/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
8036+++ linux-2.6.19.1/arch/sparc64/kernel/ptrace.c 2006-12-03 15:15:54.000000000 -0500
8037@@ -22,6 +22,7 @@
c3e8c1b5 8038 #include <linux/audit.h>
8039 #include <linux/signal.h>
b6fa5d20 8040 #include <linux/vs_base.h>
c3e8c1b5 8041+#include <linux/grsecurity.h>
8042
8043 #include <asm/asi.h>
8044 #include <asm/pgtable.h>
8045@@ -213,6 +214,11 @@ asmlinkage void do_ptrace(struct pt_regs
8046 goto out;
8047 }
8048
8049+ if (gr_handle_ptrace(child, (long)request)) {
8050+ pt_error_return(regs, EPERM);
8051+ goto out_tsk;
8052+ }
8053+
8054 if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
8055 || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
8056 if (ptrace_attach(child)) {
8057diff -urNp linux-2.6.19.1/arch/sparc64/kernel/sys_sparc.c linux-2.6.19.1/arch/sparc64/kernel/sys_sparc.c
8058--- linux-2.6.19.1/arch/sparc64/kernel/sys_sparc.c 2006-11-29 16:57:37.000000000 -0500
8059+++ linux-2.6.19.1/arch/sparc64/kernel/sys_sparc.c 2006-12-03 15:15:54.000000000 -0500
8060@@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
8061 if (filp || (flags & MAP_SHARED))
8062 do_color_align = 1;
8063
8064+#ifdef CONFIG_PAX_RANDMMAP
8065+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8066+#endif
8067+
8068 if (addr) {
8069 if (do_color_align)
8070 addr = COLOUR_ALIGN(addr, pgoff);
8071@@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
8072 }
8073
8074 if (len > mm->cached_hole_size) {
8075- start_addr = addr = mm->free_area_cache;
8076+ start_addr = addr = mm->free_area_cache;
8077 } else {
8078- start_addr = addr = TASK_UNMAPPED_BASE;
8079+ start_addr = addr = mm->mmap_base;
8080 mm->cached_hole_size = 0;
8081 }
8082
8083@@ -175,8 +179,8 @@ full_search:
8084 vma = find_vma(mm, VA_EXCLUDE_END);
8085 }
8086 if (unlikely(task_size < addr)) {
8087- if (start_addr != TASK_UNMAPPED_BASE) {
8088- start_addr = addr = TASK_UNMAPPED_BASE;
8089+ if (start_addr != mm->mmap_base) {
8090+ start_addr = addr = mm->mmap_base;
8091 mm->cached_hole_size = 0;
8092 goto full_search;
8093 }
8094@@ -379,6 +383,12 @@ void arch_pick_mmap_layout(struct mm_str
8095 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
8096 sysctl_legacy_va_layout) {
8097 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
8098+
8099+#ifdef CONFIG_PAX_RANDMMAP
8100+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8101+ mm->mmap_base += mm->delta_mmap;
8102+#endif
8103+
8104 mm->get_unmapped_area = arch_get_unmapped_area;
8105 mm->unmap_area = arch_unmap_area;
8106 } else {
8107@@ -393,6 +403,12 @@ void arch_pick_mmap_layout(struct mm_str
8108 gap = (task_size / 6 * 5);
8109
8110 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
8111+
8112+#ifdef CONFIG_PAX_RANDMMAP
8113+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8114+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8115+#endif
8116+
8117 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8118 mm->unmap_area = arch_unmap_area_topdown;
8119 }
8120diff -urNp linux-2.6.19.1/arch/sparc64/mm/fault.c linux-2.6.19.1/arch/sparc64/mm/fault.c
8121--- linux-2.6.19.1/arch/sparc64/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
8122+++ linux-2.6.19.1/arch/sparc64/mm/fault.c 2006-12-03 15:15:54.000000000 -0500
8123@@ -20,6 +20,10 @@
8124 #include <linux/interrupt.h>
8125 #include <linux/kprobes.h>
8126 #include <linux/kallsyms.h>
8127+#include <linux/slab.h>
8128+#include <linux/pagemap.h>
8129+#include <linux/compiler.h>
8130+#include <linux/binfmts.h>
8131
8132 #include <asm/page.h>
8133 #include <asm/pgtable.h>
8134@@ -290,6 +294,369 @@ cannot_handle:
8135 unhandled_fault (address, current, regs);
8136 }
8137
8138+#ifdef CONFIG_PAX_PAGEEXEC
8139+#ifdef CONFIG_PAX_EMUPLT
8140+static void pax_emuplt_close(struct vm_area_struct * vma)
8141+{
8142+ vma->vm_mm->call_dl_resolve = 0UL;
8143+}
8144+
8145+static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8146+{
8147+ struct page* page;
8148+ unsigned int *kaddr;
8149+
8150+ page = alloc_page(GFP_HIGHUSER);
8151+ if (!page)
8152+ return NOPAGE_OOM;
8153+
8154+ kaddr = kmap(page);
8155+ memset(kaddr, 0, PAGE_SIZE);
8156+ kaddr[0] = 0x9DE3BFA8U; /* save */
8157+ flush_dcache_page(page);
8158+ kunmap(page);
8159+ if (type)
8160+ *type = VM_FAULT_MAJOR;
8161+ return page;
8162+}
8163+
8164+static struct vm_operations_struct pax_vm_ops = {
8165+ .close = pax_emuplt_close,
8166+ .nopage = pax_emuplt_nopage,
8167+};
8168+
8169+static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8170+{
8171+ int ret;
8172+
8173+ memset(vma, 0, sizeof(*vma));
8174+ vma->vm_mm = current->mm;
8175+ vma->vm_start = addr;
8176+ vma->vm_end = addr + PAGE_SIZE;
8177+ vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8178+ vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
8179+ vma->vm_ops = &pax_vm_ops;
8180+
8181+ ret = insert_vm_struct(current->mm, vma);
8182+ if (ret)
8183+ return ret;
8184+
8185+ ++current->mm->total_vm;
8186+ return 0;
8187+}
8188+#endif
8189+
8190+/*
8191+ * PaX: decide what to do with offenders (regs->tpc = fault address)
8192+ *
8193+ * returns 1 when task should be killed
8194+ * 2 when patched PLT trampoline was detected
8195+ * 3 when unpatched PLT trampoline was detected
8196+ */
8197+static int pax_handle_fetch_fault(struct pt_regs *regs)
8198+{
8199+
8200+#ifdef CONFIG_PAX_EMUPLT
8201+ int err;
8202+
8203+ do { /* PaX: patched PLT emulation #1 */
8204+ unsigned int sethi1, sethi2, jmpl;
8205+
8206+ err = get_user(sethi1, (unsigned int*)regs->tpc);
8207+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
8208+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
8209+
8210+ if (err)
8211+ break;
8212+
8213+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8214+ (sethi2 & 0xFFC00000U) == 0x03000000U &&
8215+ (jmpl & 0xFFFFE000U) == 0x81C06000U)
8216+ {
8217+ unsigned long addr;
8218+
8219+ regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
8220+ addr = regs->u_regs[UREG_G1];
8221+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8222+ regs->tpc = addr;
8223+ regs->tnpc = addr+4;
8224+ return 2;
8225+ }
8226+ } while (0);
8227+
8228+ { /* PaX: patched PLT emulation #2 */
8229+ unsigned int ba;
8230+
8231+ err = get_user(ba, (unsigned int*)regs->tpc);
8232+
8233+ if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
8234+ unsigned long addr;
8235+
8236+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8237+ regs->tpc = addr;
8238+ regs->tnpc = addr+4;
8239+ return 2;
8240+ }
8241+ }
8242+
8243+ do { /* PaX: patched PLT emulation #3 */
8244+ unsigned int sethi, jmpl, nop;
8245+
8246+ err = get_user(sethi, (unsigned int*)regs->tpc);
8247+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
8248+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8249+
8250+ if (err)
8251+ break;
8252+
8253+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8254+ (jmpl & 0xFFFFE000U) == 0x81C06000U &&
8255+ nop == 0x01000000U)
8256+ {
8257+ unsigned long addr;
8258+
8259+ addr = (sethi & 0x003FFFFFU) << 10;
8260+ regs->u_regs[UREG_G1] = addr;
8261+ addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
8262+ regs->tpc = addr;
8263+ regs->tnpc = addr+4;
8264+ return 2;
8265+ }
8266+ } while (0);
8267+
8268+ do { /* PaX: patched PLT emulation #4 */
8269+ unsigned int mov1, call, mov2;
8270+
8271+ err = get_user(mov1, (unsigned int*)regs->tpc);
8272+ err |= get_user(call, (unsigned int*)(regs->tpc+4));
8273+ err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
8274+
8275+ if (err)
8276+ break;
8277+
8278+ if (mov1 == 0x8210000FU &&
8279+ (call & 0xC0000000U) == 0x40000000U &&
8280+ mov2 == 0x9E100001U)
8281+ {
8282+ unsigned long addr;
8283+
8284+ regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
8285+ addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8286+ regs->tpc = addr;
8287+ regs->tnpc = addr+4;
8288+ return 2;
8289+ }
8290+ } while (0);
8291+
8292+ do { /* PaX: patched PLT emulation #5 */
8293+ unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
8294+
8295+ err = get_user(sethi1, (unsigned int*)regs->tpc);
8296+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
8297+ err |= get_user(or1, (unsigned int*)(regs->tpc+8));
8298+ err |= get_user(or2, (unsigned int*)(regs->tpc+12));
8299+ err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
8300+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
8301+ err |= get_user(nop, (unsigned int*)(regs->tpc+24));
8302+
8303+ if (err)
8304+ break;
8305+
8306+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8307+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8308+ (or1 & 0xFFFFE000U) == 0x82106000U &&
8309+ (or2 & 0xFFFFE000U) == 0x8A116000U &&
8310+ sllx == 0x83287020 &&
8311+ jmpl == 0x81C04005U &&
8312+ nop == 0x01000000U)
8313+ {
8314+ unsigned long addr;
8315+
8316+ regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
8317+ regs->u_regs[UREG_G1] <<= 32;
8318+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
8319+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8320+ regs->tpc = addr;
8321+ regs->tnpc = addr+4;
8322+ return 2;
8323+ }
8324+ } while (0);
8325+
8326+ do { /* PaX: patched PLT emulation #6 */
8327+ unsigned int sethi1, sethi2, sllx, or, jmpl, nop;
8328+
8329+ err = get_user(sethi1, (unsigned int*)regs->tpc);
8330+ err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
8331+ err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
8332+ err |= get_user(or, (unsigned int*)(regs->tpc+12));
8333+ err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
8334+ err |= get_user(nop, (unsigned int*)(regs->tpc+20));
8335+
8336+ if (err)
8337+ break;
8338+
8339+ if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8340+ (sethi2 & 0xFFC00000U) == 0x0B000000U &&
8341+ sllx == 0x83287020 &&
8342+ (or & 0xFFFFE000U) == 0x8A116000U &&
8343+ jmpl == 0x81C04005U &&
8344+ nop == 0x01000000U)
8345+ {
8346+ unsigned long addr;
8347+
8348+ regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
8349+ regs->u_regs[UREG_G1] <<= 32;
8350+ regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
8351+ addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
8352+ regs->tpc = addr;
8353+ regs->tnpc = addr+4;
8354+ return 2;
8355+ }
8356+ } while (0);
8357+
8358+ do { /* PaX: patched PLT emulation #7 */
8359+ unsigned int sethi, ba, nop;
8360+
8361+ err = get_user(sethi, (unsigned int*)regs->tpc);
8362+ err |= get_user(ba, (unsigned int*)(regs->tpc+4));
8363+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8364+
8365+ if (err)
8366+ break;
8367+
8368+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8369+ (ba & 0xFFF00000U) == 0x30600000U &&
8370+ nop == 0x01000000U)
8371+ {
8372+ unsigned long addr;
8373+
8374+ addr = (sethi & 0x003FFFFFU) << 10;
8375+ regs->u_regs[UREG_G1] = addr;
8376+ addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8377+ regs->tpc = addr;
8378+ regs->tnpc = addr+4;
8379+ return 2;
8380+ }
8381+ } while (0);
8382+
8383+ do { /* PaX: unpatched PLT emulation step 1 */
8384+ unsigned int sethi, ba, nop;
8385+
8386+ err = get_user(sethi, (unsigned int*)regs->tpc);
8387+ err |= get_user(ba, (unsigned int*)(regs->tpc+4));
8388+ err |= get_user(nop, (unsigned int*)(regs->tpc+8));
8389+
8390+ if (err)
8391+ break;
8392+
8393+ if ((sethi & 0xFFC00000U) == 0x03000000U &&
8394+ ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
8395+ nop == 0x01000000U)
8396+ {
8397+ unsigned long addr;
8398+ unsigned int save, call;
8399+
8400+ if ((ba & 0xFFC00000U) == 0x30800000U)
8401+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
8402+ else
8403+ addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
8404+
8405+ err = get_user(save, (unsigned int*)addr);
8406+ err |= get_user(call, (unsigned int*)(addr+4));
8407+ err |= get_user(nop, (unsigned int*)(addr+8));
8408+ if (err)
8409+ break;
8410+
8411+ if (save == 0x9DE3BFA8U &&
8412+ (call & 0xC0000000U) == 0x40000000U &&
8413+ nop == 0x01000000U)
8414+ {
8415+ struct vm_area_struct *vma;
8416+ unsigned long call_dl_resolve;
8417+
8418+ down_read(&current->mm->mmap_sem);
8419+ call_dl_resolve = current->mm->call_dl_resolve;
8420+ up_read(&current->mm->mmap_sem);
8421+ if (likely(call_dl_resolve))
8422+ goto emulate;
8423+
8424+ vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8425+
8426+ down_write(&current->mm->mmap_sem);
8427+ if (current->mm->call_dl_resolve) {
8428+ call_dl_resolve = current->mm->call_dl_resolve;
8429+ up_write(&current->mm->mmap_sem);
8430+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8431+ goto emulate;
8432+ }
8433+
8434+ call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8435+ if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
8436+ up_write(&current->mm->mmap_sem);
8437+ if (vma) kmem_cache_free(vm_area_cachep, vma);
8438+ return 1;
8439+ }
8440+
8441+ if (pax_insert_vma(vma, call_dl_resolve)) {
8442+ up_write(&current->mm->mmap_sem);
8443+ kmem_cache_free(vm_area_cachep, vma);
8444+ return 1;
8445+ }
8446+
8447+ current->mm->call_dl_resolve = call_dl_resolve;
8448+ up_write(&current->mm->mmap_sem);
8449+
8450+emulate:
8451+ regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
8452+ regs->tpc = call_dl_resolve;
8453+ regs->tnpc = addr+4;
8454+ return 3;
8455+ }
8456+ }
8457+ } while (0);
8458+
8459+ do { /* PaX: unpatched PLT emulation step 2 */
8460+ unsigned int save, call, nop;
8461+
8462+ err = get_user(save, (unsigned int*)(regs->tpc-4));
8463+ err |= get_user(call, (unsigned int*)regs->tpc);
8464+ err |= get_user(nop, (unsigned int*)(regs->tpc+4));
8465+ if (err)
8466+ break;
8467+
8468+ if (save == 0x9DE3BFA8U &&
8469+ (call & 0xC0000000U) == 0x40000000U &&
8470+ nop == 0x01000000U)
8471+ {
8472+ unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
8473+
8474+ regs->u_regs[UREG_RETPC] = regs->tpc;
8475+ regs->tpc = dl_resolve;
8476+ regs->tnpc = dl_resolve+4;
8477+ return 3;
8478+ }
8479+ } while (0);
8480+#endif
8481+
8482+ return 1;
8483+}
8484+
8485+void pax_report_insns(void *pc, void *sp)
8486+{
8487+ unsigned long i;
8488+
8489+ printk(KERN_ERR "PAX: bytes at PC: ");
8490+ for (i = 0; i < 5; i++) {
8491+ unsigned int c;
8492+ if (get_user(c, (unsigned int*)pc+i))
8493+ printk("???????? ");
8494+ else
8495+ printk("%08x ", c);
8496+ }
8497+ printk("\n");
8498+}
8499+#endif
8500+
8501 asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
8502 {
8503 struct mm_struct *mm = current->mm;
8504@@ -332,8 +699,10 @@ asmlinkage void __kprobes do_sparc64_fau
8505 goto intr_or_no_mm;
8506
8507 if (test_thread_flag(TIF_32BIT)) {
8508- if (!(regs->tstate & TSTATE_PRIV))
8509+ if (!(regs->tstate & TSTATE_PRIV)) {
8510 regs->tpc &= 0xffffffff;
8511+ regs->tnpc &= 0xffffffff;
8512+ }
8513 address &= 0xffffffff;
8514 }
8515
8516@@ -350,6 +719,29 @@ asmlinkage void __kprobes do_sparc64_fau
8517 if (!vma)
8518 goto bad_area;
8519
8520+#ifdef CONFIG_PAX_PAGEEXEC
8521+ /* PaX: detect ITLB misses on non-exec pages */
8522+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
8523+ !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
8524+ {
8525+ if (address != regs->tpc)
8526+ goto good_area;
8527+
8528+ up_read(&mm->mmap_sem);
8529+ switch (pax_handle_fetch_fault(regs)) {
8530+
8531+#ifdef CONFIG_PAX_EMUPLT
8532+ case 2:
8533+ case 3:
8534+ return;
8535+#endif
8536+
8537+ }
8538+ pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
8539+ do_exit(SIGKILL);
8540+ }
8541+#endif
8542+
8543 /* Pure DTLB misses do not tell us whether the fault causing
8544 * load/store/atomic was a write or not, it only says that there
8545 * was no match. So in such a case we (carefully) read the
8546diff -urNp linux-2.6.19.1/arch/v850/kernel/module.c linux-2.6.19.1/arch/v850/kernel/module.c
8547--- linux-2.6.19.1/arch/v850/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
8548+++ linux-2.6.19.1/arch/v850/kernel/module.c 2006-12-03 15:15:54.000000000 -0500
8549@@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
8550 tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
8551
8552 /* Init, or core PLT? */
8553- if (location >= mod->module_core
8554- && location < mod->module_core + mod->core_size)
8555+ if (location >= mod->module_core_rx
8556+ && location < mod->module_core_rx + mod->core_size_rx)
8557 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
8558 else
8559 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
8560diff -urNp linux-2.6.19.1/arch/x86_64/boot/compressed/head.S linux-2.6.19.1/arch/x86_64/boot/compressed/head.S
8561--- linux-2.6.19.1/arch/x86_64/boot/compressed/head.S 2006-11-29 16:57:37.000000000 -0500
8562+++ linux-2.6.19.1/arch/x86_64/boot/compressed/head.S 2006-12-03 15:15:55.000000000 -0500
8563@@ -41,11 +41,13 @@ startup_32:
8564 movl %eax,%gs
8565
8566 lss stack_start,%esp
8567+ movl 0x000000,%ecx
8568 xorl %eax,%eax
8569 1: incl %eax # check that A20 really IS enabled
8570 movl %eax,0x000000 # loop forever if it isn't
8571 cmpl %eax,0x100000
8572 je 1b
8573+ movl %ecx,0x000000
8574
8575 /*
8576 * Initialize eflags. Some BIOS's leave bits like NT set. This would
8577diff -urNp linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c
8578--- linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c 2006-11-29 16:57:37.000000000 -0500
8579+++ linux-2.6.19.1/arch/x86_64/ia32/ia32_binfmt.c 2006-12-03 15:15:55.000000000 -0500
8580@@ -190,6 +190,17 @@ struct elf_prpsinfo
8581 //#include <asm/ia32.h>
8582 #include <linux/elf.h>
8583
8584+#ifdef CONFIG_PAX_ASLR
8585+#define PAX_ELF_ET_DYN_BASE(tsk) 0x08048000UL
8586+
8587+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
8588+#define PAX_DELTA_MMAP_LEN(tsk) 16
8589+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
8590+#define PAX_DELTA_EXEC_LEN(tsk) 16
8591+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
8592+#define PAX_DELTA_STACK_LEN(tsk) 16
8593+#endif
8594+
8595 typedef struct user_i387_ia32_struct elf_fpregset_t;
8596 typedef struct user32_fxsr_struct elf_fpxregset_t;
8597
8598diff -urNp linux-2.6.19.1/arch/x86_64/ia32/mmap32.c linux-2.6.19.1/arch/x86_64/ia32/mmap32.c
8599--- linux-2.6.19.1/arch/x86_64/ia32/mmap32.c 2006-11-29 16:57:37.000000000 -0500
8600+++ linux-2.6.19.1/arch/x86_64/ia32/mmap32.c 2006-12-03 15:15:55.000000000 -0500
8601@@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
8602 (current->personality & ADDR_COMPAT_LAYOUT) ||
8603 current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
8604 mm->mmap_base = TASK_UNMAPPED_BASE;
8605+
8606+#ifdef CONFIG_PAX_RANDMMAP
8607+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8608+ mm->mmap_base += mm->delta_mmap;
8609+#endif
8610+
8611 mm->get_unmapped_area = arch_get_unmapped_area;
8612 mm->unmap_area = arch_unmap_area;
8613 } else {
8614 mm->mmap_base = mmap_base(mm);
8615+
8616+#ifdef CONFIG_PAX_RANDMMAP
8617+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8618+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8619+#endif
8620+
8621 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8622 mm->unmap_area = arch_unmap_area_topdown;
8623 }
8624diff -urNp linux-2.6.19.1/arch/x86_64/ia32/syscall32.c linux-2.6.19.1/arch/x86_64/ia32/syscall32.c
8625--- linux-2.6.19.1/arch/x86_64/ia32/syscall32.c 2006-11-29 16:57:37.000000000 -0500
8626+++ linux-2.6.19.1/arch/x86_64/ia32/syscall32.c 2006-12-03 15:15:55.000000000 -0500
8627@@ -49,16 +49,21 @@ int syscall32_setup_pages(struct linux_b
8628 struct mm_struct *mm = current->mm;
8629 int ret;
8630
8631- vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
8632+ vma = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
8633 if (!vma)
8634 return -ENOMEM;
8635
8636- memset(vma, 0, sizeof(struct vm_area_struct));
8637 /* Could randomize here */
8638 vma->vm_start = VSYSCALL32_BASE;
8639 vma->vm_end = VSYSCALL32_END;
8640 /* MAYWRITE to allow gdb to COW and set breakpoints */
8641 vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
8642+
8643+#ifdef CONFIG_PAX_MPROTECT
8644+ if (mm->pax_flags & MF_PAX_MPROTECT)
8645+ vma->vm_flags &= ~VM_MAYWRITE;
8646+#endif
8647+
8648 vma->vm_flags |= mm->def_flags;
8649 vma->vm_page_prot = protection_map[vma->vm_flags & 7];
8650 vma->vm_ops = &syscall32_vm_ops;
8651diff -urNp linux-2.6.19.1/arch/x86_64/kernel/ioport.c linux-2.6.19.1/arch/x86_64/kernel/ioport.c
8652--- linux-2.6.19.1/arch/x86_64/kernel/ioport.c 2006-11-29 16:57:37.000000000 -0500
8653+++ linux-2.6.19.1/arch/x86_64/kernel/ioport.c 2006-12-10 22:09:57.000000000 -0500
8654@@ -41,8 +41,16 @@ asmlinkage long sys_ioperm(unsigned long
8655
8656 if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
8657 return -EINVAL;
8658+
8659+#ifdef CONFIG_GRKERNSEC_IO
8660+ if (turn_on) {
8661+ gr_handle_ioperm();
8662+ return -EPERM;
8663+ }
8664+#else
8665 if (turn_on && !capable(CAP_SYS_RAWIO))
8666 return -EPERM;
8667+#endif
8668
8669 /*
8670 * If it's the first ioperm() call in this thread's lifetime, set the
8671@@ -111,8 +119,13 @@ asmlinkage long sys_iopl(unsigned int le
8672 return -EINVAL;
8673 /* Trying to gain more privileges? */
8674 if (level > old) {
8675+#ifdef CONFIG_GRKERNSEC_IO
8676+ gr_handle_iopl();
8677+ return -EPERM;
8678+#else
8679 if (!capable(CAP_SYS_RAWIO))
8680 return -EPERM;
8681+#endif
8682 }
8683 regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
8684 return 0;
8685diff -urNp linux-2.6.19.1/arch/x86_64/kernel/process.c linux-2.6.19.1/arch/x86_64/kernel/process.c
8686--- linux-2.6.19.1/arch/x86_64/kernel/process.c 2006-11-29 16:57:37.000000000 -0500
8687+++ linux-2.6.19.1/arch/x86_64/kernel/process.c 2006-12-03 15:15:55.000000000 -0500
8688@@ -871,10 +871,3 @@ int dump_task_regs(struct task_struct *t
8689
8690 return 1;
8691 }
8692-
8693-unsigned long arch_align_stack(unsigned long sp)
8694-{
8695- if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
8696- sp -= get_random_int() % 8192;
8697- return sp & ~0xf;
8698-}
8699diff -urNp linux-2.6.19.1/arch/x86_64/kernel/ptrace.c linux-2.6.19.1/arch/x86_64/kernel/ptrace.c
8700--- linux-2.6.19.1/arch/x86_64/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
8701+++ linux-2.6.19.1/arch/x86_64/kernel/ptrace.c 2006-12-03 15:15:55.000000000 -0500
8702@@ -19,6 +19,7 @@
8703 #include <linux/audit.h>
8704 #include <linux/seccomp.h>
8705 #include <linux/signal.h>
8706+#include <linux/grsecurity.h>
8707
8708 #include <asm/uaccess.h>
8709 #include <asm/pgtable.h>
8710diff -urNp linux-2.6.19.1/arch/x86_64/kernel/setup64.c linux-2.6.19.1/arch/x86_64/kernel/setup64.c
8711--- linux-2.6.19.1/arch/x86_64/kernel/setup64.c 2006-11-29 16:57:37.000000000 -0500
8712+++ linux-2.6.19.1/arch/x86_64/kernel/setup64.c 2006-12-03 15:15:55.000000000 -0500
8713@@ -38,7 +38,6 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
8714
8715 unsigned long __supported_pte_mask __read_mostly = ~0UL;
8716 EXPORT_SYMBOL(__supported_pte_mask);
8717-static int do_not_nx __cpuinitdata = 0;
8718
8719 /* noexec=on|off
8720 Control non executable mappings for 64bit processes.
8721@@ -52,16 +51,14 @@ static int __init nonx_setup(char *str)
8722 return -EINVAL;
8723 if (!strncmp(str, "on", 2)) {
8724 __supported_pte_mask |= _PAGE_NX;
8725- do_not_nx = 0;
8726 } else if (!strncmp(str, "off", 3)) {
8727- do_not_nx = 1;
8728 __supported_pte_mask &= ~_PAGE_NX;
8729 }
8730 return 0;
8731 }
8732 early_param("noexec", nonx_setup);
8733
8734-int force_personality32 = 0;
8735+int force_personality32;
8736
8737 /* noexec32=on|off
8738 Control non executable heap for 32bit processes.
8739@@ -175,7 +172,7 @@ void __cpuinit check_efer(void)
8740 unsigned long efer;
8741
8742 rdmsrl(MSR_EFER, efer);
8743- if (!(efer & EFER_NX) || do_not_nx) {
8744+ if (!(efer & EFER_NX)) {
8745 __supported_pte_mask &= ~_PAGE_NX;
8746 }
8747 }
8748diff -urNp linux-2.6.19.1/arch/x86_64/kernel/signal.c linux-2.6.19.1/arch/x86_64/kernel/signal.c
8749--- linux-2.6.19.1/arch/x86_64/kernel/signal.c 2006-11-29 16:57:37.000000000 -0500
8750+++ linux-2.6.19.1/arch/x86_64/kernel/signal.c 2006-12-03 15:15:55.000000000 -0500
8751@@ -254,8 +254,8 @@ static int setup_rt_frame(int sig, struc
8752 err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
8753 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
8754 if (sizeof(*set) == 16) {
8755- __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
8756- __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
8757+ err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
8758+ err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
8759 } else
8760 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
8761
8762diff -urNp linux-2.6.19.1/arch/x86_64/kernel/sys_x86_64.c linux-2.6.19.1/arch/x86_64/kernel/sys_x86_64.c
8763--- linux-2.6.19.1/arch/x86_64/kernel/sys_x86_64.c 2006-11-29 16:57:37.000000000 -0500
8764+++ linux-2.6.19.1/arch/x86_64/kernel/sys_x86_64.c 2006-12-03 15:15:55.000000000 -0500
8765@@ -65,8 +65,8 @@ out:
8766 return error;
8767 }
8768
8769-static void find_start_end(unsigned long flags, unsigned long *begin,
8770- unsigned long *end)
8771+static void find_start_end(struct mm_struct *mm, unsigned long flags,
8772+ unsigned long *begin, unsigned long *end)
8773 {
8774 if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
8775 /* This is usually used needed to map code in small
8776@@ -79,7 +79,7 @@ static void find_start_end(unsigned long
8777 *begin = 0x40000000;
8778 *end = 0x80000000;
8779 } else {
8780- *begin = TASK_UNMAPPED_BASE;
8781+ *begin = mm->mmap_base;
8782 *end = TASK_SIZE;
8783 }
8784 }
8785@@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
8786 unsigned long start_addr;
8787 unsigned long begin, end;
8788
8789- find_start_end(flags, &begin, &end);
8790+ find_start_end(mm, flags, &begin, &end);
8791
8792 if (len > end)
8793 return -ENOMEM;
8794
8795+#ifdef CONFIG_PAX_RANDMMAP
8796+ if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8797+#endif
8798+
8799 if (addr) {
8800 addr = PAGE_ALIGN(addr);
8801 vma = find_vma(mm, addr);
8802diff -urNp linux-2.6.19.1/arch/x86_64/mm/fault.c linux-2.6.19.1/arch/x86_64/mm/fault.c
8803--- linux-2.6.19.1/arch/x86_64/mm/fault.c 2006-11-29 16:57:37.000000000 -0500
8804+++ linux-2.6.19.1/arch/x86_64/mm/fault.c 2006-12-03 15:15:55.000000000 -0500
8805@@ -23,6 +23,7 @@
8806 #include <linux/compiler.h>
8807 #include <linux/module.h>
8808 #include <linux/kprobes.h>
8809+#include <linux/binfmts.h>
8810
8811 #include <asm/system.h>
8812 #include <asm/uaccess.h>
8813@@ -322,6 +323,33 @@ static int vmalloc_fault(unsigned long a
8814 return 0;
8815 }
8816
8817+#ifdef CONFIG_PAX_PAGEEXEC
8818+void pax_report_insns(void *pc, void *sp)
8819+{
8820+ long i;
8821+
8822+ printk(KERN_ERR "PAX: bytes at PC: ");
8823+ for (i = 0; i < 20; i++) {
8824+ unsigned char c;
8825+ if (get_user(c, (unsigned char __user *)pc+i))
8826+ printk("?? ");
8827+ else
8828+ printk("%02x ", c);
8829+ }
8830+ printk("\n");
8831+
8832+ printk(KERN_ERR "PAX: bytes at SP-8: ");
8833+ for (i = -1; i < 10; i++) {
8834+ unsigned long c;
8835+ if (get_user(c, (unsigned long __user *)sp+i))
8836+ printk("???????????????? ");
8837+ else
8838+ printk("%016lx ", c);
8839+ }
8840+ printk("\n");
8841+}
8842+#endif
8843+
8844 int page_fault_trace = 0;
8845 int exception_trace = 1;
8846
8847@@ -453,6 +481,8 @@ asmlinkage void __kprobes do_page_fault(
8848 good_area:
8849 info.si_code = SEGV_ACCERR;
8850 write = 0;
8851+ if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
8852+ goto bad_area;
8853 switch (error_code & (PF_PROT|PF_WRITE)) {
8854 default: /* 3: write, present */
8855 /* fall through */
8856@@ -519,7 +549,14 @@ bad_area_nosemaphore:
8857 tsk->comm, tsk->pid, address, regs->rip,
8858 regs->rsp, error_code);
8859 }
8860-
8861+
8862+#ifdef CONFIG_PAX_PAGEEXEC
8863+ if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
8864+ pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
8865+ do_exit(SIGKILL);
8866+ }
8867+#endif
8868+
8869 tsk->thread.cr2 = address;
8870 /* Kernel addresses are always protection faults */
8871 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
8872diff -urNp linux-2.6.19.1/arch/x86_64/mm/mmap.c linux-2.6.19.1/arch/x86_64/mm/mmap.c
8873--- linux-2.6.19.1/arch/x86_64/mm/mmap.c 2006-11-29 16:57:37.000000000 -0500
8874+++ linux-2.6.19.1/arch/x86_64/mm/mmap.c 2006-12-03 15:15:55.000000000 -0500
8875@@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
8876 unsigned rnd = get_random_int() & 0xfffffff;
8877 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
8878 }
8879+
8880+#ifdef CONFIG_PAX_RANDMMAP
8881+ if (mm->pax_flags & MF_PAX_RANDMMAP)
8882+ mm->mmap_base += mm->delta_mmap;
8883+#endif
8884+
8885 mm->get_unmapped_area = arch_get_unmapped_area;
8886 mm->unmap_area = arch_unmap_area;
8887 }
8888diff -urNp linux-2.6.19.1/Documentation/dontdiff linux-2.6.19.1/Documentation/dontdiff
8889--- linux-2.6.19.1/Documentation/dontdiff 2006-11-29 16:57:37.000000000 -0500
8890+++ linux-2.6.19.1/Documentation/dontdiff 2006-12-03 15:15:41.000000000 -0500
8891@@ -55,7 +55,7 @@ aic7*seq.h*
8892 aicasm
8893 aicdb.h*
8894 asm
8895-asm-offsets.*
8896+asm-offsets.h
8897 asm_offsets.*
8898 autoconf.h*
8899 bbootsect
8900@@ -143,4 +143,5 @@ vmlinux.lds
8901 vsyscall.lds
8902 wanxlfw.inc
8903 uImage
8904+utsrelease.h
8905 zImage
8906diff -urNp linux-2.6.19.1/drivers/acpi/glue.c linux-2.6.19.1/drivers/acpi/glue.c
8907--- linux-2.6.19.1/drivers/acpi/glue.c 2006-11-29 16:57:37.000000000 -0500
8908+++ linux-2.6.19.1/drivers/acpi/glue.c 2006-12-03 15:15:55.000000000 -0500
8909@@ -16,7 +16,7 @@
8910 #if ACPI_GLUE_DEBUG
8911 #define DBG(x...) printk(PREFIX x)
8912 #else
8913-#define DBG(x...)
8914+#define DBG(x...) do {} while (0)
8915 #endif
8916 static LIST_HEAD(bus_type_list);
8917 static DECLARE_RWSEM(bus_type_sem);
8918diff -urNp linux-2.6.19.1/drivers/acpi/processor_core.c linux-2.6.19.1/drivers/acpi/processor_core.c
8919--- linux-2.6.19.1/drivers/acpi/processor_core.c 2006-11-29 16:57:37.000000000 -0500
8920+++ linux-2.6.19.1/drivers/acpi/processor_core.c 2006-12-03 15:15:55.000000000 -0500
8921@@ -534,7 +534,7 @@ static int __cpuinit acpi_processor_star
8922 return 0;
8923 }
8924
8925- BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
8926+ BUG_ON(pr->id >= NR_CPUS);
8927
8928 /*
8929 * Buggy BIOS check
8930diff -urNp linux-2.6.19.1/drivers/char/agp/frontend.c linux-2.6.19.1/drivers/char/agp/frontend.c
8931--- linux-2.6.19.1/drivers/char/agp/frontend.c 2006-11-29 16:57:37.000000000 -0500
8932+++ linux-2.6.19.1/drivers/char/agp/frontend.c 2006-12-03 15:15:56.000000000 -0500
8933@@ -818,7 +818,7 @@ static int agpioc_reserve_wrap(struct ag
8934 if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
8935 return -EFAULT;
8936
8937- if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
8938+ if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
8939 return -EFAULT;
8940
8941 client = agp_find_client_by_pid(reserve.pid);
8942diff -urNp linux-2.6.19.1/drivers/char/keyboard.c linux-2.6.19.1/drivers/char/keyboard.c
8943--- linux-2.6.19.1/drivers/char/keyboard.c 2006-11-29 16:57:37.000000000 -0500
8944+++ linux-2.6.19.1/drivers/char/keyboard.c 2006-12-03 15:15:56.000000000 -0500
8945@@ -203,7 +203,7 @@ int setkeycode(unsigned int scancode, un
8946
8947 if (scancode >= dev->keycodemax)
8948 return -EINVAL;
8949- if (keycode < 0 || keycode > KEY_MAX)
8950+ if (keycode > KEY_MAX)
8951 return -EINVAL;
8952 if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
8953 return -EINVAL;
8954@@ -628,6 +628,16 @@ static void k_spec(struct vc_data *vc, u
8955 kbd->kbdmode == VC_MEDIUMRAW) &&
8956 value != KVAL(K_SAK))
8957 return; /* SAK is allowed even in raw mode */
8958+
8959+#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
8960+ {
8961+ void *func = fn_handler[value];
8962+ if (func == fn_show_state || func == fn_show_ptregs ||
8963+ func == fn_show_mem)
8964+ return;
8965+ }
8966+#endif
8967+
8968 fn_handler[value](vc);
8969 }
8970
8971diff -urNp linux-2.6.19.1/drivers/char/mem.c linux-2.6.19.1/drivers/char/mem.c
8972--- linux-2.6.19.1/drivers/char/mem.c 2006-11-29 16:57:37.000000000 -0500
8973+++ linux-2.6.19.1/drivers/char/mem.c 2006-12-03 15:25:55.000000000 -0500
8974@@ -27,6 +27,7 @@
8975 #include <linux/bootmem.h>
8976 #include <linux/pipe_fs_i.h>
8977 #include <linux/pfn.h>
8978+#include <linux/grsecurity.h>
8979
8980 #include <asm/uaccess.h>
8981 #include <asm/io.h>
8982@@ -35,6 +36,10 @@
8983 # include <linux/efi.h>
8984 #endif
8985
8986+#ifdef CONFIG_GRKERNSEC
8987+extern struct file_operations grsec_fops;
8988+#endif
8989+
8990 /*
8991 * Architectures vary in how they handle caching for addresses
8992 * outside of main memory.
8993@@ -174,6 +179,11 @@ static ssize_t write_mem(struct file * f
8994 if (!valid_phys_addr_range(p, count))
8995 return -EFAULT;
8996
8997+#ifdef CONFIG_GRKERNSEC_KMEM
8998+ gr_handle_mem_write();
8999+ return -EPERM;
9000+#endif
9001+
9002 written = 0;
9003
9004 #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
9005@@ -275,6 +285,11 @@ static int mmap_mem(struct file * file,
9006 if (!private_mapping_ok(vma))
9007 return -ENOSYS;
9008
9009+#ifdef CONFIG_GRKERNSEC_KMEM
9010+ if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
9011+ return -EPERM;
9012+#endif
9013+
9014 vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
9015 size,
9016 vma->vm_page_prot);
9017@@ -506,6 +521,11 @@ static ssize_t write_kmem(struct file *
9018 ssize_t written;
9019 char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
9020
9021+#ifdef CONFIG_GRKERNSEC_KMEM
9022+ gr_handle_kmem_write();
9023+ return -EPERM;
9024+#endif
9025+
9026 if (p < (unsigned long) high_memory) {
9027
9028 wrote = count;
9029@@ -646,7 +666,23 @@ static inline size_t read_zero_pagealign
9030 count = size;
9031
9032 zap_page_range(vma, addr, count, NULL);
9033- zeromap_page_range(vma, addr, count, PAGE_COPY);
9034+ zeromap_page_range(vma, addr, count, vma->vm_page_prot);
9035+
9036+#ifdef CONFIG_PAX_SEGMEXEC
9037+ if (vma->vm_flags & VM_MIRROR) {
9038+ unsigned long addr_m;
9039+ struct vm_area_struct * vma_m;
9040+
9041+ addr_m = vma->vm_start + vma->vm_mirror;
9042+ vma_m = find_vma(mm, addr_m);
9043+ if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
9044+ addr_m = addr + vma->vm_mirror;
9045+ zap_page_range(vma_m, addr_m, count, NULL);
9046+ } else
9047+ printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
9048+ addr, vma->vm_start);
9049+ }
9050+#endif
9051
9052 size -= count;
9053 buf += count;
9054@@ -795,6 +831,16 @@ static loff_t memory_lseek(struct file *
9055
9056 static int open_port(struct inode * inode, struct file * filp)
9057 {
9058+#ifdef CONFIG_GRKERNSEC_KMEM
9059+ gr_handle_open_port();
9060+ return -EPERM;
9061+#endif
9062+
9063+ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
9064+}
9065+
9066+static int open_mem(struct inode * inode, struct file * filp)
9067+{
9068 return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
9069 }
9070
9071@@ -802,7 +848,6 @@ static int open_port(struct inode * inod
9072 #define full_lseek null_lseek
9073 #define write_zero write_null
9074 #define read_full read_zero
9075-#define open_mem open_port
9076 #define open_kmem open_mem
9077 #define open_oldmem open_mem
9078
9079@@ -935,6 +980,11 @@ static int memory_open(struct inode * in
9080 filp->f_op = &oldmem_fops;
9081 break;
9082 #endif
9083+#ifdef CONFIG_GRKERNSEC
9084+ case 13:
9085+ filp->f_op = &grsec_fops;
9086+ break;
9087+#endif
9088 default:
9089 return -ENXIO;
9090 }
9091@@ -967,6 +1017,9 @@ static const struct {
9092 #ifdef CONFIG_CRASH_DUMP
9093 {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
9094 #endif
9095+#ifdef CONFIG_GRKERNSEC
9096+ {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops},
9097+#endif
9098 };
9099
9100 static struct class *mem_class;
9101diff -urNp linux-2.6.19.1/drivers/char/random.c linux-2.6.19.1/drivers/char/random.c
9102--- linux-2.6.19.1/drivers/char/random.c 2006-11-29 16:57:37.000000000 -0500
9103+++ linux-2.6.19.1/drivers/char/random.c 2006-12-03 15:15:56.000000000 -0500
9104@@ -248,8 +248,13 @@
9105 /*
9106 * Configuration information
9107 */
9108+#ifdef CONFIG_GRKERNSEC_RANDNET
9109+#define INPUT_POOL_WORDS 512
9110+#define OUTPUT_POOL_WORDS 128
9111+#else
9112 #define INPUT_POOL_WORDS 128
9113 #define OUTPUT_POOL_WORDS 32
9114+#endif
9115 #define SEC_XFER_SIZE 512
9116
9117 /*
9118@@ -286,10 +291,17 @@ static struct poolinfo {
9119 int poolwords;
9120 int tap1, tap2, tap3, tap4, tap5;
9121 } poolinfo_table[] = {
9122+#ifdef CONFIG_GRKERNSEC_RANDNET
9123+ /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
9124+ { 512, 411, 308, 208, 104, 1 },
9125+ /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
9126+ { 128, 103, 76, 51, 25, 1 },
9127+#else
9128 /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
9129 { 128, 103, 76, 51, 25, 1 },
9130 /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
9131 { 32, 26, 20, 14, 7, 1 },
9132+#endif
9133 #if 0
9134 /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
9135 { 2048, 1638, 1231, 819, 411, 1 },
9136@@ -1662,3 +1674,25 @@ randomize_range(unsigned long start, uns
9137 return 0;
9138 return PAGE_ALIGN(get_random_int() % range + start);
9139 }
9140+
9141+#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
9142+unsigned long pax_get_random_long(void)
9143+{
9144+ static time_t rekey_time;
9145+ static __u32 secret[12];
9146+ time_t t;
9147+
9148+ /*
9149+ * Pick a random secret every REKEY_INTERVAL seconds.
9150+ */
9151+ t = get_seconds();
9152+ if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
9153+ rekey_time = t;
9154+ get_random_bytes(secret, sizeof(secret));
9155+ }
9156+
9157+ secret[1] = half_md4_transform(secret+8, secret);
9158+ secret[0] = half_md4_transform(secret+8, secret);
9159+ return *(unsigned long *)secret;
9160+}
9161+#endif
9162diff -urNp linux-2.6.19.1/drivers/char/vt_ioctl.c linux-2.6.19.1/drivers/char/vt_ioctl.c
9163--- linux-2.6.19.1/drivers/char/vt_ioctl.c 2006-11-29 16:57:37.000000000 -0500
9164+++ linux-2.6.19.1/drivers/char/vt_ioctl.c 2006-12-03 15:15:57.000000000 -0500
9165@@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
9166 case KDSKBENT:
9167 if (!perm)
9168 return -EPERM;
9169+
9170+#ifdef CONFIG_GRKERNSEC
9171+ if (!capable(CAP_SYS_TTY_CONFIG))
9172+ return -EPERM;
9173+#endif
9174+
9175 if (!i && v == K_NOSUCHMAP) {
9176 /* deallocate map */
9177 key_map = key_maps[s];
9178@@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry
9179 goto reterr;
9180 }
9181
9182+#ifdef CONFIG_GRKERNSEC
9183+ if (!capable(CAP_SYS_TTY_CONFIG)) {
9184+ ret = -EPERM;
9185+ goto reterr;
9186+ }
9187+#endif
9188+
9189 q = func_table[i];
9190 first_free = funcbufptr + (funcbufsize - funcbufleft);
9191 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
9192diff -urNp linux-2.6.19.1/drivers/edac/edac_mc.h linux-2.6.19.1/drivers/edac/edac_mc.h
9193--- linux-2.6.19.1/drivers/edac/edac_mc.h 2006-11-29 16:57:37.000000000 -0500
9194+++ linux-2.6.19.1/drivers/edac/edac_mc.h 2006-12-03 15:15:57.000000000 -0500
9195@@ -71,11 +71,11 @@ extern int edac_debug_level;
9196
9197 #else /* !CONFIG_EDAC_DEBUG */
9198
9199-#define debugf0( ... )
9200-#define debugf1( ... )
9201-#define debugf2( ... )
9202-#define debugf3( ... )
9203-#define debugf4( ... )
9204+#define debugf0( ... ) do {} while (0)
9205+#define debugf1( ... ) do {} while (0)
9206+#define debugf2( ... ) do {} while (0)
9207+#define debugf3( ... ) do {} while (0)
9208+#define debugf4( ... ) do {} while (0)
9209
9210 #endif /* !CONFIG_EDAC_DEBUG */
9211
9212diff -urNp linux-2.6.19.1/drivers/hwmon/fscpos.c linux-2.6.19.1/drivers/hwmon/fscpos.c
9213--- linux-2.6.19.1/drivers/hwmon/fscpos.c 2006-11-29 16:57:37.000000000 -0500
9214+++ linux-2.6.19.1/drivers/hwmon/fscpos.c 2006-12-03 15:15:59.000000000 -0500
9215@@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
9216 unsigned long v = simple_strtoul(buf, NULL, 10);
9217
9218 /* Range: 0..255 */
9219- if (v < 0) v = 0;
9220 if (v > 255) v = 255;
9221
9222 mutex_lock(&data->update_lock);
9223diff -urNp linux-2.6.19.1/drivers/hwmon/w83791d.c linux-2.6.19.1/drivers/hwmon/w83791d.c
9224--- linux-2.6.19.1/drivers/hwmon/w83791d.c 2006-11-29 16:57:37.000000000 -0500
9225+++ linux-2.6.19.1/drivers/hwmon/w83791d.c 2006-12-03 15:15:59.000000000 -0500
9226@@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
9227 static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
9228 static int w83791d_detach_client(struct i2c_client *client);
9229
9230-static int w83791d_read(struct i2c_client *client, u8 register);
9231-static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
9232+static int w83791d_read(struct i2c_client *client, u8 reg);
9233+static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
9234 static struct w83791d_data *w83791d_update_device(struct device *dev);
9235
9236 #ifdef DEBUG
9237diff -urNp linux-2.6.19.1/drivers/ide/ide-cd.c linux-2.6.19.1/drivers/ide/ide-cd.c
9238--- linux-2.6.19.1/drivers/ide/ide-cd.c 2006-11-29 16:57:37.000000000 -0500
9239+++ linux-2.6.19.1/drivers/ide/ide-cd.c 2006-12-03 15:15:59.000000000 -0500
9240@@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
9241 sector &= ~(bio_sectors -1);
9242 valid = (sector - failed_command->sector) << 9;
9243
9244- if (valid < 0)
9245- valid = 0;
9246 if (sector < get_capacity(info->disk) &&
9247 drive->probed_capacity - sector < 4 * 75) {
9248 set_capacity(info->disk, sector);
9249diff -urNp linux-2.6.19.1/drivers/ieee1394/dv1394.c linux-2.6.19.1/drivers/ieee1394/dv1394.c
9250--- linux-2.6.19.1/drivers/ieee1394/dv1394.c 2006-11-29 16:57:37.000000000 -0500
9251+++ linux-2.6.19.1/drivers/ieee1394/dv1394.c 2006-12-03 15:15:59.000000000 -0500
9252@@ -919,7 +919,7 @@ static int do_dv1394_init(struct video_c
9253 /* default SYT offset is 3 cycles */
9254 init->syt_offset = 3;
9255
9256- if ( (init->channel > 63) || (init->channel < 0) )
9257+ if (init->channel > 63)
9258 init->channel = 63;
9259
9260 chan_mask = (u64)1 << init->channel;
9261diff -urNp linux-2.6.19.1/drivers/ieee1394/hosts.c linux-2.6.19.1/drivers/ieee1394/hosts.c
9262--- linux-2.6.19.1/drivers/ieee1394/hosts.c 2006-11-29 16:57:37.000000000 -0500
9263+++ linux-2.6.19.1/drivers/ieee1394/hosts.c 2006-12-03 15:15:59.000000000 -0500
9264@@ -75,6 +75,7 @@ static int dummy_isoctl(struct hpsb_iso
9265 }
9266
9267 static struct hpsb_host_driver dummy_driver = {
9268+ .name = "dummy",
9269 .transmit_packet = dummy_transmit_packet,
9270 .devctl = dummy_devctl,
9271 .isoctl = dummy_isoctl
9272diff -urNp linux-2.6.19.1/drivers/ieee1394/ohci1394.c linux-2.6.19.1/drivers/ieee1394/ohci1394.c
9273--- linux-2.6.19.1/drivers/ieee1394/ohci1394.c 2006-11-29 16:57:37.000000000 -0500
9274+++ linux-2.6.19.1/drivers/ieee1394/ohci1394.c 2006-12-03 15:15:59.000000000 -0500
9275@@ -161,9 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
9276 printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
9277
9278 /* Module Parameters */
9279-static int phys_dma = 1;
9280+static int phys_dma = 0;
9281 module_param(phys_dma, int, 0444);
9282-MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
9283+MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
9284
9285 static void dma_trm_tasklet(unsigned long data);
9286 static void dma_trm_reset(struct dma_trm_ctx *d);
9287diff -urNp linux-2.6.19.1/drivers/ieee1394/sbp2.c linux-2.6.19.1/drivers/ieee1394/sbp2.c
9288--- linux-2.6.19.1/drivers/ieee1394/sbp2.c 2006-11-29 16:57:37.000000000 -0500
9289+++ linux-2.6.19.1/drivers/ieee1394/sbp2.c 2006-12-10 21:43:36.000000000 -0500
9290@@ -2664,7 +2664,7 @@ static struct scsi_host_template scsi_dr
9291 .sdev_attrs = sbp2_sysfs_sdev_attrs,
9292 };
9293
9294-static int sbp2_module_init(void)
9295+static int __init sbp2_module_init(void)
9296 {
9297 int ret;
9298
9299diff -urNp linux-2.6.19.1/drivers/ieee1394/video1394.c linux-2.6.19.1/drivers/ieee1394/video1394.c
9300--- linux-2.6.19.1/drivers/ieee1394/video1394.c 2006-11-29 16:57:37.000000000 -0500
9301+++ linux-2.6.19.1/drivers/ieee1394/video1394.c 2006-12-03 15:15:59.000000000 -0500
9302@@ -890,7 +890,7 @@ static int __video1394_ioctl(struct file
9303 d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
9304 if (d == NULL) return -EFAULT;
9305
9306- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
9307+ if (v.buffer>=d->num_desc - 1) {
9308 PRINT(KERN_ERR, ohci->host->id,
9309 "Buffer %d out of range",v.buffer);
9310 return -EINVAL;
9311@@ -955,7 +955,7 @@ static int __video1394_ioctl(struct file
9312 d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel);
9313 if (d == NULL) return -EFAULT;
9314
9315- if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) {
9316+ if (v.buffer>d->num_desc - 1) {
9317 PRINT(KERN_ERR, ohci->host->id,
9318 "Buffer %d out of range",v.buffer);
9319 return -EINVAL;
9320@@ -1026,7 +1026,7 @@ static int __video1394_ioctl(struct file
9321 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
9322 if (d == NULL) return -EFAULT;
9323
9324- if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
9325+ if (v.buffer>=d->num_desc - 1) {
9326 PRINT(KERN_ERR, ohci->host->id,
9327 "Buffer %d out of range",v.buffer);
9328 return -EINVAL;
9329@@ -1128,7 +1128,7 @@ static int __video1394_ioctl(struct file
9330 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
9331 if (d == NULL) return -EFAULT;
9332
9333- if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
9334+ if (v.buffer>=d->num_desc-1) {
9335 PRINT(KERN_ERR, ohci->host->id,
9336 "Buffer %d out of range",v.buffer);
9337 return -EINVAL;
9338diff -urNp linux-2.6.19.1/drivers/md/bitmap.c linux-2.6.19.1/drivers/md/bitmap.c
9339--- linux-2.6.19.1/drivers/md/bitmap.c 2006-11-29 16:57:37.000000000 -0500
9340+++ linux-2.6.19.1/drivers/md/bitmap.c 2006-12-03 15:16:00.000000000 -0500
9341@@ -57,7 +57,7 @@
9342 # if DEBUG > 0
9343 # define PRINTK(x...) printk(KERN_DEBUG x)
9344 # else
9345-# define PRINTK(x...)
9346+# define PRINTK(x...) do {} while (0)
9347 # endif
9348 #endif
9349
9350diff -urNp linux-2.6.19.1/drivers/mtd/devices/doc2001.c linux-2.6.19.1/drivers/mtd/devices/doc2001.c
9351--- linux-2.6.19.1/drivers/mtd/devices/doc2001.c 2006-11-29 16:57:37.000000000 -0500
9352+++ linux-2.6.19.1/drivers/mtd/devices/doc2001.c 2006-12-03 15:16:01.000000000 -0500
9353@@ -401,6 +401,8 @@ static int doc_read (struct mtd_info *mt
9354 /* Don't allow read past end of device */
9355 if (from >= this->totlen)
9356 return -EINVAL;
9357+ if (!len)
9358+ return -EINVAL;
9359
9360 /* Don't allow a single read to cross a 512-byte block boundary */
9361 if (from + len > ((from | 0x1ff) + 1))
9362diff -urNp linux-2.6.19.1/drivers/net/eepro100.c linux-2.6.19.1/drivers/net/eepro100.c
9363--- linux-2.6.19.1/drivers/net/eepro100.c 2006-11-29 16:57:37.000000000 -0500
9364+++ linux-2.6.19.1/drivers/net/eepro100.c 2006-12-03 15:16:04.000000000 -0500
9365@@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
9366 # define rx_align(skb) skb_reserve((skb), 2)
9367 # define RxFD_ALIGNMENT __attribute__ ((aligned (2), packed))
9368 #else
9369-# define rx_align(skb)
9370+# define rx_align(skb) do {} while (0)
9371 # define RxFD_ALIGNMENT
9372 #endif
9373
9374diff -urNp linux-2.6.19.1/drivers/net/pcnet32.c linux-2.6.19.1/drivers/net/pcnet32.c
9375--- linux-2.6.19.1/drivers/net/pcnet32.c 2006-11-29 16:57:37.000000000 -0500
9376+++ linux-2.6.19.1/drivers/net/pcnet32.c 2006-12-03 15:16:05.000000000 -0500
9377@@ -82,7 +82,7 @@ static int cards_found;
9378 /*
9379 * VLB I/O addresses
9380 */
9381-static unsigned int pcnet32_portlist[] __initdata =
9382+static unsigned int pcnet32_portlist[] __devinitdata =
9383 { 0x300, 0x320, 0x340, 0x360, 0 };
9384
9385 static int pcnet32_debug = 0;
9386diff -urNp linux-2.6.19.1/drivers/pci/proc.c linux-2.6.19.1/drivers/pci/proc.c
9387--- linux-2.6.19.1/drivers/pci/proc.c 2006-11-29 16:57:37.000000000 -0500
9388+++ linux-2.6.19.1/drivers/pci/proc.c 2006-12-03 15:16:06.000000000 -0500
9389@@ -467,7 +467,15 @@ static int __init pci_proc_init(void)
9390 {
9391 struct proc_dir_entry *entry;
9392 struct pci_dev *dev = NULL;
9393+#ifdef CONFIG_GRKERNSEC_PROC_ADD
9394+#ifdef CONFIG_GRKERNSEC_PROC_USER
9395+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
9396+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
9397+ proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
9398+#endif
9399+#else
9400 proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
9401+#endif
9402 entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
9403 if (entry)
9404 entry->proc_fops = &proc_bus_pci_dev_operations;
9405diff -urNp linux-2.6.19.1/drivers/pnp/pnpbios/bioscalls.c linux-2.6.19.1/drivers/pnp/pnpbios/bioscalls.c
9406--- linux-2.6.19.1/drivers/pnp/pnpbios/bioscalls.c 2006-11-29 16:57:37.000000000 -0500
9407+++ linux-2.6.19.1/drivers/pnp/pnpbios/bioscalls.c 2006-12-03 15:16:06.000000000 -0500
9408@@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
9409 set_limit(gdt[(selname) >> 3], size); \
9410 } while(0)
9411
9412-static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
9413+static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
9414
9415 /*
9416 * At some point we want to use this stack frame pointer to unwind
9417@@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
9418 struct desc_struct save_desc_40;
9419 int cpu;
9420
9421+#ifdef CONFIG_PAX_KERNEXEC
9422+ unsigned long cr0;
9423+#endif
9424+
9425 /*
9426 * PnP BIOSes are generally not terribly re-entrant.
9427 * Also, don't rely on them to save everything correctly.
9428@@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
9429 /* On some boxes IRQ's during PnP BIOS calls are deadly. */
9430 spin_lock_irqsave(&pnp_bios_lock, flags);
9431
9432+#ifdef CONFIG_PAX_KERNEXEC
9433+ pax_open_kernel(cr0);
9434+#endif
9435+
9436 /* The lock prevents us bouncing CPU here */
9437 if (ts1_size)
9438 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
9439@@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
9440 "i" (0)
9441 : "memory"
9442 );
9443- spin_unlock_irqrestore(&pnp_bios_lock, flags);
9444
9445 get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
9446+
9447+#ifdef CONFIG_PAX_KERNEXEC
9448+ pax_close_kernel(cr0);
9449+#endif
9450+
9451+ spin_unlock_irqrestore(&pnp_bios_lock, flags);
9452 put_cpu();
9453
9454 /* If we get here and this is set then the PnP BIOS faulted on us. */
9455diff -urNp linux-2.6.19.1/drivers/pnp/resource.c linux-2.6.19.1/drivers/pnp/resource.c
9456--- linux-2.6.19.1/drivers/pnp/resource.c 2006-11-29 16:57:37.000000000 -0500
9457+++ linux-2.6.19.1/drivers/pnp/resource.c 2006-12-03 15:16:06.000000000 -0500
9458@@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev,
9459 return 1;
9460
9461 /* check if the resource is valid */
9462- if (*irq < 0 || *irq > 15)
9463+ if (*irq > 15)
9464 return 0;
9465
9466 /* check if the resource is reserved */
9467@@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev,
9468 return 1;
9469
9470 /* check if the resource is valid */
9471- if (*dma < 0 || *dma == 4 || *dma > 7)
9472+ if (*dma == 4 || *dma > 7)
9473 return 0;
9474
9475 /* check if the resource is reserved */
9476diff -urNp linux-2.6.19.1/drivers/scsi/scsi_logging.h linux-2.6.19.1/drivers/scsi/scsi_logging.h
9477--- linux-2.6.19.1/drivers/scsi/scsi_logging.h 2006-11-29 16:57:37.000000000 -0500
9478+++ linux-2.6.19.1/drivers/scsi/scsi_logging.h 2006-12-03 15:16:10.000000000 -0500
9479@@ -51,7 +51,7 @@ do { \
9480 } while (0); \
9481 } while (0)
9482 #else
9483-#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
9484+#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
9485 #endif /* CONFIG_SCSI_LOGGING */
9486
9487 /*
9488diff -urNp linux-2.6.19.1/drivers/usb/storage/debug.h linux-2.6.19.1/drivers/usb/storage/debug.h
9489--- linux-2.6.19.1/drivers/usb/storage/debug.h 2006-11-29 16:57:37.000000000 -0500
9490+++ linux-2.6.19.1/drivers/usb/storage/debug.h 2006-12-03 15:16:11.000000000 -0500
9491@@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char
9492 #define US_DEBUGPX(x...) printk( x )
9493 #define US_DEBUG(x) x
9494 #else
9495-#define US_DEBUGP(x...)
9496-#define US_DEBUGPX(x...)
9497-#define US_DEBUG(x)
9498+#define US_DEBUGP(x...) do {} while (0)
9499+#define US_DEBUGPX(x...) do {} while (0)
9500+#define US_DEBUG(x) do {} while (0)
9501 #endif
9502
9503 #endif
9504diff -urNp linux-2.6.19.1/drivers/video/fbcmap.c linux-2.6.19.1/drivers/video/fbcmap.c
9505--- linux-2.6.19.1/drivers/video/fbcmap.c 2006-11-29 16:57:37.000000000 -0500
9506+++ linux-2.6.19.1/drivers/video/fbcmap.c 2006-12-03 15:16:11.000000000 -0500
9507@@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
9508 int rc, size = cmap->len * sizeof(u16);
9509 struct fb_cmap umap;
9510
9511- if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
9512- !info->fbops->fb_setcmap))
9513+ if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
9514 return -EINVAL;
9515
9516 memset(&umap, 0, sizeof(struct fb_cmap));
9517diff -urNp linux-2.6.19.1/drivers/video/fbmem.c linux-2.6.19.1/drivers/video/fbmem.c
9518--- linux-2.6.19.1/drivers/video/fbmem.c 2006-11-29 16:57:37.000000000 -0500
9519+++ linux-2.6.19.1/drivers/video/fbmem.c 2006-12-03 15:16:11.000000000 -0500
9520@@ -936,9 +936,9 @@ fb_ioctl(struct inode *inode, struct fil
9521 case FBIOPUT_CON2FBMAP:
9522 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
9523 return - EFAULT;
9524- if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
9525+ if (con2fb.console > MAX_NR_CONSOLES)
9526 return -EINVAL;
9527- if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
9528+ if (con2fb.framebuffer >= FB_MAX)
9529 return -EINVAL;
9530 #ifdef CONFIG_KMOD
9531 if (!registered_fb[con2fb.framebuffer])
9532diff -urNp linux-2.6.19.1/drivers/video/fbmon.c linux-2.6.19.1/drivers/video/fbmon.c
9533--- linux-2.6.19.1/drivers/video/fbmon.c 2006-11-29 16:57:37.000000000 -0500
9534+++ linux-2.6.19.1/drivers/video/fbmon.c 2006-12-03 15:16:11.000000000 -0500
9535@@ -45,7 +45,7 @@
9536 #ifdef DEBUG
9537 #define DPRINTK(fmt, args...) printk(fmt,## args)
9538 #else
9539-#define DPRINTK(fmt, args...)
9540+#define DPRINTK(fmt, args...) do {} while (0)
9541 #endif
9542
9543 #define FBMON_FIX_HEADER 1
9544diff -urNp linux-2.6.19.1/drivers/video/i810/i810_accel.c linux-2.6.19.1/drivers/video/i810/i810_accel.c
9545--- linux-2.6.19.1/drivers/video/i810/i810_accel.c 2006-11-29 16:57:37.000000000 -0500
9546+++ linux-2.6.19.1/drivers/video/i810/i810_accel.c 2006-12-03 15:16:11.000000000 -0500
9547@@ -73,6 +73,7 @@ static inline int wait_for_space(struct
9548 }
9549 }
9550 printk("ringbuffer lockup!!!\n");
9551+ printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
9552 i810_report_error(mmio);
9553 par->dev_flags |= LOCKUP;
9554 info->pixmap.scan_align = 1;
9555diff -urNp linux-2.6.19.1/drivers/video/i810/i810_main.c linux-2.6.19.1/drivers/video/i810/i810_main.c
9556--- linux-2.6.19.1/drivers/video/i810/i810_main.c 2006-11-29 16:57:37.000000000 -0500
9557+++ linux-2.6.19.1/drivers/video/i810/i810_main.c 2006-12-03 15:16:11.000000000 -0500
9558@@ -1506,7 +1506,7 @@ static int i810fb_cursor(struct fb_info
9559 int size = ((cursor->image.width + 7) >> 3) *
9560 cursor->image.height;
9561 int i;
9562- u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
9563+ u8 *data = kmalloc(64 * 8, GFP_KERNEL);
9564
9565 if (data == NULL)
9566 return -ENOMEM;
9567diff -urNp linux-2.6.19.1/drivers/video/vesafb.c linux-2.6.19.1/drivers/video/vesafb.c
9568--- linux-2.6.19.1/drivers/video/vesafb.c 2006-11-29 16:57:37.000000000 -0500
9569+++ linux-2.6.19.1/drivers/video/vesafb.c 2006-12-03 15:16:12.000000000 -0500
9570@@ -267,7 +267,7 @@ static int __init vesafb_probe(struct pl
9571 size_remap = size_total;
9572 vesafb_fix.smem_len = size_remap;
9573
9574-#ifndef __i386__
9575+#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
9576 screen_info.vesapm_seg = 0;
9577 #endif
9578
9579diff -urNp linux-2.6.19.1/fs/binfmt_aout.c linux-2.6.19.1/fs/binfmt_aout.c
9580--- linux-2.6.19.1/fs/binfmt_aout.c 2006-11-29 16:57:37.000000000 -0500
9581+++ linux-2.6.19.1/fs/binfmt_aout.c 2006-12-03 15:16:12.000000000 -0500
9582@@ -24,6 +24,7 @@
c3e8c1b5 9583 #include <linux/personality.h>
9584 #include <linux/init.h>
b6fa5d20 9585 #include <linux/vs_memory.h>
c3e8c1b5 9586+#include <linux/grsecurity.h>
9587
9588 #include <asm/system.h>
9589 #include <asm/uaccess.h>
9590@@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
9591 /* If the size of the dump file exceeds the rlimit, then see what would happen
9592 if we wrote the stack, but not the data area. */
9593 #ifdef __sparc__
9594+ gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
9595 if ((dump.u_dsize+dump.u_ssize) >
9596 current->signal->rlim[RLIMIT_CORE].rlim_cur)
9597 dump.u_dsize = 0;
9598 #else
9599+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
9600 if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
9601 current->signal->rlim[RLIMIT_CORE].rlim_cur)
9602 dump.u_dsize = 0;
9603@@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
9604
9605 /* Make sure we have enough room to write the stack and data areas. */
9606 #ifdef __sparc__
9607+ gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
9608 if ((dump.u_ssize) >
9609 current->signal->rlim[RLIMIT_CORE].rlim_cur)
9610 dump.u_ssize = 0;
9611 #else
9612+ gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
9613 if ((dump.u_ssize+1) * PAGE_SIZE >
9614 current->signal->rlim[RLIMIT_CORE].rlim_cur)
9615 dump.u_ssize = 0;
9616@@ -294,6 +299,8 @@ static int load_aout_binary(struct linux
9617 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
9618 if (rlim >= RLIM_INFINITY)
9619 rlim = ~0;
9620+
9621+ gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
9622 if (ex.a_data + ex.a_bss > rlim)
9623 return -ENOMEM;
9624
9625@@ -326,6 +333,28 @@ static int load_aout_binary(struct linux
9626 current->mm->mmap = NULL;
9627 compute_creds(bprm);
9628 current->flags &= ~PF_FORKNOEXEC;
9629+
9630+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
9631+ current->mm->pax_flags = 0UL;
9632+#endif
9633+
9634+#ifdef CONFIG_PAX_PAGEEXEC
9635+ if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
9636+ current->mm->pax_flags |= MF_PAX_PAGEEXEC;
9637+
9638+#ifdef CONFIG_PAX_EMUTRAMP
9639+ if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
9640+ current->mm->pax_flags |= MF_PAX_EMUTRAMP;
9641+#endif
9642+
9643+#ifdef CONFIG_PAX_MPROTECT
9644+ if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
9645+ current->mm->pax_flags |= MF_PAX_MPROTECT;
9646+#endif
9647+
9648+ }
9649+#endif
9650+
9651 #ifdef __sparc__
9652 if (N_MAGIC(ex) == NMAGIC) {
9653 loff_t pos = fd_offset;
9654@@ -421,7 +450,7 @@ static int load_aout_binary(struct linux
9655
9656 down_write(&current->mm->mmap_sem);
9657 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
9658- PROT_READ | PROT_WRITE | PROT_EXEC,
9659+ PROT_READ | PROT_WRITE,
9660 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
9661 fd_offset + ex.a_text);
9662 up_write(&current->mm->mmap_sem);
9663diff -urNp linux-2.6.19.1/fs/binfmt_elf.c linux-2.6.19.1/fs/binfmt_elf.c
9664--- linux-2.6.19.1/fs/binfmt_elf.c 2006-11-29 16:57:37.000000000 -0500
9665+++ linux-2.6.19.1/fs/binfmt_elf.c 2006-12-03 15:16:12.000000000 -0500
9666@@ -39,10 +39,16 @@
c3e8c1b5 9667 #include <linux/random.h>
9668 #include <linux/elf.h>
b6fa5d20 9669 #include <linux/vs_memory.h>
c3e8c1b5 9670+#include <linux/grsecurity.h>
9671+
9672 #include <asm/uaccess.h>
9673 #include <asm/param.h>
9674 #include <asm/page.h>
9675
9676+#ifdef CONFIG_PAX_SEGMEXEC
9677+#include <asm/desc.h>
9678+#endif
9679+
9680 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
9681 static int load_elf_library(struct file *);
9682 static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
9683@@ -87,6 +93,8 @@ static struct linux_binfmt elf_format =
9684
9685 static int set_brk(unsigned long start, unsigned long end)
9686 {
9687+ unsigned long e = end;
9688+
9689 start = ELF_PAGEALIGN(start);
9690 end = ELF_PAGEALIGN(end);
9691 if (end > start) {
9692@@ -97,7 +105,7 @@ static int set_brk(unsigned long start,
9693 if (BAD_ADDR(addr))
9694 return addr;
9695 }
9696- current->mm->start_brk = current->mm->brk = end;
9697+ current->mm->start_brk = current->mm->brk = e;
9698 return 0;
9699 }
9700
9701@@ -315,10 +323,9 @@ static unsigned long load_elf_interp(str
9702 {
9703 struct elf_phdr *elf_phdata;
9704 struct elf_phdr *eppnt;
9705- unsigned long load_addr = 0;
9706- int load_addr_set = 0;
9707+ unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
9708 unsigned long last_bss = 0, elf_bss = 0;
9709- unsigned long error = ~0UL;
9710+ unsigned long error = -EINVAL;
9711 int retval, i, size;
9712
9713 /* First of all, some simple consistency checks */
9714@@ -357,66 +364,86 @@ static unsigned long load_elf_interp(str
9715 goto out_close;
9716 }
9717
9718+#ifdef CONFIG_PAX_SEGMEXEC
9719+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
9720+ task_size = SEGMEXEC_TASK_SIZE;
9721+#endif
9722+
9723 eppnt = elf_phdata;
9724+ min_addr = task_size;
9725+ max_addr = 0;
9726+ error = -ENOMEM;
9727+
9728 for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
9729- if (eppnt->p_type == PT_LOAD) {
9730- int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
9731- int elf_prot = 0;
9732- unsigned long vaddr = 0;
9733- unsigned long k, map_addr;
9734-
9735- if (eppnt->p_flags & PF_R)
9736- elf_prot = PROT_READ;
9737- if (eppnt->p_flags & PF_W)
9738- elf_prot |= PROT_WRITE;
9739- if (eppnt->p_flags & PF_X)
9740- elf_prot |= PROT_EXEC;
9741- vaddr = eppnt->p_vaddr;
9742- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
9743- elf_type |= MAP_FIXED;
9744-
9745- map_addr = elf_map(interpreter, load_addr + vaddr,
9746- eppnt, elf_prot, elf_type);
9747- error = map_addr;
9748- if (BAD_ADDR(map_addr))
9749- goto out_close;
9750-
9751- if (!load_addr_set &&
9752- interp_elf_ex->e_type == ET_DYN) {
9753- load_addr = map_addr - ELF_PAGESTART(vaddr);
9754- load_addr_set = 1;
9755- }
9756+ if (eppnt->p_type != PT_LOAD)
9757+ continue;
9758
9759- /*
9760- * Check to see if the section's size will overflow the
9761- * allowed task size. Note that p_filesz must always be
9762- * <= p_memsize so it's only necessary to check p_memsz.
9763- */
9764- k = load_addr + eppnt->p_vaddr;
9765- if (BAD_ADDR(k) ||
9766- eppnt->p_filesz > eppnt->p_memsz ||
9767- eppnt->p_memsz > TASK_SIZE ||
9768- TASK_SIZE - eppnt->p_memsz < k) {
9769- error = -ENOMEM;
9770- goto out_close;
9771- }
9772+ /*
9773+ * Check to see if the section's size will overflow the
9774+ * allowed task size. Note that p_filesz must always be
9775+ * <= p_memsize so it is only necessary to check p_memsz.
9776+ */
9777+ if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
9778+ goto out_close;
9779
9780- /*
9781- * Find the end of the file mapping for this phdr, and
9782- * keep track of the largest address we see for this.
9783- */
9784- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
9785- if (k > elf_bss)
9786- elf_bss = k;
9787+ if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
9788+ min_addr = ELF_PAGESTART(eppnt->p_vaddr);
9789+ if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
9790+ max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
9791+ }
9792+ if (min_addr >= max_addr || max_addr > task_size)
9793+ goto out_close;
9794
9795- /*
9796- * Do the same thing for the memory mapping - between
9797- * elf_bss and last_bss is the bss section.
9798- */
9799- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
9800- if (k > last_bss)
9801- last_bss = k;
9802- }
9803+ if (interp_elf_ex->e_type == ET_DYN) {
9804+ load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
9805+
9806+ if (load_addr >= task_size)
9807+ goto out_close;
9808+
9809+ load_addr -= min_addr;
9810+ }
9811+
9812+ eppnt = elf_phdata;
9813+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
9814+ int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
9815+ int elf_prot = 0;
9816+ unsigned long vaddr = 0;
9817+ unsigned long k, map_addr;
9818+
9819+ if (eppnt->p_type != PT_LOAD)
9820+ continue;
9821+
9822+ if (eppnt->p_flags & PF_R)
9823+ elf_prot = PROT_READ;
9824+ if (eppnt->p_flags & PF_W)
9825+ elf_prot |= PROT_WRITE;
9826+ if (eppnt->p_flags & PF_X)
9827+ elf_prot |= PROT_EXEC;
9828+ vaddr = eppnt->p_vaddr;
9829+
9830+ map_addr = elf_map(interpreter, load_addr + vaddr,
9831+ eppnt, elf_prot, elf_type);
9832+ error = map_addr;
9833+ if (BAD_ADDR(map_addr))
9834+ goto out_close;
9835+
9836+ k = load_addr + eppnt->p_vaddr;
9837+
9838+ /*
9839+ * Find the end of the file mapping for this phdr, and
9840+ * keep track of the largest address we see for this.
9841+ */
9842+ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
9843+ if (k > elf_bss)
9844+ elf_bss = k;
9845+
9846+ /*
9847+ * Do the same thing for the memory mapping - between
9848+ * elf_bss and last_bss is the bss section.
9849+ */
9850+ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
9851+ if (k > last_bss)
9852+ last_bss = k;
9853 }
9854
9855 /*
9856@@ -444,6 +471,8 @@ static unsigned long load_elf_interp(str
9857
9858 *interp_load_addr = load_addr;
9859 error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
9860+ if (BAD_ADDR(error))
9861+ error = -EFAULT;
9862
9863 out_close:
9864 kfree(elf_phdata);
9865@@ -454,7 +483,7 @@ out:
9866 static unsigned long load_aout_interp(struct exec *interp_ex,
9867 struct file *interpreter)
9868 {
9869- unsigned long text_data, elf_entry = ~0UL;
9870+ unsigned long text_data, elf_entry = -EINVAL;
9871 char __user * addr;
9872 loff_t offset;
9873
9874@@ -497,6 +526,180 @@ out:
9875 return elf_entry;
9876 }
9877
9878+#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
9879+static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
9880+{
9881+ unsigned long pax_flags = 0UL;
9882+
9883+#ifdef CONFIG_PAX_PAGEEXEC
9884+ if (elf_phdata->p_flags & PF_PAGEEXEC)
9885+ pax_flags |= MF_PAX_PAGEEXEC;
9886+#endif
9887+
9888+#ifdef CONFIG_PAX_SEGMEXEC
9889+ if (elf_phdata->p_flags & PF_SEGMEXEC)
9890+ pax_flags |= MF_PAX_SEGMEXEC;
9891+#endif
9892+
9893+#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9894+ if (pax_flags & MF_PAX_PAGEEXEC)
9895+ pax_flags &= ~MF_PAX_SEGMEXEC;
9896+#endif
9897+
9898+#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9899+ if (pax_flags & MF_PAX_SEGMEXEC)
9900+ pax_flags &= ~MF_PAX_PAGEEXEC;
9901+#endif
9902+
9903+#ifdef CONFIG_PAX_EMUTRAMP
9904+ if (elf_phdata->p_flags & PF_EMUTRAMP)
9905+ pax_flags |= MF_PAX_EMUTRAMP;
9906+#endif
9907+
9908+#ifdef CONFIG_PAX_MPROTECT
9909+ if (elf_phdata->p_flags & PF_MPROTECT)
9910+ pax_flags |= MF_PAX_MPROTECT;
9911+#endif
9912+
9913+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
9914+ if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
9915+ pax_flags |= MF_PAX_RANDMMAP;
9916+#endif
9917+
9918+ return pax_flags;
9919+}
9920+#endif
9921+
9922+#ifdef CONFIG_PAX_PT_PAX_FLAGS
9923+static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
9924+{
9925+ unsigned long pax_flags = 0UL;
9926+
9927+#ifdef CONFIG_PAX_PAGEEXEC
9928+ if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
9929+ pax_flags |= MF_PAX_PAGEEXEC;
9930+#endif
9931+
9932+#ifdef CONFIG_PAX_SEGMEXEC
9933+ if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
9934+ pax_flags |= MF_PAX_SEGMEXEC;
9935+#endif
9936+
9937+#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9938+ if (pax_flags & MF_PAX_PAGEEXEC)
9939+ pax_flags &= ~MF_PAX_SEGMEXEC;
9940+#endif
9941+
9942+#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9943+ if (pax_flags & MF_PAX_SEGMEXEC)
9944+ pax_flags &= ~MF_PAX_PAGEEXEC;
9945+#endif
9946+
9947+#ifdef CONFIG_PAX_EMUTRAMP
9948+ if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
9949+ pax_flags |= MF_PAX_EMUTRAMP;
9950+#endif
9951+
9952+#ifdef CONFIG_PAX_MPROTECT
9953+ if (!(elf_phdata->p_flags & PF_NOMPROTECT))
9954+ pax_flags |= MF_PAX_MPROTECT;
9955+#endif
9956+
9957+#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
9958+ if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
9959+ pax_flags |= MF_PAX_RANDMMAP;
9960+#endif
9961+
9962+ return pax_flags;
9963+}
9964+#endif
9965+
9966+#ifdef CONFIG_PAX_EI_PAX
9967+static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
9968+{
9969+ unsigned long pax_flags = 0UL;
9970+
9971+#ifdef CONFIG_PAX_PAGEEXEC
9972+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
9973+ pax_flags |= MF_PAX_PAGEEXEC;
9974+#endif
9975+
9976+#ifdef CONFIG_PAX_SEGMEXEC
9977+ if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
9978+ pax_flags |= MF_PAX_SEGMEXEC;
9979+#endif
9980+
9981+#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
9982+ if (pax_flags & MF_PAX_PAGEEXEC)
9983+ pax_flags &= ~MF_PAX_SEGMEXEC;
9984+#endif
9985+
9986+#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
9987+ if (pax_flags & MF_PAX_SEGMEXEC)
9988+ pax_flags &= ~MF_PAX_PAGEEXEC;
9989+#endif
9990+
9991+#ifdef CONFIG_PAX_EMUTRAMP
9992+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
9993+ pax_flags |= MF_PAX_EMUTRAMP;
9994+#endif
9995+
9996+#ifdef CONFIG_PAX_MPROTECT
9997+ if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
9998+ pax_flags |= MF_PAX_MPROTECT;
9999+#endif
10000+
10001+#ifdef CONFIG_PAX_ASLR
10002+ if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
10003+ pax_flags |= MF_PAX_RANDMMAP;
10004+#endif
10005+
10006+ return pax_flags;
10007+}
10008+#endif
10009+
10010+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
10011+static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
10012+{
10013+ unsigned long pax_flags = 0UL;
10014+
10015+#ifdef CONFIG_PAX_PT_PAX_FLAGS
10016+ unsigned long i;
10017+#endif
10018+
10019+#ifdef CONFIG_PAX_EI_PAX
10020+ pax_flags = pax_parse_ei_pax(elf_ex);
10021+#endif
10022+
10023+#ifdef CONFIG_PAX_PT_PAX_FLAGS
10024+ for (i = 0UL; i < elf_ex->e_phnum; i++)
10025+ if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
10026+ if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
10027+ ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
10028+ ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
10029+ ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
10030+ ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
10031+ return -EINVAL;
10032+
10033+#ifdef CONFIG_PAX_SOFTMODE
10034+ if (pax_softmode)
10035+ pax_flags = pax_parse_softmode(&elf_phdata[i]);
10036+ else
10037+#endif
10038+
10039+ pax_flags = pax_parse_hardmode(&elf_phdata[i]);
10040+ break;
10041+ }
10042+#endif
10043+
10044+ if (0 > pax_check_flags(&pax_flags))
10045+ return -EINVAL;
10046+
10047+ current->mm->pax_flags = pax_flags;
10048+ return 0;
10049+}
10050+#endif
10051+
10052 /*
10053 * These are the functions used to load ELF style executables and shared
10054 * libraries. There is no binary dependent code anywhere else.
10055@@ -534,7 +737,7 @@ static int load_elf_binary(struct linux_
10056 char * elf_interpreter = NULL;
10057 unsigned int interpreter_type = INTERPRETER_NONE;
10058 unsigned char ibcs2_interpreter = 0;
10059- unsigned long error;
10060+ unsigned long error = 0;
10061 struct elf_phdr *elf_ppnt, *elf_phdata;
10062 unsigned long elf_bss, elf_brk;
10063 int elf_exec_fileno;
10064@@ -552,6 +755,7 @@ static int load_elf_binary(struct linux_
10065 struct elfhdr interp_elf_ex;
10066 struct exec interp_ex;
10067 } *loc;
10068+ unsigned long task_size = TASK_SIZE;
10069
10070 loc = kmalloc(sizeof(*loc), GFP_KERNEL);
10071 if (!loc) {
10072@@ -774,14 +978,88 @@ static int load_elf_binary(struct linux_
10073 current->mm->end_code = 0;
10074 current->mm->mmap = NULL;
10075 current->flags &= ~PF_FORKNOEXEC;
10076+
10077+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
10078+ current->mm->pax_flags = 0UL;
10079+#endif
10080+
10081+#ifdef CONFIG_PAX_DLRESOLVE
10082+ current->mm->call_dl_resolve = 0UL;
10083+#endif
10084+
10085+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
10086+ current->mm->call_syscall = 0UL;
10087+#endif
10088+
10089+#ifdef CONFIG_PAX_ASLR
10090+ current->mm->delta_mmap = 0UL;
10091+ current->mm->delta_exec = 0UL;
10092+ current->mm->delta_stack = 0UL;
10093+#endif
10094+
10095 current->mm->def_flags = def_flags;
10096
10097+#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
10098+ if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
10099+ send_sig(SIGKILL, current, 0);
10100+ goto out_free_dentry;
10101+ }
10102+#endif
10103+
10104+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
10105+ pax_set_initial_flags(bprm);
10106+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
10107+ if (pax_set_initial_flags_func)
10108+ (pax_set_initial_flags_func)(bprm);
10109+#endif
10110+
10111+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
10112+ if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
10113+ current->mm->context.user_cs_limit = PAGE_SIZE;
10114+#endif
10115+
10116+#ifdef CONFIG_PAX_SEGMEXEC
10117+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
10118+ int cpu = get_cpu();
10119+
10120+ current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
10121+ current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
10122+ set_user_cs(current->mm, cpu);
10123+ put_cpu();
10124+ task_size = SEGMEXEC_TASK_SIZE;
10125+ }
10126+#endif
10127+
10128+#ifdef CONFIG_PAX_ASLR
10129+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
10130+#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
10131+
10132+ current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
10133+ current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
10134+ current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
10135+ }
10136+#endif
10137+
10138+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10139+ if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10140+ executable_stack = EXSTACK_DEFAULT;
10141+#endif
10142+
10143 /* Do this immediately, since STACK_TOP as used in setup_arg_pages
10144 may depend on the personality. */
10145 SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
10146+
10147+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10148+ if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
10149+#endif
10150+
10151 if (elf_read_implies_exec(loc->elf_ex, executable_stack))
10152 current->personality |= READ_IMPLIES_EXEC;
10153
10154+#ifdef CONFIG_PAX_ASLR
10155+ if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
10156+#endif
10157+
10158 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
10159 current->flags |= PF_RANDOMIZE;
10160 arch_pick_mmap_layout(current->mm);
10161@@ -857,6 +1135,15 @@ static int load_elf_binary(struct linux_
10162 * might try to exec. This is because the brk will
10163 * follow the loader, and is not movable. */
10164 load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
10165+
10166+#ifdef CONFIG_PAX_RANDMMAP
10167+ /* PaX: randomize base address at the default exe base if requested */
10168+ if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
10169+ load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
10170+ elf_flags |= MAP_FIXED;
10171+ }
10172+#endif
10173+
10174 }
10175
10176 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
10177@@ -887,9 +1174,9 @@ static int load_elf_binary(struct linux_
10178 * allowed task size. Note that p_filesz must always be
10179 * <= p_memsz so it is only necessary to check p_memsz.
10180 */
10181- if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
10182- elf_ppnt->p_memsz > TASK_SIZE ||
10183- TASK_SIZE - elf_ppnt->p_memsz < k) {
10184+ if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
10185+ elf_ppnt->p_memsz > task_size ||
10186+ task_size - elf_ppnt->p_memsz < k) {
10187 /* set_brk can never work. Avoid overflows. */
10188 send_sig(SIGKILL, current, 0);
10189 goto out_free_dentry;
10190@@ -916,6 +1203,12 @@ static int load_elf_binary(struct linux_
10191 start_data += load_bias;
10192 end_data += load_bias;
10193
10194+#ifdef CONFIG_PAX_RANDMMAP
10195+ if (current->mm->pax_flags & MF_PAX_RANDMMAP)
10196+ elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
10197+#undef pax_delta_mask
10198+#endif
10199+
10200 /* Calling set_brk effectively mmaps the pages that we need
10201 * for the bss and break sections. We must do this before
10202 * mapping in the interpreter, to make sure it doesn't wind
10203@@ -1178,7 +1471,7 @@ static int dump_seek(struct file *file,
10204 *
10205 * I think we should skip something. But I am not sure how. H.J.
10206 */
10207-static int maydump(struct vm_area_struct *vma)
10208+static int maydump(struct vm_area_struct *vma, long signr)
10209 {
10210 /* Do not dump I/O mapped devices or special mappings */
10211 if (vma->vm_flags & (VM_IO | VM_RESERVED))
10212@@ -1189,7 +1482,7 @@ static int maydump(struct vm_area_struct
10213 return vma->vm_file->f_dentry->d_inode->i_nlink == 0;
10214
10215 /* If it hasn't been written to, don't write it out */
10216- if (!vma->anon_vma)
10217+ if (signr != SIGKILL && !vma->anon_vma)
10218 return 0;
10219
10220 return 1;
10221@@ -1246,8 +1539,11 @@ static int writenote(struct memelfnote *
10222 #undef DUMP_WRITE
10223
10224 #define DUMP_WRITE(addr, nr) \
10225+ do { \
10226+ gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
10227 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
10228- goto end_coredump;
10229+ goto end_coredump; \
10230+ } while (0);
10231 #define DUMP_SEEK(off) \
10232 if (!dump_seek(file, (off))) \
10233 goto end_coredump;
10234@@ -1600,7 +1896,7 @@ static int elf_core_dump(long signr, str
10235 phdr.p_offset = offset;
10236 phdr.p_vaddr = vma->vm_start;
10237 phdr.p_paddr = 0;
10238- phdr.p_filesz = maydump(vma) ? sz : 0;
10239+ phdr.p_filesz = maydump(vma, signr) ? sz : 0;
10240 phdr.p_memsz = sz;
10241 offset += phdr.p_filesz;
10242 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
10243@@ -1638,7 +1934,7 @@ static int elf_core_dump(long signr, str
10244 for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
10245 unsigned long addr;
10246
10247- if (!maydump(vma))
10248+ if (!maydump(vma, signr))
10249 continue;
10250
10251 for (addr = vma->vm_start;
10252@@ -1658,6 +1954,7 @@ static int elf_core_dump(long signr, str
10253 flush_cache_page(vma, addr,
10254 page_to_pfn(page));
10255 kaddr = kmap(page);
10256+ gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
10257 if ((size += PAGE_SIZE) > limit ||
10258 !dump_write(file, kaddr,
10259 PAGE_SIZE)) {
10260diff -urNp linux-2.6.19.1/fs/binfmt_flat.c linux-2.6.19.1/fs/binfmt_flat.c
10261--- linux-2.6.19.1/fs/binfmt_flat.c 2006-11-29 16:57:37.000000000 -0500
10262+++ linux-2.6.19.1/fs/binfmt_flat.c 2006-12-03 15:16:12.000000000 -0500
10263@@ -551,7 +551,9 @@ static int load_flat_file(struct linux_b
10264 realdatastart = (unsigned long) -ENOMEM;
10265 printk("Unable to allocate RAM for process data, errno %d\n",
10266 (int)-datapos);
10267+ down_write(&current->mm->mmap_sem);
10268 do_munmap(current->mm, textpos, text_len);
10269+ up_write(&current->mm->mmap_sem);
10270 ret = realdatastart;
10271 goto err;
10272 }
10273@@ -573,8 +575,10 @@ static int load_flat_file(struct linux_b
10274 }
10275 if (result >= (unsigned long)-4096) {
10276 printk("Unable to read data+bss, errno %d\n", (int)-result);
10277+ down_write(&current->mm->mmap_sem);
10278 do_munmap(current->mm, textpos, text_len);
10279 do_munmap(current->mm, realdatastart, data_len + extra);
10280+ up_write(&current->mm->mmap_sem);
10281 ret = result;
10282 goto err;
10283 }
10284@@ -638,8 +642,10 @@ static int load_flat_file(struct linux_b
10285 }
10286 if (result >= (unsigned long)-4096) {
10287 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
10288+ down_write(&current->mm->mmap_sem);
10289 do_munmap(current->mm, textpos, text_len + data_len + extra +
10290 MAX_SHARED_LIBS * sizeof(unsigned long));
10291+ up_write(&current->mm->mmap_sem);
10292 ret = result;
10293 goto err;
10294 }
10295diff -urNp linux-2.6.19.1/fs/binfmt_misc.c linux-2.6.19.1/fs/binfmt_misc.c
10296--- linux-2.6.19.1/fs/binfmt_misc.c 2006-11-29 16:57:37.000000000 -0500
10297+++ linux-2.6.19.1/fs/binfmt_misc.c 2006-12-03 15:16:12.000000000 -0500
10298@@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
10299 struct files_struct *files = NULL;
10300
10301 retval = -ENOEXEC;
10302- if (!enabled)
10303+ if (!enabled || bprm->misc)
10304 goto _ret;
10305
10306+ bprm->misc++;
10307+
10308 /* to keep locking time low, we copy the interpreter string */
10309 read_lock(&entries_lock);
10310 fmt = check_file(bprm);
10311diff -urNp linux-2.6.19.1/fs/buffer.c linux-2.6.19.1/fs/buffer.c
10312--- linux-2.6.19.1/fs/buffer.c 2006-11-29 16:57:37.000000000 -0500
10313+++ linux-2.6.19.1/fs/buffer.c 2006-12-03 15:16:12.000000000 -0500
10314@@ -41,6 +41,7 @@
10315 #include <linux/bitops.h>
10316 #include <linux/mpage.h>
10317 #include <linux/bit_spinlock.h>
10318+#include <linux/grsecurity.h>
10319
10320 static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
10321 static void invalidate_bh_lrus(void);
10322@@ -2018,6 +2019,7 @@ static int __generic_cont_expand(struct
10323
10324 err = -EFBIG;
10325 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
10326+ gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
10327 if (limit != RLIM_INFINITY && size > (loff_t)limit) {
10328 send_sig(SIGXFSZ, current, 0);
10329 goto out;
10330diff -urNp linux-2.6.19.1/fs/cifs/cifssmb.c linux-2.6.19.1/fs/cifs/cifssmb.c
10331--- linux-2.6.19.1/fs/cifs/cifssmb.c 2006-11-29 16:57:37.000000000 -0500
10332+++ linux-2.6.19.1/fs/cifs/cifssmb.c 2006-12-03 15:16:14.000000000 -0500
10333@@ -2812,10 +2812,10 @@ GetExtAttrOut:
10334
10335
10336 /* security id for everyone */
10337-const static struct cifs_sid sid_everyone =
10338+static const struct cifs_sid sid_everyone =
10339 {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
10340 /* group users */
10341-const static struct cifs_sid sid_user =
10342+static const struct cifs_sid sid_user =
10343 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
10344
10345 /* Convert CIFS ACL to POSIX form */
10346diff -urNp linux-2.6.19.1/fs/cifs/smbdes.c linux-2.6.19.1/fs/cifs/smbdes.c
10347--- linux-2.6.19.1/fs/cifs/smbdes.c 2006-11-29 16:57:37.000000000 -0500
10348+++ linux-2.6.19.1/fs/cifs/smbdes.c 2006-12-03 15:16:14.000000000 -0500
10349@@ -196,15 +196,18 @@ dohash(char *out, char *in, char *key, i
10350 char c[28];
10351 char d[28];
10352 char *cd;
10353- char ki[16][48];
10354+ char *ki;
10355 char *pd1;
10356 char l[32], r[32];
10357 char *rl;
10358+ char *er; /* er[48] */
10359
10360 /* Have to reduce stack usage */
10361- pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
10362- if(pk1 == NULL)
10363- return;
10364+ pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
10365+ ki = kmalloc(16*48, GFP_KERNEL);
10366+ er = kmalloc(48+48+32+32+32, GFP_KERNEL);
10367+ if (!pk1 || !ki || !er)
10368+ goto free;
10369
10370 cd = pk1 + 56;
10371 pd1= cd + 56;
10372@@ -222,7 +225,7 @@ dohash(char *out, char *in, char *key, i
10373 lshift(d, sc[i], 28);
10374
10375 concat(cd, c, d, 28, 28);
10376- permute(ki[i], cd, perm2, 48);
10377+ permute(ki+48*i, cd, perm2, 48);
10378 }
10379
10380 permute(pd1, in, perm3, 64);
10381@@ -233,18 +236,12 @@ dohash(char *out, char *in, char *key, i
10382 }
10383
10384 for (i = 0; i < 16; i++) {
10385- char *er; /* er[48] */
10386 char *erk; /* erk[48] */
10387 char b[8][6];
10388 char *cb; /* cb[32] */
10389 char *pcb; /* pcb[32] */
10390 char *r2; /* r2[32] */
10391
10392- er = kmalloc(48+48+32+32+32, GFP_KERNEL);
10393- if(er == NULL) {
10394- kfree(pk1);
10395- return;
10396- }
10397 erk = er+48;
10398 cb = erk+48;
10399 pcb = cb+32;
10400@@ -252,7 +249,7 @@ dohash(char *out, char *in, char *key, i
10401
10402 permute(er, r, perm4, 48);
10403
10404- xor(erk, er, ki[forw ? i : 15 - i], 48);
10405+ xor(erk, er, ki+48*(forw ? i : 15 - i), 48);
10406
10407 for (j = 0; j < 8; j++)
10408 for (k = 0; k < 6; k++)
10409@@ -282,13 +279,15 @@ dohash(char *out, char *in, char *key, i
10410
10411 for (j = 0; j < 32; j++)
10412 r[j] = r2[j];
10413-
10414- kfree(er);
10415 }
10416
10417 concat(rl, r, l, 32, 32);
10418
10419 permute(out, rl, perm6, 64);
10420+
10421+free:
10422+ kfree(er);
10423+ kfree(ki);
10424 kfree(pk1);
10425 }
10426
10427diff -urNp linux-2.6.19.1/fs/compat.c linux-2.6.19.1/fs/compat.c
10428--- linux-2.6.19.1/fs/compat.c 2006-12-10 21:40:26.000000000 -0500
10429+++ linux-2.6.19.1/fs/compat.c 2006-12-10 21:40:16.000000000 -0500
10430@@ -46,6 +46,7 @@
10431 #include <linux/rwsem.h>
10432 #include <linux/tsacct_kern.h>
10433 #include <linux/mm.h>
10434+#include <linux/grsecurity.h>
10435
10436 #include <net/sock.h> /* siocdevprivate_ioctl */
10437
10438@@ -1492,6 +1493,11 @@ int compat_do_execve(char * filename,
10439 struct file *file;
10440 int retval;
10441 int i;
10442+#ifdef CONFIG_GRKERNSEC
10443+ struct file *old_exec_file;
10444+ struct acl_subject_label *old_acl;
10445+ struct rlimit old_rlim[RLIM_NLIMITS];
10446+#endif
10447
10448 retval = -ENOMEM;
10449 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
10450@@ -1509,6 +1515,15 @@ int compat_do_execve(char * filename,
10451 bprm->file = file;
10452 bprm->filename = filename;
10453 bprm->interp = filename;
10454+
10455+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
10456+ retval = -EAGAIN;
10457+ if (gr_handle_nproc())
10458+ goto out_file;
10459+ retval = -EACCES;
10460+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
10461+ goto out_file;
10462+
10463 bprm->mm = mm_alloc();
10464 retval = -ENOMEM;
10465 if (!bprm->mm)
10466@@ -1547,10 +1562,39 @@ int compat_do_execve(char * filename,
10467 if (retval < 0)
10468 goto out;
10469
10470+ if (!gr_tpe_allow(file)) {
10471+ retval = -EACCES;
10472+ goto out;
10473+ }
10474+
10475+ if (gr_check_crash_exec(file)) {
10476+ retval = -EACCES;
10477+ goto out;
10478+ }
10479+
10480+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
10481+
10482+ gr_handle_exec_args(bprm, (char __user * __user *)argv);
10483+
10484+#ifdef CONFIG_GRKERNSEC
10485+ old_acl = current->acl;
10486+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
10487+ old_exec_file = current->exec_file;
10488+ get_file(file);
10489+ current->exec_file = file;
10490+#endif
10491+
10492+ gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
10493+
10494 retval = search_binary_handler(bprm, regs);
10495 if (retval >= 0) {
10496 free_arg_pages(bprm);
10497
10498+#ifdef CONFIG_GRKERNSEC
10499+ if (old_exec_file)
10500+ fput(old_exec_file);
10501+#endif
10502+
10503 /* execve success */
10504 security_bprm_free(bprm);
10505 acct_update_integrals(current);
10506@@ -1558,6 +1602,13 @@ int compat_do_execve(char * filename,
10507 return retval;
10508 }
10509
10510+#ifdef CONFIG_GRKERNSEC
10511+ current->acl = old_acl;
10512+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
10513+ fput(current->exec_file);
10514+ current->exec_file = old_exec_file;
10515+#endif
10516+
10517 out:
10518 /* Something went wrong, return the inode and free the argument pages*/
10519 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10520diff -urNp linux-2.6.19.1/fs/dcache.c linux-2.6.19.1/fs/dcache.c
10521--- linux-2.6.19.1/fs/dcache.c 2006-11-29 16:57:37.000000000 -0500
10522+++ linux-2.6.19.1/fs/dcache.c 2006-12-03 15:16:14.000000000 -0500
10523@@ -1739,7 +1739,7 @@ shouldnt_be_hashed:
10524 *
10525 * "buflen" should be positive. Caller holds the dcache_lock.
10526 */
10527-static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
10528+char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
10529 struct dentry *root, struct vfsmount *rootmnt,
10530 char *buffer, int buflen)
10531 {
10532diff -urNp linux-2.6.19.1/fs/exec.c linux-2.6.19.1/fs/exec.c
10533--- linux-2.6.19.1/fs/exec.c 2006-12-10 21:40:26.000000000 -0500
10534+++ linux-2.6.19.1/fs/exec.c 2006-12-10 21:40:16.000000000 -0500
10535@@ -49,6 +49,8 @@
c3e8c1b5 10536 #include <linux/cn_proc.h>
10537 #include <linux/audit.h>
b6fa5d20 10538 #include <linux/vs_memory.h>
c3e8c1b5 10539+#include <linux/random.h>
10540+#include <linux/grsecurity.h>
10541
10542 #include <asm/uaccess.h>
10543 #include <asm/mmu_context.h>
10544@@ -67,6 +69,15 @@ EXPORT_SYMBOL(suid_dumpable);
10545 static struct linux_binfmt *formats;
10546 static DEFINE_RWLOCK(binfmt_lock);
10547
10548+#ifdef CONFIG_PAX_SOFTMODE
10549+unsigned int pax_softmode;
10550+#endif
10551+
10552+#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
10553+void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
10554+EXPORT_SYMBOL(pax_set_initial_flags_func);
10555+#endif
10556+
10557 int register_binfmt(struct linux_binfmt * fmt)
10558 {
10559 struct linux_binfmt ** tmp = &formats;
10560@@ -312,6 +323,10 @@ void install_arg_page(struct vm_area_str
10561 if (unlikely(anon_vma_prepare(vma)))
10562 goto out;
10563
10564+#ifdef CONFIG_PAX_SEGMEXEC
10565+ if (page_count(page) == 1)
10566+#endif
10567+
10568 flush_dcache_page(page);
10569 pte = get_locked_pte(mm, address, &ptl);
10570 if (!pte)
10571@@ -321,9 +336,21 @@ void install_arg_page(struct vm_area_str
10572 goto out;
10573 }
10574 inc_mm_counter(mm, anon_rss);
10575+
10576+#ifdef CONFIG_PAX_SEGMEXEC
10577+ if (page_count(page) == 1)
10578+#endif
10579+
10580 lru_cache_add_active(page);
10581 set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
10582 page, vma->vm_page_prot))));
10583+
10584+#ifdef CONFIG_PAX_SEGMEXEC
10585+ if (page_count(page) != 1)
10586+ page_add_anon_rmap(page, vma, address);
10587+ else
10588+#endif
10589+
10590 page_add_new_anon_rmap(page, vma, address);
10591 pte_unmap_unlock(pte, ptl);
10592
10593@@ -346,6 +373,10 @@ int setup_arg_pages(struct linux_binprm
10594 int i, ret;
10595 long arg_size;
10596
10597+#ifdef CONFIG_PAX_SEGMEXEC
10598+ struct vm_area_struct *mpnt_m = NULL;
10599+#endif
10600+
10601 #ifdef CONFIG_STACK_GROWSUP
10602 /* Move the argument and environment strings to the bottom of the
10603 * stack space.
10604@@ -404,11 +435,19 @@ int setup_arg_pages(struct linux_binprm
10605 bprm->loader += stack_base;
10606 bprm->exec += stack_base;
10607
10608- mpnt = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
10609+ mpnt = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
10610 if (!mpnt)
10611 return -ENOMEM;
10612
10613- memset(mpnt, 0, sizeof(*mpnt));
10614+#ifdef CONFIG_PAX_SEGMEXEC
10615+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
10616+ mpnt_m = kmem_cache_zalloc(vm_area_cachep, SLAB_KERNEL);
10617+ if (!mpnt_m) {
10618+ kmem_cache_free(vm_area_cachep, mpnt);
10619+ return -ENOMEM;
10620+ }
10621+ }
10622+#endif
10623
10624 down_write(&mm->mmap_sem);
10625 {
5c9295bc 10626@@ -430,10 +453,23 @@ int setup_arg_pages(struct linux_binprm
c3e8c1b5 10627 else
10628 mpnt->vm_flags = VM_STACK_FLAGS;
10629 mpnt->vm_flags |= mm->def_flags;
10630- mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
10631+
10632+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
10633+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
10634+ mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
10635+ else
10636+#endif
10637+
10638+ mpnt->vm_page_prot = protection_map[mpnt->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
10639 if ((ret = insert_vm_struct(mm, mpnt))) {
10640 up_write(&mm->mmap_sem);
10641 kmem_cache_free(vm_area_cachep, mpnt);
10642+
10643+#ifdef CONFIG_PAX_SEGMEXEC
10644+ if (mpnt_m)
10645+ kmem_cache_free(vm_area_cachep, mpnt_m);
10646+#endif
10647+
10648 return ret;
10649 }
b6fa5d20 10650 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
5c9295bc 10651@@ -452,6 +482,30 @@ int setup_arg_pages(struct linux_binprm
10652 }
10653 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
b6fa5d20 10654 mm->stack_vm = mm->total_vm;
c3e8c1b5 10655+
10656+#ifdef CONFIG_PAX_SEGMEXEC
10657+ if (mpnt_m) {
10658+ *mpnt_m = *mpnt;
10659+ if (!(mpnt->vm_flags & VM_EXEC)) {
10660+ mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
10661+ mpnt_m->vm_page_prot = PAGE_NONE;
10662+ }
10663+ mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
10664+ mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
10665+ if ((ret = insert_vm_struct(mm, mpnt_m))) {
10666+ up_write(&mm->mmap_sem);
10667+ kmem_cache_free(vm_area_cachep, mpnt_m);
10668+ return ret;
10669+ }
10670+ mpnt_m->vm_flags |= VM_MIRROR;
10671+ mpnt->vm_flags |= VM_MIRROR;
10672+ mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
10673+ mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
10674+ mpnt_m->vm_pgoff = mpnt->vm_pgoff;
10675+ mm->total_vm += vma_pages(mpnt_m);
10676+ }
10677+#endif
10678+
10679 }
10680
10681 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10682@@ -444,6 +520,14 @@ int setup_arg_pages(struct linux_binprm
10683 if (page) {
10684 bprm->page[i] = NULL;
10685 install_arg_page(mpnt, page, stack_base);
10686+
10687+#ifdef CONFIG_PAX_SEGMEXEC
10688+ if (mpnt_m) {
10689+ page_cache_get(page);
10690+ install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
10691+ }
10692+#endif
10693+
10694 }
10695 stack_base += PAGE_SIZE;
10696 }
10697@@ -1128,6 +1212,11 @@ int do_execve(char * filename,
10698 struct file *file;
10699 int retval;
10700 int i;
10701+#ifdef CONFIG_GRKERNSEC
10702+ struct file *old_exec_file;
10703+ struct acl_subject_label *old_acl;
10704+ struct rlimit old_rlim[RLIM_NLIMITS];
10705+#endif
10706
10707 retval = -ENOMEM;
10708 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
10709@@ -1139,10 +1228,29 @@ int do_execve(char * filename,
10710 if (IS_ERR(file))
10711 goto out_kfree;
10712
10713+ gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
10714+
10715+ if (gr_handle_nproc()) {
10716+ allow_write_access(file);
10717+ fput(file);
10718+ return -EAGAIN;
10719+ }
10720+
10721+ if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
10722+ allow_write_access(file);
10723+ fput(file);
10724+ return -EACCES;
10725+ }
10726+
10727 sched_exec();
10728
10729 bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
10730
10731+#ifdef CONFIG_PAX_RANDUSTACK
10732+ if (randomize_va_space)
10733+ bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
10734+#endif
10735+
10736 bprm->file = file;
10737 bprm->filename = filename;
10738 bprm->interp = filename;
10739@@ -1184,8 +1292,38 @@ int do_execve(char * filename,
10740 if (retval < 0)
10741 goto out;
10742
10743+ if (!gr_tpe_allow(file)) {
10744+ retval = -EACCES;
10745+ goto out;
10746+ }
10747+
10748+ if (gr_check_crash_exec(file)) {
10749+ retval = -EACCES;
10750+ goto out;
10751+ }
10752+
10753+ gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
10754+
10755+ gr_handle_exec_args(bprm, argv);
10756+
10757+#ifdef CONFIG_GRKERNSEC
10758+ old_acl = current->acl;
10759+ memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
10760+ old_exec_file = current->exec_file;
10761+ get_file(file);
10762+ current->exec_file = file;
10763+#endif
10764+
10765+ retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
10766+ if (retval < 0)
10767+ goto out_fail;
10768+
10769 retval = search_binary_handler(bprm,regs);
10770 if (retval >= 0) {
10771+#ifdef CONFIG_GRKERNSEC
10772+ if (old_exec_file)
10773+ fput(old_exec_file);
10774+#endif
10775 free_arg_pages(bprm);
10776
10777 /* execve success */
10778@@ -1195,6 +1333,14 @@ int do_execve(char * filename,
10779 return retval;
10780 }
10781
10782+out_fail:
10783+#ifdef CONFIG_GRKERNSEC
10784+ current->acl = old_acl;
10785+ memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
10786+ fput(current->exec_file);
10787+ current->exec_file = old_exec_file;
10788+#endif
10789+
10790 out:
10791 /* Something went wrong, return the inode and free the argument pages*/
10792 for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
10793@@ -1355,6 +1501,114 @@ static void format_corename(char *corena
10794 *out_ptr = 0;
10795 }
10796
10797+int pax_check_flags(unsigned long * flags)
10798+{
10799+ int retval = 0;
10800+
10801+#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
10802+ if (*flags & MF_PAX_SEGMEXEC)
10803+ {
10804+ *flags &= ~MF_PAX_SEGMEXEC;
10805+ retval = -EINVAL;
10806+ }
10807+#endif
10808+
10809+ if ((*flags & MF_PAX_PAGEEXEC)
10810+
10811+#ifdef CONFIG_PAX_PAGEEXEC
10812+ && (*flags & MF_PAX_SEGMEXEC)
10813+#endif
10814+
10815+ )
10816+ {
10817+ *flags &= ~MF_PAX_PAGEEXEC;
10818+ retval = -EINVAL;
10819+ }
10820+
10821+ if ((*flags & MF_PAX_MPROTECT)
10822+
10823+#ifdef CONFIG_PAX_MPROTECT
10824+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10825+#endif
10826+
10827+ )
10828+ {
10829+ *flags &= ~MF_PAX_MPROTECT;
10830+ retval = -EINVAL;
10831+ }
10832+
10833+ if ((*flags & MF_PAX_EMUTRAMP)
10834+
10835+#ifdef CONFIG_PAX_EMUTRAMP
10836+ && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
10837+#endif
10838+
10839+ )
10840+ {
10841+ *flags &= ~MF_PAX_EMUTRAMP;
10842+ retval = -EINVAL;
10843+ }
10844+
10845+ return retval;
10846+}
10847+
10848+EXPORT_SYMBOL(pax_check_flags);
10849+
10850+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10851+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
10852+{
10853+ struct task_struct *tsk = current;
10854+ struct mm_struct *mm = current->mm;
10855+ char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
10856+ char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
10857+ char* path_exec=NULL;
10858+ char* path_fault=NULL;
10859+ unsigned long start=0UL, end=0UL, offset=0UL;
10860+
10861+ if (buffer_exec && buffer_fault) {
10862+ struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
10863+
10864+ down_read(&mm->mmap_sem);
10865+ vma = mm->mmap;
10866+ while (vma && (!vma_exec || !vma_fault)) {
10867+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
10868+ vma_exec = vma;
10869+ if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
10870+ vma_fault = vma;
10871+ vma = vma->vm_next;
10872+ }
10873+ if (vma_exec) {
10874+ path_exec = d_path(vma_exec->vm_file->f_dentry, vma_exec->vm_file->f_vfsmnt, buffer_exec, PAGE_SIZE);
10875+ if (IS_ERR(path_exec))
10876+ path_exec = "<path too long>";
10877+ }
10878+ if (vma_fault) {
10879+ start = vma_fault->vm_start;
10880+ end = vma_fault->vm_end;
10881+ offset = vma_fault->vm_pgoff << PAGE_SHIFT;
10882+ if (vma_fault->vm_file) {
10883+ path_fault = d_path(vma_fault->vm_file->f_dentry, vma_fault->vm_file->f_vfsmnt, buffer_fault, PAGE_SIZE);
10884+ if (IS_ERR(path_fault))
10885+ path_fault = "<path too long>";
10886+ } else
10887+ path_fault = "<anonymous mapping>";
10888+ }
10889+ up_read(&mm->mmap_sem);
10890+ }
10891+ if (tsk->signal->curr_ip)
10892+ 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);
10893+ else
10894+ printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
10895+ printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
10896+ "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
10897+ tsk->uid, tsk->euid, pc, sp);
10898+ free_page((unsigned long)buffer_exec);
10899+ free_page((unsigned long)buffer_fault);
10900+ pax_report_insns(pc, sp);
10901+ do_coredump(SIGKILL, SIGKILL, regs);
10902+}
10903+#endif
10904+
10905 static void zap_process(struct task_struct *start)
10906 {
10907 struct task_struct *t;
10908@@ -1495,6 +1749,10 @@ int do_coredump(long signr, int exit_cod
10909 */
10910 clear_thread_flag(TIF_SIGPENDING);
10911
10912+ if (signr == SIGKILL || signr == SIGILL)
10913+ gr_handle_brute_attach(current);
10914+
10915+ gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
10916 if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
10917 goto fail_unlock;
10918
10919diff -urNp linux-2.6.19.1/fs/ext3/xattr.c linux-2.6.19.1/fs/ext3/xattr.c
10920--- linux-2.6.19.1/fs/ext3/xattr.c 2006-11-29 16:57:37.000000000 -0500
10921+++ linux-2.6.19.1/fs/ext3/xattr.c 2006-12-03 15:16:14.000000000 -0500
10922@@ -89,8 +89,8 @@
10923 printk("\n"); \
10924 } while (0)
10925 #else
10926-# define ea_idebug(f...)
10927-# define ea_bdebug(f...)
10928+# define ea_idebug(f...) do {} while (0)
10929+# define ea_bdebug(f...) do {} while (0)
10930 #endif
10931
10932 static void ext3_xattr_cache_insert(struct buffer_head *);
10933diff -urNp linux-2.6.19.1/fs/ext4/extents.c linux-2.6.19.1/fs/ext4/extents.c
10934--- linux-2.6.19.1/fs/ext4/extents.c 2006-11-29 16:57:37.000000000 -0500
10935+++ linux-2.6.19.1/fs/ext4/extents.c 2006-12-03 15:16:14.000000000 -0500
10936@@ -1093,7 +1093,7 @@ int ext4_ext_correct_indexes(handle_t *h
10937 return err;
10938 }
10939
10940-static int inline
10941+inline static int
10942 ext4_can_extents_be_merged(struct inode *inode, struct ext4_extent *ex1,
10943 struct ext4_extent *ex2)
10944 {
10945@@ -1509,7 +1509,7 @@ int ext4_ext_rm_idx(handle_t *handle, st
10946 * the caller should calculate credits under truncate_mutex and
10947 * pass the actual path.
10948 */
10949-int inline ext4_ext_calc_credits_for_insert(struct inode *inode,
10950+inline int ext4_ext_calc_credits_for_insert(struct inode *inode,
10951 struct ext4_ext_path *path)
10952 {
10953 int depth, needed;
10954@@ -1718,7 +1718,7 @@ out:
10955 * ext4_ext_more_to_rm:
10956 * returns 1 if current index has to be freed (even partial)
10957 */
10958-static int inline
10959+inline static int
10960 ext4_ext_more_to_rm(struct ext4_ext_path *path)
10961 {
10962 BUG_ON(path->p_idx == NULL);
10963diff -urNp linux-2.6.19.1/fs/fcntl.c linux-2.6.19.1/fs/fcntl.c
10964--- linux-2.6.19.1/fs/fcntl.c 2006-11-29 16:57:37.000000000 -0500
10965+++ linux-2.6.19.1/fs/fcntl.c 2006-12-03 15:16:14.000000000 -0500
10966@@ -18,6 +18,7 @@
c3e8c1b5 10967 #include <linux/signal.h>
10968 #include <linux/rcupdate.h>
b6fa5d20 10969 #include <linux/vs_limit.h>
c3e8c1b5 10970+#include <linux/grsecurity.h>
10971
10972 #include <asm/poll.h>
10973 #include <asm/siginfo.h>
10974@@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
10975 struct fdtable *fdt;
10976
10977 error = -EINVAL;
10978+ gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
10979 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10980 goto out;
10981
10982@@ -83,6 +85,7 @@ repeat:
10983 }
10984
10985 error = -EMFILE;
10986+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
10987 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
10988 goto out;
10989
10990@@ -141,6 +144,8 @@ asmlinkage long sys_dup2(unsigned int ol
10991 struct files_struct * files = current->files;
10992 struct fdtable *fdt;
10993
10994+ gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
10995+
10996 spin_lock(&files->file_lock);
10997 if (!(file = fcheck(oldfd)))
10998 goto out_unlock;
10999@@ -459,7 +464,8 @@ static inline int sigio_perm(struct task
11000 return (((fown->euid == 0) ||
11001 (fown->euid == p->suid) || (fown->euid == p->uid) ||
11002 (fown->uid == p->suid) || (fown->uid == p->uid)) &&
11003- !security_file_send_sigiotask(p, fown, sig));
11004+ !security_file_send_sigiotask(p, fown, sig) &&
11005+ !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
11006 }
11007
11008 static void send_sigio_to_task(struct task_struct *p,
11009diff -urNp linux-2.6.19.1/fs/Kconfig linux-2.6.19.1/fs/Kconfig
11010--- linux-2.6.19.1/fs/Kconfig 2006-11-29 16:57:37.000000000 -0500
11011+++ linux-2.6.19.1/fs/Kconfig 2006-12-03 15:16:12.000000000 -0500
11012@@ -929,7 +929,7 @@ config PROC_FS
11013
11014 config PROC_KCORE
11015 bool "/proc/kcore support" if !ARM
11016- depends on PROC_FS && MMU
11017+ depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
11018
11019 config PROC_VMCORE
11020 bool "/proc/vmcore support (EXPERIMENTAL)"
11021diff -urNp linux-2.6.19.1/fs/namei.c linux-2.6.19.1/fs/namei.c
11022--- linux-2.6.19.1/fs/namei.c 2006-11-29 16:57:37.000000000 -0500
11023+++ linux-2.6.19.1/fs/namei.c 2006-12-03 15:16:15.000000000 -0500
11024@@ -32,6 +32,7 @@
b6fa5d20 11025 #include <linux/vs_base.h>
11026 #include <linux/vs_tag.h>
11027 #include <linux/vs_cowbl.h>
c3e8c1b5 11028+#include <linux/grsecurity.h>
11029 #include <asm/namei.h>
11030 #include <asm/uaccess.h>
11031
11032@@ -640,6 +641,13 @@ static inline int do_follow_link(struct
11033 err = security_inode_follow_link(path->dentry, nd);
11034 if (err)
11035 goto loop;
11036+
11037+ if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
11038+ path->dentry->d_inode, path->dentry, nd->mnt)) {
11039+ err = -EACCES;
11040+ goto loop;
11041+ }
11042+
11043 current->link_count++;
11044 current->total_link_count++;
11045 nd->depth++;
11046@@ -985,11 +993,18 @@ return_reval:
11047 break;
11048 }
11049 return_base:
11050+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
11051+ path_release(nd);
11052+ return -ENOENT;
11053+ }
11054 return 0;
11055 out_dput:
11056 dput_path(&next, nd);
11057 break;
11058 }
11059+ if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
11060+ err = -ENOENT;
11061+
11062 path_release(nd);
11063 return_err:
11064 return err;
11065@@ -1601,9 +1616,17 @@ static int open_namei_create(struct name
11066 int error;
11067 struct dentry *dir = nd->dentry;
11068
11069+ if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
11070+ error = -EACCES;
11071+ goto out_unlock_dput;
11072+ }
11073+
11074 if (!IS_POSIXACL(dir->d_inode))
11075 mode &= ~current->fs->umask;
11076 error = vfs_create(dir->d_inode, path->dentry, mode, nd);
11077+ if (!error)
11078+ gr_handle_create(path->dentry, nd->mnt);
11079+out_unlock_dput:
11080 mutex_unlock(&dir->d_inode->i_mutex);
11081 dput(nd->dentry);
11082 nd->dentry = path->dentry;
11083@@ -1654,6 +1677,17 @@ int open_namei(int dfd, const char *path
11084 nd, flag);
11085 if (error)
11086 return error;
11087+
11088+ if (gr_handle_rawio(nd->dentry->d_inode)) {
11089+ error = -EPERM;
11090+ goto exit;
11091+ }
11092+
11093+ if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
11094+ error = -EACCES;
11095+ goto exit;
11096+ }
11097+
11098 goto ok;
11099 }
11100
11101@@ -1703,6 +1737,23 @@ do_last:
11102 /*
11103 * It already exists.
11104 */
11105+
11106+ if (gr_handle_rawio(path.dentry->d_inode)) {
11107+ mutex_unlock(&dir->d_inode->i_mutex);
11108+ error = -EPERM;
11109+ goto exit_dput;
11110+ }
11111+ if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
11112+ mutex_unlock(&dir->d_inode->i_mutex);
11113+ error = -EACCES;
11114+ goto exit_dput;
11115+ }
11116+ if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
11117+ mutex_unlock(&dir->d_inode->i_mutex);
11118+ error = -EACCES;
11119+ goto exit_dput;
11120+ }
11121+
11122 mutex_unlock(&dir->d_inode->i_mutex);
11123 audit_inode_update(path.dentry->d_inode);
11124
11125@@ -1758,6 +1809,13 @@ do_link:
11126 error = security_inode_follow_link(path.dentry, nd);
11127 if (error)
11128 goto exit_dput;
11129+
11130+ if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
11131+ path.dentry, nd->mnt)) {
11132+ error = -EACCES;
11133+ goto exit_dput;
11134+ }
11135+
11136 error = __do_follow_link(&path, nd);
11137 if (error) {
11138 /* Does someone understand code flow here? Or it is only
11139@@ -1886,6 +1944,22 @@ asmlinkage long sys_mknodat(int dfd, con
11140 if (!IS_POSIXACL(nd.dentry->d_inode))
11141 mode &= ~current->fs->umask;
11142 if (!IS_ERR(dentry)) {
11143+ if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
11144+ error = -EPERM;
11145+ dput(dentry);
11146+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
11147+ path_release(&nd);
11148+ goto out;
11149+ }
11150+
11151+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
11152+ error = -EACCES;
11153+ dput(dentry);
11154+ mutex_unlock(&nd.dentry->d_inode->i_mutex);
11155+ path_release(&nd);
11156+ goto out;
11157+ }
11158+
11159 switch (mode & S_IFMT) {
11160 case 0: case S_IFREG:
11161 error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
11162@@ -1903,6 +1977,10 @@ asmlinkage long sys_mknodat(int dfd, con
11163 default:
11164 error = -EINVAL;
11165 }
11166+
11167+ if (!error)
11168+ gr_handle_create(dentry, nd.mnt);
11169+
11170 dput(dentry);
11171 }
11172 mutex_unlock(&nd.dentry->d_inode->i_mutex);
11173@@ -1960,9 +2038,18 @@ asmlinkage long sys_mkdirat(int dfd, con
11174 if (IS_ERR(dentry))
11175 goto out_unlock;
11176
11177+ if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
11178+ error = -EACCES;
11179+ goto out_unlock_dput;
11180+ }
11181+
11182 if (!IS_POSIXACL(nd.dentry->d_inode))
11183 mode &= ~current->fs->umask;
b6fa5d20 11184 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
c3e8c1b5 11185+
11186+ if (!error)
11187+ gr_handle_create(dentry, nd.mnt);
11188+out_unlock_dput:
11189 dput(dentry);
11190 out_unlock:
11191 mutex_unlock(&nd.dentry->d_inode->i_mutex);
11192@@ -2045,6 +2132,8 @@ static long do_rmdir(int dfd, const char
11193 char * name;
11194 struct dentry *dentry;
11195 struct nameidata nd;
11196+ ino_t saved_ino = 0;
11197+ dev_t saved_dev = 0;
11198
11199 name = getname(pathname);
11200 if(IS_ERR(name))
11201@@ -2070,7 +2159,22 @@ static long do_rmdir(int dfd, const char
11202 error = PTR_ERR(dentry);
11203 if (IS_ERR(dentry))
11204 goto exit2;
11205+
11206+ if (dentry->d_inode != NULL) {
11207+ if (dentry->d_inode->i_nlink <= 1) {
11208+ saved_ino = dentry->d_inode->i_ino;
11209+ saved_dev = dentry->d_inode->i_sb->s_dev;
11210+ }
11211+
11212+ if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
11213+ error = -EACCES;
11214+ goto dput_exit2;
11215+ }
11216+ }
b6fa5d20 11217 error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
c3e8c1b5 11218+ if (!error && (saved_dev || saved_ino))
11219+ gr_handle_delete(saved_ino, saved_dev);
11220+dput_exit2:
11221 dput(dentry);
11222 exit2:
11223 mutex_unlock(&nd.dentry->d_inode->i_mutex);
11224@@ -2129,6 +2233,8 @@ static long do_unlinkat(int dfd, const c
11225 struct dentry *dentry;
11226 struct nameidata nd;
11227 struct inode *inode = NULL;
11228+ ino_t saved_ino = 0;
11229+ dev_t saved_dev = 0;
11230
11231 name = getname(pathname);
11232 if(IS_ERR(name))
11233@@ -2144,13 +2250,26 @@ static long do_unlinkat(int dfd, const c
11234 dentry = lookup_hash(&nd);
11235 error = PTR_ERR(dentry);
11236 if (!IS_ERR(dentry)) {
11237+ error = 0;
11238 /* Why not before? Because we want correct error value */
11239 if (nd.last.name[nd.last.len])
11240 goto slashes;
11241 inode = dentry->d_inode;
11242- if (inode)
11243+ if (inode) {
11244+ if (inode->i_nlink <= 1) {
11245+ saved_ino = inode->i_ino;
11246+ saved_dev = inode->i_sb->s_dev;
11247+ }
11248+
11249+ if (!gr_acl_handle_unlink(dentry, nd.mnt))
11250+ error = -EACCES;
11251+
11252 atomic_inc(&inode->i_count);
b6fa5d20 11253- error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
c3e8c1b5 11254+ }
11255+ if (!error)
b6fa5d20 11256+ error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
c3e8c1b5 11257+ if (!error && (saved_ino || saved_dev))
11258+ gr_handle_delete(saved_ino, saved_dev);
11259 exit2:
11260 dput(dentry);
11261 }
11262@@ -2231,7 +2350,16 @@ asmlinkage long sys_symlinkat(const char
11263 if (IS_ERR(dentry))
11264 goto out_unlock;
11265
11266+ if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
11267+ error = -EACCES;
11268+ goto out_dput_unlock;
11269+ }
11270+
b6fa5d20 11271 error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
c3e8c1b5 11272+
11273+ if (!error)
11274+ gr_handle_create(dentry, nd.mnt);
11275+out_dput_unlock:
11276 dput(dentry);
11277 out_unlock:
11278 mutex_unlock(&nd.dentry->d_inode->i_mutex);
11279@@ -2326,7 +2454,25 @@ asmlinkage long sys_linkat(int olddfd, c
11280 error = PTR_ERR(new_dentry);
11281 if (IS_ERR(new_dentry))
11282 goto out_unlock;
11283+
11284+ if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
11285+ old_nd.dentry->d_inode,
11286+ old_nd.dentry->d_inode->i_mode, to)) {
11287+ error = -EACCES;
11288+ goto out_unlock_dput;
11289+ }
11290+
11291+ if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
11292+ old_nd.dentry, old_nd.mnt, to)) {
11293+ error = -EACCES;
11294+ goto out_unlock_dput;
11295+ }
11296+
b6fa5d20 11297 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
c3e8c1b5 11298+
11299+ if (!error)
11300+ gr_handle_create(new_dentry, nd.mnt);
11301+out_unlock_dput:
11302 dput(new_dentry);
11303 out_unlock:
11304 mutex_unlock(&nd.dentry->d_inode->i_mutex);
11305@@ -2552,8 +2698,16 @@ static int do_rename(int olddfd, const c
11306 if (new_dentry == trap)
11307 goto exit5;
11308
11309- error = vfs_rename(old_dir->d_inode, old_dentry,
11310+ error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
11311+ old_dentry, old_dir->d_inode, oldnd.mnt,
11312+ newname);
11313+
11314+ if (!error)
11315+ error = vfs_rename(old_dir->d_inode, old_dentry,
11316 new_dir->d_inode, new_dentry);
11317+ if (!error)
11318+ gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry,
11319+ new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
11320 exit5:
11321 dput(new_dentry);
11322 exit4:
11323diff -urNp linux-2.6.19.1/fs/namespace.c linux-2.6.19.1/fs/namespace.c
11324--- linux-2.6.19.1/fs/namespace.c 2006-11-29 16:57:37.000000000 -0500
11325+++ linux-2.6.19.1/fs/namespace.c 2006-12-03 15:16:15.000000000 -0500
11326@@ -25,6 +25,7 @@
b6fa5d20 11327 #include <linux/vserver/space.h>
11328 #include <linux/vs_context.h>
11329 #include <linux/vs_tag.h>
c3e8c1b5 11330+#include <linux/grsecurity.h>
11331 #include <asm/uaccess.h>
11332 #include <asm/unistd.h>
11333 #include "pnode.h"
11334@@ -598,6 +599,8 @@ static int do_umount(struct vfsmount *mn
11335 DQUOT_OFF(sb);
11336 retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
11337 unlock_kernel();
11338+
11339+ gr_log_remount(mnt->mnt_devname, retval);
11340 }
11341 up_write(&sb->s_umount);
11342 return retval;
11343@@ -618,6 +621,9 @@ static int do_umount(struct vfsmount *mn
11344 security_sb_umount_busy(mnt);
11345 up_write(&namespace_sem);
11346 release_mounts(&umount_list);
11347+
11348+ gr_log_unmount(mnt->mnt_devname, retval);
11349+
11350 return retval;
11351 }
11352
11353@@ -1418,6 +1424,11 @@ long do_mount(char *dev_name, char *dir_
11354 if (retval)
11355 goto dput_out;
11356
11357+ if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
11358+ retval = -EPERM;
11359+ goto dput_out;
11360+ }
11361+
11362 if (flags & MS_REMOUNT)
11363 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
11364 data_page);
11365@@ -1432,6 +1443,9 @@ long do_mount(char *dev_name, char *dir_
11366 dev_name, data_page);
11367 dput_out:
11368 path_release(&nd);
11369+
11370+ gr_log_mount(dev_name, dir_name, retval);
11371+
11372 return retval;
11373 }
11374
11375@@ -1684,6 +1698,9 @@ asmlinkage long sys_pivot_root(const cha
11376 if (!capable(CAP_SYS_ADMIN))
11377 return -EPERM;
11378
11379+ if (gr_handle_chroot_pivot())
11380+ return -EPERM;
11381+
11382 lock_kernel();
11383
11384 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
11385diff -urNp linux-2.6.19.1/fs/open.c linux-2.6.19.1/fs/open.c
11386--- linux-2.6.19.1/fs/open.c 2006-11-29 16:57:37.000000000 -0500
11387+++ linux-2.6.19.1/fs/open.c 2006-12-03 15:16:15.000000000 -0500
11388@@ -27,6 +27,7 @@
b6fa5d20 11389 #include <linux/vs_dlimit.h>
11390 #include <linux/vs_tag.h>
11391 #include <linux/vs_cowbl.h>
c3e8c1b5 11392+#include <linux/grsecurity.h>
11393
11394 int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
11395 {
11396@@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
11397 if (length < 0)
11398 return -EINVAL;
11399
11400+ if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
11401+ return -EACCES;
11402+
11403 newattrs.ia_size = length;
11404 newattrs.ia_valid = ATTR_SIZE | time_attrs;
11405 if (filp) {
11406@@ -398,6 +402,9 @@ asmlinkage long sys_faccessat(int dfd, c
11407 if(IS_RDONLY(nd.dentry->d_inode))
11408 res = -EROFS;
11409
11410+ if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
11411+ res = -EACCES;
11412+
11413 out_path_release:
11414 path_release(&nd);
11415 out:
11416@@ -427,6 +434,8 @@ asmlinkage long sys_chdir(const char __u
11417 if (error)
11418 goto dput_and_out;
11419
11420+ gr_log_chdir(nd.dentry, nd.mnt);
11421+
11422 set_fs_pwd(current->fs, nd.mnt, nd.dentry);
11423
11424 dput_and_out:
11425@@ -457,6 +466,13 @@ asmlinkage long sys_fchdir(unsigned int
11426 goto out_putf;
11427
11428 error = file_permission(file, MAY_EXEC);
11429+
11430+ if (!error && !gr_chroot_fchdir(dentry, mnt))
11431+ error = -EPERM;
11432+
11433+ if (!error)
11434+ gr_log_chdir(dentry, mnt);
11435+
11436 if (!error)
11437 set_fs_pwd(current->fs, mnt, dentry);
11438 out_putf:
11439@@ -482,8 +498,16 @@ asmlinkage long sys_chroot(const char __
11440 if (!capable(CAP_SYS_CHROOT))
11441 goto dput_and_out;
11442
11443+ if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
11444+ goto dput_and_out;
11445+
11446 set_fs_root(current->fs, nd.mnt, nd.dentry);
11447 set_fs_altroot();
11448+
11449+ gr_handle_chroot_caps(current);
11450+
11451+ gr_handle_chroot_chdir(nd.dentry, nd.mnt);
11452+
11453 error = 0;
11454 dput_and_out:
11455 path_release(&nd);
11456@@ -514,9 +538,22 @@ asmlinkage long sys_fchmod(unsigned int
11457 err = -EPERM;
11458 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
11459 goto out_putf;
11460+
11461+ if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
11462+ err = -EACCES;
11463+ goto out_putf;
11464+ }
11465+
11466 mutex_lock(&inode->i_mutex);
11467 if (mode == (mode_t) -1)
11468 mode = inode->i_mode;
11469+
11470+ if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
11471+ err = -EPERM;
11472+ mutex_unlock(&inode->i_mutex);
11473+ goto out_putf;
11474+ }
11475+
11476 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
11477 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
11478 err = notify_change(dentry, &newattrs);
11479@@ -549,9 +586,21 @@ asmlinkage long sys_fchmodat(int dfd, co
11480 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
11481 goto dput_and_out;
11482
11483+ if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
11484+ error = -EACCES;
11485+ goto dput_and_out;
11486+ };
11487+
11488 mutex_lock(&inode->i_mutex);
11489 if (mode == (mode_t) -1)
11490 mode = inode->i_mode;
11491+
11492+ if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
11493+ error = -EACCES;
11494+ mutex_unlock(&inode->i_mutex);
11495+ goto dput_and_out;
11496+ }
11497+
11498 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
11499 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
11500 error = notify_change(nd.dentry, &newattrs);
c3e8c1b5 11501@@ -585,6 +634,12 @@ static int chown_common(struct dentry *
11502 error = -EPERM;
11503 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
11504 goto out;
11505+
11506+ if (!gr_acl_handle_chown(dentry, mnt)) {
11507+ error = -EACCES;
11508+ goto out;
11509+ }
11510+
11511 newattrs.ia_valid = ATTR_CTIME;
11512 if (user != (uid_t) -1) {
11513 newattrs.ia_valid |= ATTR_UID;
c3e8c1b5 11514@@ -872,6 +927,7 @@ repeat:
11515 * N.B. For clone tasks sharing a files structure, this test
11516 * will limit the total number of files that can be opened.
11517 */
11518+ gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
11519 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
11520 goto out;
11521
11522diff -urNp linux-2.6.19.1/fs/partitions/efi.c linux-2.6.19.1/fs/partitions/efi.c
11523--- linux-2.6.19.1/fs/partitions/efi.c 2006-11-29 16:57:37.000000000 -0500
11524+++ linux-2.6.19.1/fs/partitions/efi.c 2006-12-03 15:16:15.000000000 -0500
11525@@ -99,7 +99,7 @@
11526 #ifdef EFI_DEBUG
11527 #define Dprintk(x...) printk(KERN_DEBUG x)
11528 #else
11529-#define Dprintk(x...)
11530+#define Dprintk(x...) do {} while (0)
11531 #endif
11532
11533 /* This allows a kernel command line option 'gpt' to override
11534diff -urNp linux-2.6.19.1/fs/pipe.c linux-2.6.19.1/fs/pipe.c
11535--- linux-2.6.19.1/fs/pipe.c 2006-11-29 16:57:37.000000000 -0500
11536+++ linux-2.6.19.1/fs/pipe.c 2006-12-03 15:16:15.000000000 -0500
11537@@ -827,7 +827,7 @@ void free_pipe_info(struct inode *inode)
11538 inode->i_pipe = NULL;
11539 }
11540
11541-static struct vfsmount *pipe_mnt __read_mostly;
11542+struct vfsmount *pipe_mnt __read_mostly;
11543 static int pipefs_delete_dentry(struct dentry *dentry)
11544 {
11545 return 1;
11546diff -urNp linux-2.6.19.1/fs/proc/array.c linux-2.6.19.1/fs/proc/array.c
11547--- linux-2.6.19.1/fs/proc/array.c 2006-11-29 16:57:37.000000000 -0500
11548+++ linux-2.6.19.1/fs/proc/array.c 2006-12-03 15:16:15.000000000 -0500
11549@@ -291,6 +291,21 @@ static inline char *task_cap(struct task
11550 cap_t(p->cap_effective));
11551 }
11552
11553+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
11554+static inline char *task_pax(struct task_struct *p, char *buffer)
11555+{
11556+ if (p->mm)
11557+ return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
11558+ p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
11559+ p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
11560+ p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
11561+ p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
11562+ p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
11563+ else
11564+ return buffer + sprintf(buffer, "PaX:\t-----\n");
11565+}
11566+#endif
11567+
11568 int proc_pid_status(struct task_struct *task, char * buffer)
11569 {
11570 char * orig = buffer;
11571@@ -309,9 +324,20 @@ int proc_pid_status(struct task_struct *
11572 #if defined(CONFIG_S390)
11573 buffer = task_show_regs(task, buffer);
11574 #endif
11575+
11576+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
11577+ buffer = task_pax(task, buffer);
11578+#endif
11579+
11580 return buffer - orig;
11581 }
11582
11583+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11584+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
11585+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
11586+ _mm->pax_flags & MF_PAX_SEGMEXEC))
11587+#endif
11588+
11589 static int do_task_stat(struct task_struct *task, char * buffer, int whole)
11590 {
11591 unsigned long vsize, eip, esp, wchan = ~0UL;
11592@@ -406,6 +432,19 @@ static int do_task_stat(struct task_stru
11593 stime = task->stime;
11594 }
11595
11596+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11597+ if (PAX_RAND_FLAGS(mm)) {
11598+ eip = 0;
11599+ esp = 0;
11600+ wchan = 0;
11601+ }
11602+#endif
11603+#ifdef CONFIG_GRKERNSEC_HIDESYM
11604+ wchan = 0;
11605+ eip =0;
11606+ esp =0;
11607+#endif
11608+
11609 /* scale priority and nice values from timeslices to -20..20 */
11610 /* to make it look like a "normal" Unix priority/nice value */
11611 priority = task_prio(task);
11612@@ -445,9 +484,15 @@ static int do_task_stat(struct task_stru
11613 vsize,
11614 mm ? get_mm_rss(mm) : 0,
11615 rsslim,
11616+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
11617+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
11618+ PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
11619+ PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
11620+#else
11621 mm ? mm->start_code : 0,
11622 mm ? mm->end_code : 0,
11623 mm ? mm->start_stack : 0,
11624+#endif
11625 esp,
11626 eip,
11627 /* The signal information here is obsolete.
11628@@ -494,3 +539,14 @@ int proc_pid_statm(struct task_struct *t
11629 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
11630 size, resident, shared, text, lib, data, 0);
11631 }
11632+
11633+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11634+int proc_pid_ipaddr(struct task_struct *task, char * buffer)
11635+{
11636+ int len;
11637+
11638+ len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
11639+ return len;
11640+}
11641+#endif
11642+
11643diff -urNp linux-2.6.19.1/fs/proc/base.c linux-2.6.19.1/fs/proc/base.c
11644--- linux-2.6.19.1/fs/proc/base.c 2006-11-29 16:57:37.000000000 -0500
11645+++ linux-2.6.19.1/fs/proc/base.c 2006-12-03 15:41:31.000000000 -0500
11646@@ -73,6 +73,7 @@
c3e8c1b5 11647 #include <linux/oom.h>
b6fa5d20 11648 #include <linux/vs_context.h>
11649 #include <linux/vs_network.h>
c3e8c1b5 11650+#include <linux/grsecurity.h>
b6fa5d20 11651
c3e8c1b5 11652 #include "internal.h"
11653
c3e8c1b5 11654@@ -194,7 +195,7 @@ static int proc_root_link(struct inode *
11655 (task->parent == current && \
11656 (task->ptrace & PT_PTRACED) && \
11657 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
11658- security_ptrace(current,task) == 0))
11659+ security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
11660
11661 static int proc_pid_environ(struct task_struct *task, char * buffer)
11662 {
11663@@ -330,6 +331,8 @@ static int proc_fd_access_allowed(struct
11664 task = get_proc_task(inode);
11665 if (task) {
11666 allowed = ptrace_may_attach(task);
11667+ if (allowed != 0)
11668+ allowed = !gr_acl_handle_procpidmem(task);
11669 put_task_struct(task);
11670 }
11671 return allowed;
11672@@ -521,7 +524,7 @@ static ssize_t mem_read(struct file * fi
11673 if (!task)
11674 goto out_no_task;
11675
11676- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
11677+ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
11678 goto out;
11679
11680 ret = -ENOMEM;
11681@@ -591,7 +594,7 @@ static ssize_t mem_write(struct file * f
11682 if (!task)
11683 goto out_no_task;
11684
11685- if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
11686+ if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
11687 goto out;
11688
11689 copied = -ENOMEM;
11690@@ -969,7 +972,11 @@ static struct inode *proc_pid_make_inode
11691 inode->i_gid = 0;
11692 if (task_dumpable(task)) {
11693 inode->i_uid = task->euid;
11694+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11695+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11696+#else
11697 inode->i_gid = task->egid;
11698+#endif
11699 }
11700 security_task_to_inode(task, inode);
11701
11702@@ -985,17 +992,38 @@ static int pid_getattr(struct vfsmount *
11703 {
11704 struct inode *inode = dentry->d_inode;
11705 struct task_struct *task;
11706+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11707+ struct task_struct *tmp = current;
11708+#endif
11709+
11710 generic_fillattr(inode, stat);
11711
11712 rcu_read_lock();
11713 stat->uid = 0;
11714 stat->gid = 0;
11715 task = pid_task(proc_pid(inode), PIDTYPE_PID);
11716- if (task) {
11717+ if (task &&
11718+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11719+ (!tmp->uid || (tmp->uid == task->uid)
11720+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11721+ || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11722+#endif
11723+ ) &&
11724+#endif
11725+ !gr_check_hidden_task(task)) {
11726 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
11727+#ifdef CONFIG_GRKERNSEC_PROC_USER
11728+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
11729+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11730+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
11731+#endif
11732 task_dumpable(task)) {
11733 stat->uid = task->euid;
11734+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11735+ stat->gid = CONFIG_GRKERNSEC_PROC_GID;
11736+#else
11737 stat->gid = task->egid;
11738+#endif
11739 }
11740 }
11741 rcu_read_unlock();
11742@@ -1025,9 +1053,18 @@ static int pid_revalidate(struct dentry
11743 struct task_struct *task = get_proc_task(inode);
11744 if (task) {
11745 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
11746+#ifdef CONFIG_GRKERNSEC_PROC_USER
11747+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
11748+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11749+ (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
11750+#endif
11751 task_dumpable(task)) {
11752 inode->i_uid = task->euid;
11753+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11754+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11755+#else
11756 inode->i_gid = task->egid;
11757+#endif
11758 } else {
11759 inode->i_uid = 0;
11760 inode->i_gid = 0;
11761@@ -1273,6 +1310,9 @@ static struct dentry *proc_lookupfd(stru
11762 if (fd == ~0U)
11763 goto out;
11764
11765+ if (gr_acl_handle_procpidmem(task))
11766+ goto out;
11767+
11768 result = proc_fd_instantiate(dir, dentry, task, &fd);
11769 out:
11770 put_task_struct(task);
11771@@ -1317,6 +1357,8 @@ static int proc_readfd(struct file * fil
11772 goto out;
11773 filp->f_pos++;
11774 default:
11775+ if (gr_acl_handle_procpidmem(p))
11776+ goto out;
11777 files = get_files_struct(p);
11778 if (!files)
11779 goto out;
11780@@ -1791,6 +1833,9 @@ static struct pid_entry tgid_base_stuff[
11781 #ifdef CONFIG_AUDITSYSCALL
11782 REG("loginuid", S_IWUSR|S_IRUGO, loginuid),
11783 #endif
11784+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11785+ INF("ipaddr", S_IRUSR, pid_ipaddr),
11786+#endif
11787 };
11788
11789 static int proc_tgid_base_readdir(struct file * filp,
11790@@ -1893,7 +1938,14 @@ struct dentry *proc_pid_instantiate(stru
11791 if (!inode)
11792 goto out;
11793
11794+#ifdef CONFIG_GRKERNSEC_PROC_USER
11795+ inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
11796+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11797+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11798+ inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
11799+#else
11800 inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
11801+#endif
11802 inode->i_op = &proc_tgid_base_inode_operations;
11803 inode->i_fop = &proc_tgid_base_operations;
11804 inode->i_flags|=S_IMMUTABLE;
11805@@ -1934,7 +1986,11 @@ struct dentry *proc_pid_lookup(struct in
11806 if (!task)
11807 goto out;
11808
11809+ if (gr_check_hidden_task(task))
11810+ goto out_put_task;
11811+
11812 result = proc_pid_instantiate(dir, dentry, task, NULL);
11813+out_put_task:
11814 put_task_struct(task);
11815 out:
11816 return result;
11817@@ -1992,6 +2048,9 @@ int proc_pid_readdir(struct file * filp,
11818 {
11819 unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
b6fa5d20 11820 struct task_struct *reaper = get_proc_task_real(filp->f_dentry->d_inode);
c3e8c1b5 11821+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11822+ struct task_struct *tmp = current;
11823+#endif
11824 struct task_struct *task;
11825 int tgid;
11826
11827@@ -2009,6 +2068,18 @@ int proc_pid_readdir(struct file * filp,
11828 task;
11829 put_task_struct(task), task = next_tgid(tgid + 1)) {
11830 tgid = task->pid;
11831+
11832+ if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
11833+#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11834+ || (tmp->uid && (task->uid != tmp->uid)
11835+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11836+ && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
11837+#endif
11838+ )
11839+#endif
11840+ )
11841+ continue;
11842+
11843 filp->f_pos = tgid + TGID_OFFSET;
11844 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
11845 put_task_struct(task);
11846diff -urNp linux-2.6.19.1/fs/proc/inode.c linux-2.6.19.1/fs/proc/inode.c
11847--- linux-2.6.19.1/fs/proc/inode.c 2006-11-29 16:57:37.000000000 -0500
11848+++ linux-2.6.19.1/fs/proc/inode.c 2006-12-03 15:16:15.000000000 -0500
11849@@ -166,7 +166,11 @@ struct inode *proc_get_inode(struct supe
11850 if (de->mode) {
11851 inode->i_mode = de->mode;
11852 inode->i_uid = de->uid;
11853+#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
11854+ inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
11855+#else
11856 inode->i_gid = de->gid;
11857+#endif
11858 }
11859 if (de->size)
11860 inode->i_size = de->size;
11861diff -urNp linux-2.6.19.1/fs/proc/internal.h linux-2.6.19.1/fs/proc/internal.h
11862--- linux-2.6.19.1/fs/proc/internal.h 2006-11-29 16:57:37.000000000 -0500
11863+++ linux-2.6.19.1/fs/proc/internal.h 2006-12-03 15:16:15.000000000 -0500
11864@@ -37,6 +37,9 @@ extern int proc_tid_stat(struct task_str
11865 extern int proc_tgid_stat(struct task_struct *, char *);
11866 extern int proc_pid_status(struct task_struct *, char *);
11867 extern int proc_pid_statm(struct task_struct *, char *);
11868+#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
11869+extern int proc_pid_ipaddr(struct task_struct*,char*);
11870+#endif
11871
11872 extern struct file_operations proc_maps_operations;
11873 extern struct file_operations proc_numa_maps_operations;
11874diff -urNp linux-2.6.19.1/fs/proc/proc_misc.c linux-2.6.19.1/fs/proc/proc_misc.c
11875--- linux-2.6.19.1/fs/proc/proc_misc.c 2006-11-29 16:57:37.000000000 -0500
11876+++ linux-2.6.19.1/fs/proc/proc_misc.c 2006-12-03 15:16:15.000000000 -0500
11877@@ -670,6 +670,8 @@ void create_seq_entry(char *name, mode_t
11878 void __init proc_misc_init(void)
11879 {
11880 struct proc_dir_entry *entry;
11881+ int gr_mode = 0;
11882+
11883 static struct {
11884 char *name;
11885 int (*read_proc)(char*,char**,off_t,int,int*,void*);
11886@@ -685,7 +687,9 @@ void __init proc_misc_init(void)
11887 {"stram", stram_read_proc},
11888 #endif
11889 {"filesystems", filesystems_read_proc},
11890+#ifndef CONFIG_GRKERNSEC_PROC_ADD
11891 {"cmdline", cmdline_read_proc},
11892+#endif
11893 {"locks", locks_read_proc},
11894 {"execdomains", execdomains_read_proc},
11895 {NULL,}
11896@@ -693,13 +697,26 @@ void __init proc_misc_init(void)
11897 for (p = simple_ones; p->name; p++)
11898 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
11899
11900+#ifdef CONFIG_GRKERNSEC_PROC_USER
11901+ gr_mode = S_IRUSR;
11902+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11903+ gr_mode = S_IRUSR | S_IRGRP;
11904+#endif
11905+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11906+ create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
11907+#endif
11908+
11909 proc_symlink("mounts", NULL, "self/mounts");
11910
11911 /* And now for trickier ones */
11912 entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
11913 if (entry)
11914 entry->proc_fops = &proc_kmsg_operations;
11915+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11916+ create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
11917+#else
11918 create_seq_entry("devices", 0, &proc_devinfo_operations);
11919+#endif
11920 create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
11921 #ifdef CONFIG_BLOCK
11922 create_seq_entry("partitions", 0, &proc_partitions_operations);
11923@@ -707,7 +724,11 @@ void __init proc_misc_init(void)
11924 create_seq_entry("stat", 0, &proc_stat_operations);
11925 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
11926 #ifdef CONFIG_SLAB
11927+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11928+ create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
11929+#else
11930 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
11931+#endif
11932 #ifdef CONFIG_DEBUG_SLAB_LEAK
11933 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
11934 #endif
11935@@ -724,7 +745,7 @@ void __init proc_misc_init(void)
11936 #ifdef CONFIG_SCHEDSTATS
11937 create_seq_entry("schedstat", 0, &proc_schedstat_operations);
11938 #endif
11939-#ifdef CONFIG_PROC_KCORE
11940+#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
11941 proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
11942 if (proc_root_kcore) {
11943 proc_root_kcore->proc_fops = &proc_kcore_operations;
11944diff -urNp linux-2.6.19.1/fs/proc/root.c linux-2.6.19.1/fs/proc/root.c
11945--- linux-2.6.19.1/fs/proc/root.c 2006-11-29 16:57:37.000000000 -0500
11946+++ linux-2.6.19.1/fs/proc/root.c 2006-12-03 15:16:15.000000000 -0500
11947@@ -64,7 +64,13 @@ void __init proc_root_init(void)
11948 return;
11949 }
11950 proc_misc_init();
11951+#ifdef CONFIG_GRKERNSEC_PROC_USER
11952+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
11953+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11954+ proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
11955+#else
11956 proc_net = proc_mkdir("net", NULL);
11957+#endif
11958 proc_net_stat = proc_mkdir("net/stat", NULL);
11959
11960 #ifdef CONFIG_SYSVIPC
11961@@ -88,7 +94,15 @@ void __init proc_root_init(void)
11962 #ifdef CONFIG_PROC_DEVICETREE
11963 proc_device_tree_init();
11964 #endif
11965+#ifdef CONFIG_GRKERNSEC_PROC_ADD
11966+#ifdef CONFIG_GRKERNSEC_PROC_USER
11967+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
11968+#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
11969+ proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
11970+#endif
11971+#else
11972 proc_bus = proc_mkdir("bus", NULL);
11973+#endif
b6fa5d20 11974 proc_vx_init();
c3e8c1b5 11975 }
11976
11977 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
11978diff -urNp linux-2.6.19.1/fs/proc/task_mmu.c linux-2.6.19.1/fs/proc/task_mmu.c
11979--- linux-2.6.19.1/fs/proc/task_mmu.c 2006-11-29 16:57:37.000000000 -0500
11980+++ linux-2.6.19.1/fs/proc/task_mmu.c 2006-12-03 15:16:15.000000000 -0500
11981@@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
11982 "VmStk:\t%8lu kB\n"
11983 "VmExe:\t%8lu kB\n"
11984 "VmLib:\t%8lu kB\n"
11985- "VmPTE:\t%8lu kB\n",
11986- hiwater_vm << (PAGE_SHIFT-10),
11987+ "VmPTE:\t%8lu kB\n"
11988+
11989+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
11990+ "CsBase:\t%8lx\nCsLim:\t%8lx\n"
11991+#endif
11992+
11993+ ,hiwater_vm << (PAGE_SHIFT-10),
11994 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
11995 mm->locked_vm << (PAGE_SHIFT-10),
11996 hiwater_rss << (PAGE_SHIFT-10),
11997 total_rss << (PAGE_SHIFT-10),
11998 data << (PAGE_SHIFT-10),
11999 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
12000- (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
12001+ (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
12002+
12003+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
12004+ , mm->context.user_cs_base, mm->context.user_cs_limit
12005+#endif
12006+
12007+ );
12008+
12009 return buffer;
12010 }
12011
12012@@ -122,6 +134,12 @@ struct mem_size_stats
12013 unsigned long private_dirty;
12014 };
12015
12016+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
12017+#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
12018+ (_mm->pax_flags & MF_PAX_RANDMMAP || \
12019+ _mm->pax_flags & MF_PAX_SEGMEXEC))
12020+#endif
12021+
12022 static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
12023 {
12024 struct proc_maps_private *priv = m->private;
12025@@ -141,13 +159,30 @@ static int show_map_internal(struct seq_
12026 }
12027
12028 seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
12029+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
12030+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
12031+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
12032+#else
12033 vma->vm_start,
12034 vma->vm_end,
12035+#endif
12036+
12037+#if 0
12038+ flags & VM_MAYREAD ? flags & VM_READ ? 'R' : '+' : flags & VM_READ ? 'r' : '-',
12039+ flags & VM_MAYWRITE ? flags & VM_WRITE ? 'W' : '+' : flags & VM_WRITE ? 'w' : '-',
12040+ flags & VM_MAYEXEC ? flags & VM_EXEC ? 'X' : '+' : flags & VM_EXEC ? 'x' : '-',
12041+#else
12042 flags & VM_READ ? 'r' : '-',
12043 flags & VM_WRITE ? 'w' : '-',
12044 flags & VM_EXEC ? 'x' : '-',
12045+#endif
12046+
12047 flags & VM_MAYSHARE ? 's' : 'p',
12048+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
12049+ PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
12050+#else
12051 vma->vm_pgoff << PAGE_SHIFT,
12052+#endif
12053 MAJOR(dev), MINOR(dev), ino, &len);
12054
12055 /*
12056@@ -161,11 +196,11 @@ static int show_map_internal(struct seq_
12057 const char *name = arch_vma_name(vma);
12058 if (!name) {
12059 if (mm) {
12060- if (vma->vm_start <= mm->start_brk &&
12061- vma->vm_end >= mm->brk) {
12062+ if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
12063 name = "[heap]";
12064- } else if (vma->vm_start <= mm->start_stack &&
12065- vma->vm_end >= mm->start_stack) {
12066+ } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
12067+ (vma->vm_start <= mm->start_stack &&
12068+ vma->vm_end >= mm->start_stack)) {
12069 name = "[stack]";
12070 }
12071 } else {
12072@@ -179,7 +214,25 @@ static int show_map_internal(struct seq_
12073 }
12074 seq_putc(m, '\n');
12075
12076- if (mss)
12077+
12078+ if (mss) {
12079+#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
12080+ if (PAX_RAND_FLAGS(mm))
12081+ seq_printf(m,
12082+ "Size: %8lu kB\n"
12083+ "Rss: %8lu kB\n"
12084+ "Shared_Clean: %8lu kB\n"
12085+ "Shared_Dirty: %8lu kB\n"
12086+ "Private_Clean: %8lu kB\n"
12087+ "Private_Dirty: %8lu kB\n",
12088+ 0UL,
12089+ 0UL,
12090+ 0UL,
12091+ 0UL,
12092+ 0UL,
12093+ 0UL);
12094+ else
12095+#endif
12096 seq_printf(m,
12097 "Size: %8lu kB\n"
12098 "Rss: %8lu kB\n"
12099@@ -193,6 +246,7 @@ static int show_map_internal(struct seq_
12100 mss->shared_dirty >> 10,
12101 mss->private_clean >> 10,
12102 mss->private_dirty >> 10);
12103+ }
12104
12105 if (m->count < m->size) /* vma is copied successfully */
12106 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
12107diff -urNp linux-2.6.19.1/fs/readdir.c linux-2.6.19.1/fs/readdir.c
12108--- linux-2.6.19.1/fs/readdir.c 2006-11-29 16:57:37.000000000 -0500
12109+++ linux-2.6.19.1/fs/readdir.c 2006-12-03 16:05:44.000000000 -0500
12110@@ -16,6 +16,8 @@
12111 #include <linux/security.h>
12112 #include <linux/syscalls.h>
12113 #include <linux/unistd.h>
12114+#include <linux/namei.h>
12115+#include <linux/grsecurity.h>
12116
12117 #include <asm/uaccess.h>
12118
12119@@ -65,6 +67,7 @@ struct old_linux_dirent {
12120
12121 struct readdir_callback {
12122 struct old_linux_dirent __user * dirent;
12123+ struct file * file;
12124 int result;
12125 };
12126
12127@@ -80,6 +83,10 @@ static int fillonedir(void * __buf, cons
12128 d_ino = ino;
12129 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
12130 return -EOVERFLOW;
12131+
12132+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
12133+ return 0;
12134+
12135 buf->result++;
12136 dirent = buf->dirent;
12137 if (!access_ok(VERIFY_WRITE, dirent,
12138@@ -111,6 +118,7 @@ asmlinkage long old_readdir(unsigned int
12139
12140 buf.result = 0;
12141 buf.dirent = dirent;
12142+ buf.file = file;
12143
12144 error = vfs_readdir(file, fillonedir, &buf);
12145 if (error >= 0)
12146@@ -137,6 +145,7 @@ struct linux_dirent {
12147 struct getdents_callback {
12148 struct linux_dirent __user * current_dir;
12149 struct linux_dirent __user * previous;
12150+ struct file * file;
12151 int count;
12152 int error;
12153 };
12154@@ -155,6 +164,10 @@ static int filldir(void * __buf, const c
12155 d_ino = ino;
12156 if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
12157 return -EOVERFLOW;
12158+
12159+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
12160+ return 0;
12161+
12162 dirent = buf->previous;
12163 if (dirent) {
12164 if (__put_user(offset, &dirent->d_off))
12165@@ -201,6 +214,7 @@ asmlinkage long sys_getdents(unsigned in
12166 buf.previous = NULL;
12167 buf.count = count;
12168 buf.error = 0;
12169+ buf.file = file;
12170
12171 error = vfs_readdir(file, filldir, &buf);
12172 if (error < 0)
12173@@ -225,6 +239,7 @@ out:
12174 struct getdents_callback64 {
12175 struct linux_dirent64 __user * current_dir;
12176 struct linux_dirent64 __user * previous;
12177+ struct file *file;
12178 int count;
12179 int error;
12180 };
12181@@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
12182 buf->error = -EINVAL; /* only used if we fail.. */
12183 if (reclen > buf->count)
12184 return -EINVAL;
12185+
12186+ if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
12187+ return 0;
12188+
12189 dirent = buf->previous;
12190 if (dirent) {
12191 if (__put_user(offset, &dirent->d_off))
12192@@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned
12193
12194 buf.current_dir = dirent;
12195 buf.previous = NULL;
12196+ buf.file = file;
12197 buf.count = count;
12198 buf.error = 0;
12199
12200diff -urNp linux-2.6.19.1/fs/udf/balloc.c linux-2.6.19.1/fs/udf/balloc.c
12201--- linux-2.6.19.1/fs/udf/balloc.c 2006-11-29 16:57:37.000000000 -0500
12202+++ linux-2.6.19.1/fs/udf/balloc.c 2006-12-03 15:16:15.000000000 -0500
12203@@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
12204 unsigned long overflow;
12205
12206 mutex_lock(&sbi->s_alloc_mutex);
12207- if (bloc.logicalBlockNum < 0 ||
12208- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12209+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12210 {
12211 udf_debug("%d < %d || %d + %d > %d\n",
12212 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
12213@@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
12214 struct buffer_head *bh;
12215
12216 mutex_lock(&sbi->s_alloc_mutex);
12217- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
12218+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
12219 goto out;
12220
12221 if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
12222@@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
12223 mutex_lock(&sbi->s_alloc_mutex);
12224
12225 repeat:
12226- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
12227+ if (goal >= UDF_SB_PARTLEN(sb, partition))
12228 goal = 0;
12229
12230 nr_groups = bitmap->s_nr_groups;
12231@@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
12232 int i;
12233
12234 mutex_lock(&sbi->s_alloc_mutex);
12235- if (bloc.logicalBlockNum < 0 ||
12236- (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12237+ if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
12238 {
12239 udf_debug("%d < %d || %d + %d > %d\n",
12240 bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
12241@@ -682,7 +680,7 @@ static int udf_table_prealloc_blocks(str
12242 struct buffer_head *bh;
12243 int8_t etype = -1;
12244
12245- if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
12246+ if (first_block >= UDF_SB_PARTLEN(sb, partition))
12247 return 0;
12248
12249 if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
12250@@ -762,7 +760,7 @@ static int udf_table_new_block(struct su
12251 return newblock;
12252
12253 mutex_lock(&sbi->s_alloc_mutex);
12254- if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
12255+ if (goal >= UDF_SB_PARTLEN(sb, partition))
12256 goal = 0;
12257
12258 /* We search for the closest matching block to goal. If we find a exact hit,
12259diff -urNp linux-2.6.19.1/fs/udf/inode.c linux-2.6.19.1/fs/udf/inode.c
12260--- linux-2.6.19.1/fs/udf/inode.c 2006-11-29 16:57:37.000000000 -0500
12261+++ linux-2.6.19.1/fs/udf/inode.c 2006-12-03 15:16:15.000000000 -0500
12262@@ -300,9 +300,6 @@ static int udf_get_block(struct inode *i
12263
12264 lock_kernel();
12265
12266- if (block < 0)
12267- goto abort_negative;
12268-
12269 if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
12270 {
12271 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
12272@@ -323,10 +320,6 @@ static int udf_get_block(struct inode *i
12273 abort:
12274 unlock_kernel();
12275 return err;
12276-
12277-abort_negative:
12278- udf_warning(inode->i_sb, "udf_get_block", "block < 0");
12279- goto abort;
12280 }
12281
12282 static struct buffer_head *
12283diff -urNp linux-2.6.19.1/fs/ufs/inode.c linux-2.6.19.1/fs/ufs/inode.c
12284--- linux-2.6.19.1/fs/ufs/inode.c 2006-11-29 16:57:37.000000000 -0500
12285+++ linux-2.6.19.1/fs/ufs/inode.c 2006-12-03 15:16:16.000000000 -0500
12286@@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
12287
12288
12289 UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
12290- if (i_block < 0) {
12291- ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
12292- } else if (i_block < direct_blocks) {
12293+ if (i_block < direct_blocks) {
12294 offsets[n++] = i_block;
12295 } else if ((i_block -= direct_blocks) < indirect_blocks) {
12296 offsets[n++] = UFS_IND_BLOCK;
12297@@ -454,8 +452,6 @@ int ufs_getfrag_block(struct inode *inod
12298 lock_kernel();
12299
12300 UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
12301- if (fragment < 0)
12302- goto abort_negative;
12303 if (fragment >
12304 ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
12305 << uspi->s_fpbshift))
12306@@ -516,10 +512,6 @@ abort:
12307 unlock_kernel();
12308 return err;
12309
12310-abort_negative:
12311- ufs_warning(sb, "ufs_get_block", "block < 0");
12312- goto abort;
12313-
12314 abort_too_big:
12315 ufs_warning(sb, "ufs_get_block", "block > big");
12316 goto abort;
12317diff -urNp linux-2.6.19.1/fs/utimes.c linux-2.6.19.1/fs/utimes.c
12318--- linux-2.6.19.1/fs/utimes.c 2006-11-29 16:57:37.000000000 -0500
12319+++ linux-2.6.19.1/fs/utimes.c 2006-12-03 15:16:16.000000000 -0500
12320@@ -3,6 +3,7 @@
c3e8c1b5 12321 #include <linux/utime.h>
b6fa5d20 12322 #include <linux/mount.h>
12323 #include <linux/vs_cowbl.h>
c3e8c1b5 12324+#include <linux/grsecurity.h>
12325 #include <asm/uaccess.h>
12326 #include <asm/unistd.h>
12327
12328@@ -60,6 +61,12 @@ asmlinkage long sys_utime(char __user *
12329 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
12330 goto dput_and_out;
12331 }
12332+
12333+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
12334+ error = -EACCES;
12335+ goto dput_and_out;
12336+ }
12337+
12338 mutex_lock(&inode->i_mutex);
12339 error = notify_change(nd.dentry, &newattrs);
12340 mutex_unlock(&inode->i_mutex);
12341@@ -113,6 +120,12 @@ long do_utimes(int dfd, char __user *fil
12342 (error = vfs_permission(&nd, MAY_WRITE)) != 0)
12343 goto dput_and_out;
12344 }
12345+
12346+ if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
12347+ error = -EACCES;
12348+ goto dput_and_out;
12349+ }
12350+
12351 mutex_lock(&inode->i_mutex);
12352 error = notify_change(nd.dentry, &newattrs);
12353 mutex_unlock(&inode->i_mutex);
12354diff -urNp linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c
12355--- linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c 2006-11-29 16:57:37.000000000 -0500
12356+++ linux-2.6.19.1/fs/xfs/linux-2.6/xfs_file.c 2006-12-03 15:16:16.000000000 -0500
12357@@ -342,6 +342,12 @@ xfs_file_mmap(
12358 struct file *filp,
12359 struct vm_area_struct *vma)
12360 {
12361+
12362+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
12363+ if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
12364+ vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
12365+#endif
12366+
12367 vma->vm_ops = &xfs_file_vm_ops;
12368
12369 #ifdef CONFIG_XFS_DMAPI
12370diff -urNp linux-2.6.19.1/fs/xfs/xfs_bmap.c linux-2.6.19.1/fs/xfs/xfs_bmap.c
12371--- linux-2.6.19.1/fs/xfs/xfs_bmap.c 2006-11-29 16:57:37.000000000 -0500
12372+++ linux-2.6.19.1/fs/xfs/xfs_bmap.c 2006-12-03 15:16:16.000000000 -0500
12373@@ -376,7 +376,7 @@ xfs_bmap_validate_ret(
12374 int nmap,
12375 int ret_nmap);
12376 #else
12377-#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
12378+#define xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
12379 #endif /* DEBUG */
12380
12381 #if defined(XFS_RW_TRACE)
12382diff -urNp linux-2.6.19.1/grsecurity/gracl_alloc.c linux-2.6.19.1/grsecurity/gracl_alloc.c
12383--- linux-2.6.19.1/grsecurity/gracl_alloc.c 1969-12-31 19:00:00.000000000 -0500
12384+++ linux-2.6.19.1/grsecurity/gracl_alloc.c 2006-12-03 15:16:32.000000000 -0500
12385@@ -0,0 +1,91 @@
12386+#include <linux/kernel.h>
12387+#include <linux/mm.h>
12388+#include <linux/slab.h>
12389+#include <linux/vmalloc.h>
12390+#include <linux/gracl.h>
12391+#include <linux/grsecurity.h>
12392+
12393+static unsigned long alloc_stack_next = 1;
12394+static unsigned long alloc_stack_size = 1;
12395+static void **alloc_stack;
12396+
12397+static __inline__ int
12398+alloc_pop(void)
12399+{
12400+ if (alloc_stack_next == 1)
12401+ return 0;
12402+
12403+ kfree(alloc_stack[alloc_stack_next - 2]);
12404+
12405+ alloc_stack_next--;
12406+
12407+ return 1;
12408+}
12409+
12410+static __inline__ void
12411+alloc_push(void *buf)
12412+{
12413+ if (alloc_stack_next >= alloc_stack_size)
12414+ BUG();
12415+
12416+ alloc_stack[alloc_stack_next - 1] = buf;
12417+
12418+ alloc_stack_next++;
12419+
12420+ return;
12421+}
12422+
12423+void *
12424+acl_alloc(unsigned long len)
12425+{
12426+ void *ret;
12427+
12428+ if (len > PAGE_SIZE)
12429+ BUG();
12430+
12431+ ret = kmalloc(len, GFP_KERNEL);
12432+
12433+ if (ret)
12434+ alloc_push(ret);
12435+
12436+ return ret;
12437+}
12438+
12439+void
12440+acl_free_all(void)
12441+{
12442+ if (gr_acl_is_enabled() || !alloc_stack)
12443+ return;
12444+
12445+ while (alloc_pop()) ;
12446+
12447+ if (alloc_stack) {
12448+ if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
12449+ kfree(alloc_stack);
12450+ else
12451+ vfree(alloc_stack);
12452+ }
12453+
12454+ alloc_stack = NULL;
12455+ alloc_stack_size = 1;
12456+ alloc_stack_next = 1;
12457+
12458+ return;
12459+}
12460+
12461+int
12462+acl_alloc_stack_init(unsigned long size)
12463+{
12464+ if ((size * sizeof (void *)) <= PAGE_SIZE)
12465+ alloc_stack =
12466+ (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
12467+ else
12468+ alloc_stack = (void **) vmalloc(size * sizeof (void *));
12469+
12470+ alloc_stack_size = size;
12471+
12472+ if (!alloc_stack)
12473+ return 0;
12474+ else
12475+ return 1;
12476+}
12477diff -urNp linux-2.6.19.1/grsecurity/gracl.c linux-2.6.19.1/grsecurity/gracl.c
12478--- linux-2.6.19.1/grsecurity/gracl.c 1969-12-31 19:00:00.000000000 -0500
12479+++ linux-2.6.19.1/grsecurity/gracl.c 2006-12-03 15:16:32.000000000 -0500
12480@@ -0,0 +1,3547 @@
12481+#include <linux/kernel.h>
12482+#include <linux/module.h>
12483+#include <linux/sched.h>
12484+#include <linux/mm.h>
12485+#include <linux/file.h>
12486+#include <linux/fs.h>
12487+#include <linux/namei.h>
12488+#include <linux/mount.h>
12489+#include <linux/tty.h>
12490+#include <linux/proc_fs.h>
12491+#include <linux/smp_lock.h>
12492+#include <linux/slab.h>
12493+#include <linux/vmalloc.h>
12494+#include <linux/types.h>
12495+#include <linux/capability.h>
12496+#include <linux/sysctl.h>
12497+#include <linux/netdevice.h>
12498+#include <linux/ptrace.h>
12499+#include <linux/gracl.h>
12500+#include <linux/gralloc.h>
12501+#include <linux/grsecurity.h>
12502+#include <linux/grinternal.h>
12503+#include <linux/percpu.h>
12504+
12505+#include <asm/uaccess.h>
12506+#include <asm/errno.h>
12507+#include <asm/mman.h>
12508+
12509+static struct acl_role_db acl_role_set;
12510+static struct name_db name_set;
12511+static struct inodev_db inodev_set;
12512+
12513+/* for keeping track of userspace pointers used for subjects, so we
12514+ can share references in the kernel as well
12515+*/
12516+
12517+static struct dentry *real_root;
12518+static struct vfsmount *real_root_mnt;
12519+
12520+static struct acl_subj_map_db subj_map_set;
12521+
12522+static struct acl_role_label *default_role;
12523+
12524+static u16 acl_sp_role_value;
12525+
12526+extern char *gr_shared_page[4];
12527+static DECLARE_MUTEX(gr_dev_sem);
12528+rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
12529+
12530+struct gr_arg *gr_usermode;
12531+
12532+static unsigned int gr_status = GR_STATUS_INIT;
12533+
12534+extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
12535+extern void gr_clear_learn_entries(void);
12536+
12537+#ifdef CONFIG_GRKERNSEC_RESLOG
12538+extern void gr_log_resource(const struct task_struct *task,
12539+ const int res, const unsigned long wanted, const int gt);
12540+#endif
12541+
12542+extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
12543+ struct dentry *root, struct vfsmount *rootmnt,
12544+ char *buffer, int buflen);
12545+
12546+unsigned char *gr_system_salt;
12547+unsigned char *gr_system_sum;
12548+
12549+static struct sprole_pw **acl_special_roles = NULL;
12550+static __u16 num_sprole_pws = 0;
12551+
12552+static struct acl_role_label *kernel_role = NULL;
12553+
12554+static unsigned int gr_auth_attempts = 0;
12555+static unsigned long gr_auth_expires = 0UL;
12556+
12557+extern struct vfsmount *sock_mnt;
12558+extern struct vfsmount *pipe_mnt;
12559+extern struct vfsmount *shm_mnt;
12560+static struct acl_object_label *fakefs_obj;
12561+
12562+extern int gr_init_uidset(void);
12563+extern void gr_free_uidset(void);
12564+extern void gr_remove_uid(uid_t uid);
12565+extern int gr_find_uid(uid_t uid);
12566+
12567+__inline__ int
12568+gr_acl_is_enabled(void)
12569+{
12570+ return (gr_status & GR_READY);
12571+}
12572+
12573+char gr_roletype_to_char(void)
12574+{
12575+ switch (current->role->roletype &
12576+ (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
12577+ GR_ROLE_SPECIAL)) {
12578+ case GR_ROLE_DEFAULT:
12579+ return 'D';
12580+ case GR_ROLE_USER:
12581+ return 'U';
12582+ case GR_ROLE_GROUP:
12583+ return 'G';
12584+ case GR_ROLE_SPECIAL:
12585+ return 'S';
12586+ }
12587+
12588+ return 'X';
12589+}
12590+
12591+__inline__ int
12592+gr_acl_tpe_check(void)
12593+{
12594+ if (unlikely(!(gr_status & GR_READY)))
12595+ return 0;
12596+ if (current->role->roletype & GR_ROLE_TPE)
12597+ return 1;
12598+ else
12599+ return 0;
12600+}
12601+
12602+int
12603+gr_handle_rawio(const struct inode *inode)
12604+{
12605+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
12606+ if (inode && S_ISBLK(inode->i_mode) &&
12607+ grsec_enable_chroot_caps && proc_is_chrooted(current) &&
12608+ !capable(CAP_SYS_RAWIO))
12609+ return 1;
12610+#endif
12611+ return 0;
12612+}
12613+
12614+static int
12615+gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
12616+{
12617+ int i;
12618+ unsigned long *l1;
12619+ unsigned long *l2;
12620+ unsigned char *c1;
12621+ unsigned char *c2;
12622+ int num_longs;
12623+
12624+ if (likely(lena != lenb))
12625+ return 0;
12626+
12627+ l1 = (unsigned long *)a;
12628+ l2 = (unsigned long *)b;
12629+
12630+ num_longs = lena / sizeof(unsigned long);
12631+
12632+ for (i = num_longs; i--; l1++, l2++) {
12633+ if (unlikely(*l1 != *l2))
12634+ return 0;
12635+ }
12636+
12637+ c1 = (unsigned char *) l1;
12638+ c2 = (unsigned char *) l2;
12639+
12640+ i = lena - (num_longs * sizeof(unsigned long));
12641+
12642+ for (; i--; c1++, c2++) {
12643+ if (unlikely(*c1 != *c2))
12644+ return 0;
12645+ }
12646+
12647+ return 1;
12648+}
12649+
12650+static char *
12651+gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
12652+ struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
12653+{
12654+ char *end = buf + buflen;
12655+ char *retval;
12656+ int namelen = 0;
12657+
12658+ *--end = '\0';
12659+
12660+ retval = end - 1;
12661+ *retval = '/';
12662+
12663+ if (dentry == root && vfsmnt == rootmnt)
12664+ return retval;
12665+ if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
12666+ namelen = strlen(dentry->d_name.name);
12667+ buflen -= namelen;
12668+ if (buflen < 2)
12669+ goto err;
12670+ if (dentry->d_parent != root || vfsmnt != rootmnt)
12671+ buflen--;
12672+ }
12673+
12674+ retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
12675+ if (unlikely(IS_ERR(retval)))
12676+err:
12677+ retval = strcpy(buf, "<path too long>");
12678+ else if (namelen != 0) {
12679+ end = buf + buflen - 1; // accounts for null termination
12680+ if (dentry->d_parent != root || vfsmnt != rootmnt)
12681+ *end++ = '/'; // accounted for above with buflen--
12682+ memcpy(end, dentry->d_name.name, namelen);
12683+ }
12684+
12685+ return retval;
12686+}
12687+
12688+static char *
12689+__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
12690+ char *buf, int buflen)
12691+{
12692+ char *res;
12693+
12694+ /* we can use real_root, real_root_mnt, because this is only called
12695+ by the RBAC system */
12696+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
12697+
12698+ return res;
12699+}
12700+
12701+static char *
12702+d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
12703+ char *buf, int buflen)
12704+{
12705+ char *res;
12706+ struct dentry *root;
12707+ struct vfsmount *rootmnt;
12708+
12709+ /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
12710+ read_lock(&child_reaper->fs->lock);
12711+ root = dget(child_reaper->fs->root);
12712+ rootmnt = mntget(child_reaper->fs->rootmnt);
12713+ read_unlock(&child_reaper->fs->lock);
12714+
12715+ spin_lock(&dcache_lock);
12716+ res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
12717+ spin_unlock(&dcache_lock);
12718+
12719+ dput(root);
12720+ mntput(rootmnt);
12721+ return res;
12722+}
12723+
12724+static char *
12725+gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
12726+{
12727+ char *ret;
12728+ spin_lock(&dcache_lock);
12729+ ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
12730+ PAGE_SIZE);
12731+ spin_unlock(&dcache_lock);
12732+ return ret;
12733+}
12734+
12735+char *
12736+gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
12737+{
12738+ return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
12739+ PAGE_SIZE);
12740+}
12741+
12742+char *
12743+gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
12744+{
12745+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
12746+ PAGE_SIZE);
12747+}
12748+
12749+char *
12750+gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
12751+{
12752+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
12753+ PAGE_SIZE);
12754+}
12755+
12756+char *
12757+gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
12758+{
12759+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
12760+ PAGE_SIZE);
12761+}
12762+
12763+char *
12764+gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
12765+{
12766+ return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
12767+ PAGE_SIZE);
12768+}
12769+
12770+__inline__ __u32
12771+to_gr_audit(const __u32 reqmode)
12772+{
12773+ /* masks off auditable permission flags, then shifts them to create
12774+ auditing flags, and adds the special case of append auditing if
12775+ we're requesting write */
12776+ return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
12777+}
12778+
12779+struct acl_subject_label *
12780+lookup_subject_map(const struct acl_subject_label *userp)
12781+{
12782+ unsigned int index = shash(userp, subj_map_set.s_size);
12783+ struct subject_map *match;
12784+
12785+ match = subj_map_set.s_hash[index];
12786+
12787+ while (match && match->user != userp)
12788+ match = match->next;
12789+
12790+ if (match != NULL)
12791+ return match->kernel;
12792+ else
12793+ return NULL;
12794+}
12795+
12796+static void
12797+insert_subj_map_entry(struct subject_map *subjmap)
12798+{
12799+ unsigned int index = shash(subjmap->user, subj_map_set.s_size);
12800+ struct subject_map **curr;
12801+
12802+ subjmap->prev = NULL;
12803+
12804+ curr = &subj_map_set.s_hash[index];
12805+ if (*curr != NULL)
12806+ (*curr)->prev = subjmap;
12807+
12808+ subjmap->next = *curr;
12809+ *curr = subjmap;
12810+
12811+ return;
12812+}
12813+
12814+static struct acl_role_label *
12815+lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
12816+ const gid_t gid)
12817+{
12818+ unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
12819+ struct acl_role_label *match;
12820+ struct role_allowed_ip *ipp;
12821+ unsigned int x;
12822+
12823+ match = acl_role_set.r_hash[index];
12824+
12825+ while (match) {
12826+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
12827+ for (x = 0; x < match->domain_child_num; x++) {
12828+ if (match->domain_children[x] == uid)
12829+ goto found;
12830+ }
12831+ } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
12832+ break;
12833+ match = match->next;
12834+ }
12835+found:
12836+ if (match == NULL) {
12837+ try_group:
12838+ index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
12839+ match = acl_role_set.r_hash[index];
12840+
12841+ while (match) {
12842+ if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
12843+ for (x = 0; x < match->domain_child_num; x++) {
12844+ if (match->domain_children[x] == gid)
12845+ goto found2;
12846+ }
12847+ } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
12848+ break;
12849+ match = match->next;
12850+ }
12851+found2:
12852+ if (match == NULL)
12853+ match = default_role;
12854+ if (match->allowed_ips == NULL)
12855+ return match;
12856+ else {
12857+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
12858+ if (likely
12859+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
12860+ (ntohl(ipp->addr) & ipp->netmask)))
12861+ return match;
12862+ }
12863+ match = default_role;
12864+ }
12865+ } else if (match->allowed_ips == NULL) {
12866+ return match;
12867+ } else {
12868+ for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
12869+ if (likely
12870+ ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
12871+ (ntohl(ipp->addr) & ipp->netmask)))
12872+ return match;
12873+ }
12874+ goto try_group;
12875+ }
12876+
12877+ return match;
12878+}
12879+
12880+struct acl_subject_label *
12881+lookup_acl_subj_label(const ino_t ino, const dev_t dev,
12882+ const struct acl_role_label *role)
12883+{
12884+ unsigned int index = fhash(ino, dev, role->subj_hash_size);
12885+ struct acl_subject_label *match;
12886+
12887+ match = role->subj_hash[index];
12888+
12889+ while (match && (match->inode != ino || match->device != dev ||
12890+ (match->mode & GR_DELETED))) {
12891+ match = match->next;
12892+ }
12893+
12894+ if (match && !(match->mode & GR_DELETED))
12895+ return match;
12896+ else
12897+ return NULL;
12898+}
12899+
12900+static struct acl_object_label *
12901+lookup_acl_obj_label(const ino_t ino, const dev_t dev,
12902+ const struct acl_subject_label *subj)
12903+{
12904+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
12905+ struct acl_object_label *match;
12906+
12907+ match = subj->obj_hash[index];
12908+
12909+ while (match && (match->inode != ino || match->device != dev ||
12910+ (match->mode & GR_DELETED))) {
12911+ match = match->next;
12912+ }
12913+
12914+ if (match && !(match->mode & GR_DELETED))
12915+ return match;
12916+ else
12917+ return NULL;
12918+}
12919+
12920+static struct acl_object_label *
12921+lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
12922+ const struct acl_subject_label *subj)
12923+{
12924+ unsigned int index = fhash(ino, dev, subj->obj_hash_size);
12925+ struct acl_object_label *match;
12926+
12927+ match = subj->obj_hash[index];
12928+
12929+ while (match && (match->inode != ino || match->device != dev ||
12930+ !(match->mode & GR_DELETED))) {
12931+ match = match->next;
12932+ }
12933+
12934+ if (match && (match->mode & GR_DELETED))
12935+ return match;
12936+
12937+ match = subj->obj_hash[index];
12938+
12939+ while (match && (match->inode != ino || match->device != dev ||
12940+ (match->mode & GR_DELETED))) {
12941+ match = match->next;
12942+ }
12943+
12944+ if (match && !(match->mode & GR_DELETED))
12945+ return match;
12946+ else
12947+ return NULL;
12948+}
12949+
12950+static struct name_entry *
12951+lookup_name_entry(const char *name)
12952+{
12953+ unsigned int len = strlen(name);
12954+ unsigned int key = full_name_hash(name, len);
12955+ unsigned int index = key % name_set.n_size;
12956+ struct name_entry *match;
12957+
12958+ match = name_set.n_hash[index];
12959+
12960+ while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
12961+ match = match->next;
12962+
12963+ return match;
12964+}
12965+
12966+static struct inodev_entry *
12967+lookup_inodev_entry(const ino_t ino, const dev_t dev)
12968+{
12969+ unsigned int index = fhash(ino, dev, inodev_set.i_size);
12970+ struct inodev_entry *match;
12971+
12972+ match = inodev_set.i_hash[index];
12973+
12974+ while (match && (match->nentry->inode != ino || match->nentry->device != dev))
12975+ match = match->next;
12976+
12977+ return match;
12978+}
12979+
12980+static void
12981+insert_inodev_entry(struct inodev_entry *entry)
12982+{
12983+ unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
12984+ inodev_set.i_size);
12985+ struct inodev_entry **curr;
12986+
12987+ entry->prev = NULL;
12988+
12989+ curr = &inodev_set.i_hash[index];
12990+ if (*curr != NULL)
12991+ (*curr)->prev = entry;
12992+
12993+ entry->next = *curr;
12994+ *curr = entry;
12995+
12996+ return;
12997+}
12998+
12999+static void
13000+__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
13001+{
13002+ unsigned int index =
13003+ rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
13004+ struct acl_role_label **curr;
13005+
13006+ role->prev = NULL;
13007+
13008+ curr = &acl_role_set.r_hash[index];
13009+ if (*curr != NULL)
13010+ (*curr)->prev = role;
13011+
13012+ role->next = *curr;
13013+ *curr = role;
13014+
13015+ return;
13016+}
13017+
13018+static void
13019+insert_acl_role_label(struct acl_role_label *role)
13020+{
13021+ int i;
13022+
13023+ if (role->roletype & GR_ROLE_DOMAIN) {
13024+ for (i = 0; i < role->domain_child_num; i++)
13025+ __insert_acl_role_label(role, role->domain_children[i]);
13026+ } else
13027+ __insert_acl_role_label(role, role->uidgid);
13028+}
13029+
13030+static int
13031+insert_name_entry(char *name, const ino_t inode, const dev_t device)
13032+{
13033+ struct name_entry **curr, *nentry;
13034+ struct inodev_entry *ientry;
13035+ unsigned int len = strlen(name);
13036+ unsigned int key = full_name_hash(name, len);
13037+ unsigned int index = key % name_set.n_size;
13038+
13039+ curr = &name_set.n_hash[index];
13040+
13041+ while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
13042+ curr = &((*curr)->next);
13043+
13044+ if (*curr != NULL)
13045+ return 1;
13046+
13047+ nentry = acl_alloc(sizeof (struct name_entry));
13048+ if (nentry == NULL)
13049+ return 0;
13050+ ientry = acl_alloc(sizeof (struct inodev_entry));
13051+ if (ientry == NULL)
13052+ return 0;
13053+ ientry->nentry = nentry;
13054+
13055+ nentry->key = key;
13056+ nentry->name = name;
13057+ nentry->inode = inode;
13058+ nentry->device = device;
13059+ nentry->len = len;
13060+
13061+ nentry->prev = NULL;
13062+ curr = &name_set.n_hash[index];
13063+ if (*curr != NULL)
13064+ (*curr)->prev = nentry;
13065+ nentry->next = *curr;
13066+ *curr = nentry;
13067+
13068+ /* insert us into the table searchable by inode/dev */
13069+ insert_inodev_entry(ientry);
13070+
13071+ return 1;
13072+}
13073+
13074+static void
13075+insert_acl_obj_label(struct acl_object_label *obj,
13076+ struct acl_subject_label *subj)
13077+{
13078+ unsigned int index =
13079+ fhash(obj->inode, obj->device, subj->obj_hash_size);
13080+ struct acl_object_label **curr;
13081+
13082+
13083+ obj->prev = NULL;
13084+
13085+ curr = &subj->obj_hash[index];
13086+ if (*curr != NULL)
13087+ (*curr)->prev = obj;
13088+
13089+ obj->next = *curr;
13090+ *curr = obj;
13091+
13092+ return;
13093+}
13094+
13095+static void
13096+insert_acl_subj_label(struct acl_subject_label *obj,
13097+ struct acl_role_label *role)
13098+{
13099+ unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
13100+ struct acl_subject_label **curr;
13101+
13102+ obj->prev = NULL;
13103+
13104+ curr = &role->subj_hash[index];
13105+ if (*curr != NULL)
13106+ (*curr)->prev = obj;
13107+
13108+ obj->next = *curr;
13109+ *curr = obj;
13110+
13111+ return;
13112+}
13113+
13114+/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
13115+
13116+static void *
13117+create_table(__u32 * len, int elementsize)
13118+{
13119+ unsigned int table_sizes[] = {
13120+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
13121+ 32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
13122+ 4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
13123+ 268435399, 536870909, 1073741789, 2147483647
13124+ };
13125+ void *newtable = NULL;
13126+ unsigned int pwr = 0;
13127+
13128+ while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
13129+ table_sizes[pwr] <= *len)
13130+ pwr++;
13131+
13132+ if (table_sizes[pwr] <= *len)
13133+ return newtable;
13134+
13135+ if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
13136+ newtable =
13137+ kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
13138+ else
13139+ newtable = vmalloc(table_sizes[pwr] * elementsize);
13140+
13141+ *len = table_sizes[pwr];
13142+
13143+ return newtable;
13144+}
13145+
13146+static int
13147+init_variables(const struct gr_arg *arg)
13148+{
13149+ unsigned int stacksize;
13150+
13151+ subj_map_set.s_size = arg->role_db.num_subjects;
13152+ acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
13153+ name_set.n_size = arg->role_db.num_objects;
13154+ inodev_set.i_size = arg->role_db.num_objects;
13155+
13156+ if (!subj_map_set.s_size || !acl_role_set.r_size ||
13157+ !name_set.n_size || !inodev_set.i_size)
13158+ return 1;
13159+
13160+ if (!gr_init_uidset())
13161+ return 1;
13162+
13163+ /* set up the stack that holds allocation info */
13164+
13165+ stacksize = arg->role_db.num_pointers + 5;
13166+
13167+ if (!acl_alloc_stack_init(stacksize))
13168+ return 1;
13169+
13170+ /* grab reference for the real root dentry and vfsmount */
13171+ read_lock(&child_reaper->fs->lock);
13172+ real_root_mnt = mntget(child_reaper->fs->rootmnt);
13173+ real_root = dget(child_reaper->fs->root);
13174+ read_unlock(&child_reaper->fs->lock);
13175+
13176+ fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
13177+ if (fakefs_obj == NULL)
13178+ return 1;
13179+ fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
13180+
13181+ subj_map_set.s_hash =
13182+ (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
13183+ acl_role_set.r_hash =
13184+ (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
13185+ name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
13186+ inodev_set.i_hash =
13187+ (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
13188+
13189+ if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
13190+ !name_set.n_hash || !inodev_set.i_hash)
13191+ return 1;
13192+
13193+ memset(subj_map_set.s_hash, 0,
13194+ sizeof(struct subject_map *) * subj_map_set.s_size);
13195+ memset(acl_role_set.r_hash, 0,
13196+ sizeof (struct acl_role_label *) * acl_role_set.r_size);
13197+ memset(name_set.n_hash, 0,
13198+ sizeof (struct name_entry *) * name_set.n_size);
13199+ memset(inodev_set.i_hash, 0,
13200+ sizeof (struct inodev_entry *) * inodev_set.i_size);
13201+
13202+ return 0;
13203+}
13204+
13205+/* free information not needed after startup
13206+ currently contains user->kernel pointer mappings for subjects
13207+*/
13208+
13209+static void
13210+free_init_variables(void)
13211+{
13212+ __u32 i;
13213+
13214+ if (subj_map_set.s_hash) {
13215+ for (i = 0; i < subj_map_set.s_size; i++) {
13216+ if (subj_map_set.s_hash[i]) {
13217+ kfree(subj_map_set.s_hash[i]);
13218+ subj_map_set.s_hash[i] = NULL;
13219+ }
13220+ }
13221+
13222+ if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
13223+ PAGE_SIZE)
13224+ kfree(subj_map_set.s_hash);
13225+ else
13226+ vfree(subj_map_set.s_hash);
13227+ }
13228+
13229+ return;
13230+}
13231+
13232+static void
13233+free_variables(void)
13234+{
13235+ struct acl_subject_label *s;
13236+ struct acl_role_label *r;
13237+ struct task_struct *task, *task2;
13238+ unsigned int i, x;
13239+
13240+ gr_clear_learn_entries();
13241+
13242+ read_lock(&tasklist_lock);
13243+ do_each_thread(task2, task) {
13244+ task->acl_sp_role = 0;
13245+ task->acl_role_id = 0;
13246+ task->acl = NULL;
13247+ task->role = NULL;
13248+ } while_each_thread(task2, task);
13249+ read_unlock(&tasklist_lock);
13250+
13251+ /* release the reference to the real root dentry and vfsmount */
13252+ if (real_root)
13253+ dput(real_root);
13254+ real_root = NULL;
13255+ if (real_root_mnt)
13256+ mntput(real_root_mnt);
13257+ real_root_mnt = NULL;
13258+
13259+ /* free all object hash tables */
13260+
13261+ FOR_EACH_ROLE_START(r, i)
13262+ if (r->subj_hash == NULL)
13263+ break;
13264+ FOR_EACH_SUBJECT_START(r, s, x)
13265+ if (s->obj_hash == NULL)
13266+ break;
13267+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
13268+ kfree(s->obj_hash);
13269+ else
13270+ vfree(s->obj_hash);
13271+ FOR_EACH_SUBJECT_END(s, x)
13272+ FOR_EACH_NESTED_SUBJECT_START(r, s)
13273+ if (s->obj_hash == NULL)
13274+ break;
13275+ if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
13276+ kfree(s->obj_hash);
13277+ else
13278+ vfree(s->obj_hash);
13279+ FOR_EACH_NESTED_SUBJECT_END(s)
13280+ if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
13281+ kfree(r->subj_hash);
13282+ else
13283+ vfree(r->subj_hash);
13284+ r->subj_hash = NULL;
13285+ FOR_EACH_ROLE_END(r,i)
13286+
13287+ acl_free_all();
13288+
13289+ if (acl_role_set.r_hash) {
13290+ if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
13291+ PAGE_SIZE)
13292+ kfree(acl_role_set.r_hash);
13293+ else
13294+ vfree(acl_role_set.r_hash);
13295+ }
13296+ if (name_set.n_hash) {
13297+ if ((name_set.n_size * sizeof (struct name_entry *)) <=
13298+ PAGE_SIZE)
13299+ kfree(name_set.n_hash);
13300+ else
13301+ vfree(name_set.n_hash);
13302+ }
13303+
13304+ if (inodev_set.i_hash) {
13305+ if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
13306+ PAGE_SIZE)
13307+ kfree(inodev_set.i_hash);
13308+ else
13309+ vfree(inodev_set.i_hash);
13310+ }
13311+
13312+ gr_free_uidset();
13313+
13314+ memset(&name_set, 0, sizeof (struct name_db));
13315+ memset(&inodev_set, 0, sizeof (struct inodev_db));
13316+ memset(&acl_role_set, 0, sizeof (struct acl_role_db));
13317+ memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
13318+
13319+ default_role = NULL;
13320+
13321+ return;
13322+}
13323+
13324+static __u32
13325+count_user_objs(struct acl_object_label *userp)
13326+{
13327+ struct acl_object_label o_tmp;
13328+ __u32 num = 0;
13329+
13330+ while (userp) {
13331+ if (copy_from_user(&o_tmp, userp,
13332+ sizeof (struct acl_object_label)))
13333+ break;
13334+
13335+ userp = o_tmp.prev;
13336+ num++;
13337+ }
13338+
13339+ return num;
13340+}
13341+
13342+static struct acl_subject_label *
13343+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
13344+
13345+static int
13346+copy_user_glob(struct acl_object_label *obj)
13347+{
13348+ struct acl_object_label *g_tmp, **guser;
13349+ unsigned int len;
13350+ char *tmp;
13351+
13352+ if (obj->globbed == NULL)
13353+ return 0;
13354+
13355+ guser = &obj->globbed;
13356+ while (*guser) {
13357+ g_tmp = (struct acl_object_label *)
13358+ acl_alloc(sizeof (struct acl_object_label));
13359+ if (g_tmp == NULL)
13360+ return -ENOMEM;
13361+
13362+ if (copy_from_user(g_tmp, *guser,
13363+ sizeof (struct acl_object_label)))
13364+ return -EFAULT;
13365+
13366+ len = strnlen_user(g_tmp->filename, PATH_MAX);
13367+
13368+ if (!len || len >= PATH_MAX)
13369+ return -EINVAL;
13370+
13371+ if ((tmp = (char *) acl_alloc(len)) == NULL)
13372+ return -ENOMEM;
13373+
13374+ if (copy_from_user(tmp, g_tmp->filename, len))
13375+ return -EFAULT;
13376+
13377+ g_tmp->filename = tmp;
13378+
13379+ *guser = g_tmp;
13380+ guser = &(g_tmp->next);
13381+ }
13382+
13383+ return 0;
13384+}
13385+
13386+static int
13387+copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
13388+ struct acl_role_label *role)
13389+{
13390+ struct acl_object_label *o_tmp;
13391+ unsigned int len;
13392+ int ret;
13393+ char *tmp;
13394+
13395+ while (userp) {
13396+ if ((o_tmp = (struct acl_object_label *)
13397+ acl_alloc(sizeof (struct acl_object_label))) == NULL)
13398+ return -ENOMEM;
13399+
13400+ if (copy_from_user(o_tmp, userp,
13401+ sizeof (struct acl_object_label)))
13402+ return -EFAULT;
13403+
13404+ userp = o_tmp->prev;
13405+
13406+ len = strnlen_user(o_tmp->filename, PATH_MAX);
13407+
13408+ if (!len || len >= PATH_MAX)
13409+ return -EINVAL;
13410+
13411+ if ((tmp = (char *) acl_alloc(len)) == NULL)
13412+ return -ENOMEM;
13413+
13414+ if (copy_from_user(tmp, o_tmp->filename, len))
13415+ return -EFAULT;
13416+
13417+ o_tmp->filename = tmp;
13418+
13419+ insert_acl_obj_label(o_tmp, subj);
13420+ if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
13421+ o_tmp->device))
13422+ return -ENOMEM;
13423+
13424+ ret = copy_user_glob(o_tmp);
13425+ if (ret)
13426+ return ret;
13427+
13428+ if (o_tmp->nested) {
13429+ o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
13430+ if (IS_ERR(o_tmp->nested))
13431+ return PTR_ERR(o_tmp->nested);
13432+
13433+ /* insert into nested subject list */
13434+ o_tmp->nested->next = role->hash->first;
13435+ role->hash->first = o_tmp->nested;
13436+ }
13437+ }
13438+
13439+ return 0;
13440+}
13441+
13442+static __u32
13443+count_user_subjs(struct acl_subject_label *userp)
13444+{
13445+ struct acl_subject_label s_tmp;
13446+ __u32 num = 0;
13447+
13448+ while (userp) {
13449+ if (copy_from_user(&s_tmp, userp,
13450+ sizeof (struct acl_subject_label)))
13451+ break;
13452+
13453+ userp = s_tmp.prev;
13454+ /* do not count nested subjects against this count, since
13455+ they are not included in the hash table, but are
13456+ attached to objects. We have already counted
13457+ the subjects in userspace for the allocation
13458+ stack
13459+ */
13460+ if (!(s_tmp.mode & GR_NESTED))
13461+ num++;
13462+ }
13463+
13464+ return num;
13465+}
13466+
13467+static int
13468+copy_user_allowedips(struct acl_role_label *rolep)
13469+{
13470+ struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
13471+
13472+ ruserip = rolep->allowed_ips;
13473+
13474+ while (ruserip) {
13475+ rlast = rtmp;
13476+
13477+ if ((rtmp = (struct role_allowed_ip *)
13478+ acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
13479+ return -ENOMEM;
13480+
13481+ if (copy_from_user(rtmp, ruserip,
13482+ sizeof (struct role_allowed_ip)))
13483+ return -EFAULT;
13484+
13485+ ruserip = rtmp->prev;
13486+
13487+ if (!rlast) {
13488+ rtmp->prev = NULL;
13489+ rolep->allowed_ips = rtmp;
13490+ } else {
13491+ rlast->next = rtmp;
13492+ rtmp->prev = rlast;
13493+ }
13494+
13495+ if (!ruserip)
13496+ rtmp->next = NULL;
13497+ }
13498+
13499+ return 0;
13500+}
13501+
13502+static int
13503+copy_user_transitions(struct acl_role_label *rolep)
13504+{
13505+ struct role_transition *rusertp, *rtmp = NULL, *rlast;
13506+
13507+ unsigned int len;
13508+ char *tmp;
13509+
13510+ rusertp = rolep->transitions;
13511+
13512+ while (rusertp) {
13513+ rlast = rtmp;
13514+
13515+ if ((rtmp = (struct role_transition *)
13516+ acl_alloc(sizeof (struct role_transition))) == NULL)
13517+ return -ENOMEM;
13518+
13519+ if (copy_from_user(rtmp, rusertp,
13520+ sizeof (struct role_transition)))
13521+ return -EFAULT;
13522+
13523+ rusertp = rtmp->prev;
13524+
13525+ len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
13526+
13527+ if (!len || len >= GR_SPROLE_LEN)
13528+ return -EINVAL;
13529+
13530+ if ((tmp = (char *) acl_alloc(len)) == NULL)
13531+ return -ENOMEM;
13532+
13533+ if (copy_from_user(tmp, rtmp->rolename, len))
13534+ return -EFAULT;
13535+
13536+ rtmp->rolename = tmp;
13537+
13538+ if (!rlast) {
13539+ rtmp->prev = NULL;
13540+ rolep->transitions = rtmp;
13541+ } else {
13542+ rlast->next = rtmp;
13543+ rtmp->prev = rlast;
13544+ }
13545+
13546+ if (!rusertp)
13547+ rtmp->next = NULL;
13548+ }
13549+
13550+ return 0;
13551+}
13552+
13553+static struct acl_subject_label *
13554+do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
13555+{
13556+ struct acl_subject_label *s_tmp = NULL, *s_tmp2;
13557+ unsigned int len;
13558+ char *tmp;
13559+ __u32 num_objs;
13560+ struct acl_ip_label **i_tmp, *i_utmp2;
13561+ struct gr_hash_struct ghash;
13562+ struct subject_map *subjmap;
13563+ unsigned int i_num;
13564+ int err;
13565+
13566+ s_tmp = lookup_subject_map(userp);
13567+
13568+ /* we've already copied this subject into the kernel, just return
13569+ the reference to it, and don't copy it over again
13570+ */
13571+ if (s_tmp)
13572+ return(s_tmp);
13573+
13574+ if ((s_tmp = (struct acl_subject_label *)
13575+ acl_alloc(sizeof (struct acl_subject_label))) == NULL)
13576+ return ERR_PTR(-ENOMEM);
13577+
13578+ subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
13579+ if (subjmap == NULL)
13580+ return ERR_PTR(-ENOMEM);
13581+
13582+ subjmap->user = userp;
13583+ subjmap->kernel = s_tmp;
13584+ insert_subj_map_entry(subjmap);
13585+
13586+ if (copy_from_user(s_tmp, userp,
13587+ sizeof (struct acl_subject_label)))
13588+ return ERR_PTR(-EFAULT);
13589+
13590+ len = strnlen_user(s_tmp->filename, PATH_MAX);
13591+
13592+ if (!len || len >= PATH_MAX)
13593+ return ERR_PTR(-EINVAL);
13594+
13595+ if ((tmp = (char *) acl_alloc(len)) == NULL)
13596+ return ERR_PTR(-ENOMEM);
13597+
13598+ if (copy_from_user(tmp, s_tmp->filename, len))
13599+ return ERR_PTR(-EFAULT);
13600+
13601+ s_tmp->filename = tmp;
13602+
13603+ if (!strcmp(s_tmp->filename, "/"))
13604+ role->root_label = s_tmp;
13605+
13606+ if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
13607+ return ERR_PTR(-EFAULT);
13608+
13609+ /* copy user and group transition tables */
13610+
13611+ if (s_tmp->user_trans_num) {
13612+ uid_t *uidlist;
13613+
13614+ uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
13615+ if (uidlist == NULL)
13616+ return ERR_PTR(-ENOMEM);
13617+ if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
13618+ return ERR_PTR(-EFAULT);
13619+
13620+ s_tmp->user_transitions = uidlist;
13621+ }
13622+
13623+ if (s_tmp->group_trans_num) {
13624+ gid_t *gidlist;
13625+
13626+ gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
13627+ if (gidlist == NULL)
13628+ return ERR_PTR(-ENOMEM);
13629+ if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
13630+ return ERR_PTR(-EFAULT);
13631+
13632+ s_tmp->group_transitions = gidlist;
13633+ }
13634+
13635+ /* set up object hash table */
13636+ num_objs = count_user_objs(ghash.first);
13637+
13638+ s_tmp->obj_hash_size = num_objs;
13639+ s_tmp->obj_hash =
13640+ (struct acl_object_label **)
13641+ create_table(&(s_tmp->obj_hash_size), sizeof(void *));
13642+
13643+ if (!s_tmp->obj_hash)
13644+ return ERR_PTR(-ENOMEM);
13645+
13646+ memset(s_tmp->obj_hash, 0,
13647+ s_tmp->obj_hash_size *
13648+ sizeof (struct acl_object_label *));
13649+
13650+ /* add in objects */
13651+ err = copy_user_objs(ghash.first, s_tmp, role);
13652+
13653+ if (err)
13654+ return ERR_PTR(err);
13655+
13656+ /* set pointer for parent subject */
13657+ if (s_tmp->parent_subject) {
13658+ s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
13659+
13660+ if (IS_ERR(s_tmp2))
13661+ return s_tmp2;
13662+
13663+ s_tmp->parent_subject = s_tmp2;
13664+ }
13665+
13666+ /* add in ip acls */
13667+
13668+ if (!s_tmp->ip_num) {
13669+ s_tmp->ips = NULL;
13670+ goto insert;
13671+ }
13672+
13673+ i_tmp =
13674+ (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
13675+ sizeof (struct
13676+ acl_ip_label *));
13677+
13678+ if (!i_tmp)
13679+ return ERR_PTR(-ENOMEM);
13680+
13681+ for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
13682+ *(i_tmp + i_num) =
13683+ (struct acl_ip_label *)
13684+ acl_alloc(sizeof (struct acl_ip_label));
13685+ if (!*(i_tmp + i_num))
13686+ return ERR_PTR(-ENOMEM);
13687+
13688+ if (copy_from_user
13689+ (&i_utmp2, s_tmp->ips + i_num,
13690+ sizeof (struct acl_ip_label *)))
13691+ return ERR_PTR(-EFAULT);
13692+
13693+ if (copy_from_user
13694+ (*(i_tmp + i_num), i_utmp2,
13695+ sizeof (struct acl_ip_label)))
13696+ return ERR_PTR(-EFAULT);
13697+
13698+ if ((*(i_tmp + i_num))->iface == NULL)
13699+ continue;
13700+
13701+ len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
13702+ if (!len || len >= IFNAMSIZ)
13703+ return ERR_PTR(-EINVAL);
13704+ tmp = acl_alloc(len);
13705+ if (tmp == NULL)
13706+ return ERR_PTR(-ENOMEM);
13707+ if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
13708+ return ERR_PTR(-EFAULT);
13709+ (*(i_tmp + i_num))->iface = tmp;
13710+ }
13711+
13712+ s_tmp->ips = i_tmp;
13713+
13714+insert:
13715+ if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
13716+ s_tmp->device))
13717+ return ERR_PTR(-ENOMEM);
13718+
13719+ return s_tmp;
13720+}
13721+
13722+static int
13723+copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
13724+{
13725+ struct acl_subject_label s_pre;
13726+ struct acl_subject_label * ret;
13727+ int err;
13728+
13729+ while (userp) {
13730+ if (copy_from_user(&s_pre, userp,
13731+ sizeof (struct acl_subject_label)))
13732+ return -EFAULT;
13733+
13734+ /* do not add nested subjects here, add
13735+ while parsing objects
13736+ */
13737+
13738+ if (s_pre.mode & GR_NESTED) {
13739+ userp = s_pre.prev;
13740+ continue;
13741+ }
13742+
13743+ ret = do_copy_user_subj(userp, role);
13744+
13745+ err = PTR_ERR(ret);
13746+ if (IS_ERR(ret))
13747+ return err;
13748+
13749+ insert_acl_subj_label(ret, role);
13750+
13751+ userp = s_pre.prev;
13752+ }
13753+
13754+ return 0;
13755+}
13756+
13757+static int
13758+copy_user_acl(struct gr_arg *arg)
13759+{
13760+ struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
13761+ struct sprole_pw *sptmp;
13762+ struct gr_hash_struct *ghash;
13763+ uid_t *domainlist;
13764+ unsigned int r_num;
13765+ unsigned int len;
13766+ char *tmp;
13767+ int err = 0;
13768+ __u16 i;
13769+ __u32 num_subjs;
13770+
13771+ /* we need a default and kernel role */
13772+ if (arg->role_db.num_roles < 2)
13773+ return -EINVAL;
13774+
13775+ /* copy special role authentication info from userspace */
13776+
13777+ num_sprole_pws = arg->num_sprole_pws;
13778+ acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
13779+
13780+ if (!acl_special_roles) {
13781+ err = -ENOMEM;
13782+ goto cleanup;
13783+ }
13784+
13785+ for (i = 0; i < num_sprole_pws; i++) {
13786+ sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
13787+ if (!sptmp) {
13788+ err = -ENOMEM;
13789+ goto cleanup;
13790+ }
13791+ if (copy_from_user(sptmp, arg->sprole_pws + i,
13792+ sizeof (struct sprole_pw))) {
13793+ err = -EFAULT;
13794+ goto cleanup;
13795+ }
13796+
13797+ len =
13798+ strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
13799+
13800+ if (!len || len >= GR_SPROLE_LEN) {
13801+ err = -EINVAL;
13802+ goto cleanup;
13803+ }
13804+
13805+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
13806+ err = -ENOMEM;
13807+ goto cleanup;
13808+ }
13809+
13810+ if (copy_from_user(tmp, sptmp->rolename, len)) {
13811+ err = -EFAULT;
13812+ goto cleanup;
13813+ }
13814+
13815+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
13816+ printk(KERN_ALERT "Copying special role %s\n", tmp);
13817+#endif
13818+ sptmp->rolename = tmp;
13819+ acl_special_roles[i] = sptmp;
13820+ }
13821+
13822+ r_utmp = (struct acl_role_label **) arg->role_db.r_table;
13823+
13824+ for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
13825+ r_tmp = acl_alloc(sizeof (struct acl_role_label));
13826+
13827+ if (!r_tmp) {
13828+ err = -ENOMEM;
13829+ goto cleanup;
13830+ }
13831+
13832+ if (copy_from_user(&r_utmp2, r_utmp + r_num,
13833+ sizeof (struct acl_role_label *))) {
13834+ err = -EFAULT;
13835+ goto cleanup;
13836+ }
13837+
13838+ if (copy_from_user(r_tmp, r_utmp2,
13839+ sizeof (struct acl_role_label))) {
13840+ err = -EFAULT;
13841+ goto cleanup;
13842+ }
13843+
13844+ len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
13845+
13846+ if (!len || len >= PATH_MAX) {
13847+ err = -EINVAL;
13848+ goto cleanup;
13849+ }
13850+
13851+ if ((tmp = (char *) acl_alloc(len)) == NULL) {
13852+ err = -ENOMEM;
13853+ goto cleanup;
13854+ }
13855+ if (copy_from_user(tmp, r_tmp->rolename, len)) {
13856+ err = -EFAULT;
13857+ goto cleanup;
13858+ }
13859+ r_tmp->rolename = tmp;
13860+
13861+ if (!strcmp(r_tmp->rolename, "default")
13862+ && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
13863+ default_role = r_tmp;
13864+ } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
13865+ kernel_role = r_tmp;
13866+ }
13867+
13868+ if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
13869+ err = -ENOMEM;
13870+ goto cleanup;
13871+ }
13872+ if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
13873+ err = -EFAULT;
13874+ goto cleanup;
13875+ }
13876+
13877+ r_tmp->hash = ghash;
13878+
13879+ num_subjs = count_user_subjs(r_tmp->hash->first);
13880+
13881+ r_tmp->subj_hash_size = num_subjs;
13882+ r_tmp->subj_hash =
13883+ (struct acl_subject_label **)
13884+ create_table(&(r_tmp->subj_hash_size), sizeof(void *));
13885+
13886+ if (!r_tmp->subj_hash) {
13887+ err = -ENOMEM;
13888+ goto cleanup;
13889+ }
13890+
13891+ err = copy_user_allowedips(r_tmp);
13892+ if (err)
13893+ goto cleanup;
13894+
13895+ /* copy domain info */
13896+ if (r_tmp->domain_children != NULL) {
13897+ domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
13898+ if (domainlist == NULL) {
13899+ err = -ENOMEM;
13900+ goto cleanup;
13901+ }
13902+ if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
13903+ err = -EFAULT;
13904+ goto cleanup;
13905+ }
13906+ r_tmp->domain_children = domainlist;
13907+ }
13908+
13909+ err = copy_user_transitions(r_tmp);
13910+ if (err)
13911+ goto cleanup;
13912+
13913+ memset(r_tmp->subj_hash, 0,
13914+ r_tmp->subj_hash_size *
13915+ sizeof (struct acl_subject_label *));
13916+
13917+ err = copy_user_subjs(r_tmp->hash->first, r_tmp);
13918+
13919+ if (err)
13920+ goto cleanup;
13921+
13922+ /* set nested subject list to null */
13923+ r_tmp->hash->first = NULL;
13924+
13925+ insert_acl_role_label(r_tmp);
13926+ }
13927+
13928+ goto return_err;
13929+ cleanup:
13930+ free_variables();
13931+ return_err:
13932+ return err;
13933+
13934+}
13935+
13936+static int
13937+gracl_init(struct gr_arg *args)
13938+{
13939+ int error = 0;
13940+
13941+ memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
13942+ memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
13943+
13944+ if (init_variables(args)) {
13945+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
13946+ error = -ENOMEM;
13947+ free_variables();
13948+ goto out;
13949+ }
13950+
13951+ error = copy_user_acl(args);
13952+ free_init_variables();
13953+ if (error) {
13954+ free_variables();
13955+ goto out;
13956+ }
13957+
13958+ if ((error = gr_set_acls(0))) {
13959+ free_variables();
13960+ goto out;
13961+ }
13962+
13963+ gr_status |= GR_READY;
13964+ out:
13965+ return error;
13966+}
13967+
13968+/* derived from glibc fnmatch() 0: match, 1: no match*/
13969+
13970+static int
13971+glob_match(const char *p, const char *n)
13972+{
13973+ char c;
13974+
13975+ while ((c = *p++) != '\0') {
13976+ switch (c) {
13977+ case '?':
13978+ if (*n == '\0')
13979+ return 1;
13980+ else if (*n == '/')
13981+ return 1;
13982+ break;
13983+ case '\\':
13984+ if (*n != c)
13985+ return 1;
13986+ break;
13987+ case '*':
13988+ for (c = *p++; c == '?' || c == '*'; c = *p++) {
13989+ if (*n == '/')
13990+ return 1;
13991+ else if (c == '?') {
13992+ if (*n == '\0')
13993+ return 1;
13994+ else
13995+ ++n;
13996+ }
13997+ }
13998+ if (c == '\0') {
13999+ return 0;
14000+ } else {
14001+ const char *endp;
14002+
14003+ if ((endp = strchr(n, '/')) == NULL)
14004+ endp = n + strlen(n);
14005+
14006+ if (c == '[') {
14007+ for (--p; n < endp; ++n)
14008+ if (!glob_match(p, n))
14009+ return 0;
14010+ } else if (c == '/') {
14011+ while (*n != '\0' && *n != '/')
14012+ ++n;
14013+ if (*n == '/' && !glob_match(p, n + 1))
14014+ return 0;
14015+ } else {
14016+ for (--p; n < endp; ++n)
14017+ if (*n == c && !glob_match(p, n))
14018+ return 0;
14019+ }
14020+
14021+ return 1;
14022+ }
14023+ case '[':
14024+ {
14025+ int not;
14026+ char cold;
14027+
14028+ if (*n == '\0' || *n == '/')
14029+ return 1;
14030+
14031+ not = (*p == '!' || *p == '^');
14032+ if (not)
14033+ ++p;
14034+
14035+ c = *p++;
14036+ for (;;) {
14037+ unsigned char fn = (unsigned char)*n;
14038+
14039+ if (c == '\0')
14040+ return 1;
14041+ else {
14042+ if (c == fn)
14043+ goto matched;
14044+ cold = c;
14045+ c = *p++;
14046+
14047+ if (c == '-' && *p != ']') {
14048+ unsigned char cend = *p++;
14049+
14050+ if (cend == '\0')
14051+ return 1;
14052+
14053+ if (cold <= fn && fn <= cend)
14054+ goto matched;
14055+
14056+ c = *p++;
14057+ }
14058+ }
14059+
14060+ if (c == ']')
14061+ break;
14062+ }
14063+ if (!not)
14064+ return 1;
14065+ break;
14066+ matched:
14067+ while (c != ']') {
14068+ if (c == '\0')
14069+ return 1;
14070+
14071+ c = *p++;
14072+ }
14073+ if (not)
14074+ return 1;
14075+ }
14076+ break;
14077+ default:
14078+ if (c != *n)
14079+ return 1;
14080+ }
14081+
14082+ ++n;
14083+ }
14084+
14085+ if (*n == '\0')
14086+ return 0;
14087+
14088+ if (*n == '/')
14089+ return 0;
14090+
14091+ return 1;
14092+}
14093+
14094+static struct acl_object_label *
14095+chk_glob_label(struct acl_object_label *globbed,
14096+ struct dentry *dentry, struct vfsmount *mnt, char **path)
14097+{
14098+ struct acl_object_label *tmp;
14099+
14100+ if (*path == NULL)
14101+ *path = gr_to_filename_nolock(dentry, mnt);
14102+
14103+ tmp = globbed;
14104+
14105+ while (tmp) {
14106+ if (!glob_match(tmp->filename, *path))
14107+ return tmp;
14108+ tmp = tmp->next;
14109+ }
14110+
14111+ return NULL;
14112+}
14113+
14114+static struct acl_object_label *
14115+__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
14116+ const ino_t curr_ino, const dev_t curr_dev,
14117+ const struct acl_subject_label *subj, char **path)
14118+{
14119+ struct acl_subject_label *tmpsubj;
14120+ struct acl_object_label *retval;
14121+ struct acl_object_label *retval2;
14122+
14123+ tmpsubj = (struct acl_subject_label *) subj;
14124+ read_lock(&gr_inode_lock);
14125+ do {
14126+ retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
14127+ if (retval) {
14128+ if (retval->globbed) {
14129+ retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
14130+ (struct vfsmount *)orig_mnt, path);
14131+ if (retval2)
14132+ retval = retval2;
14133+ }
14134+ break;
14135+ }
14136+ } while ((tmpsubj = tmpsubj->parent_subject));
14137+ read_unlock(&gr_inode_lock);
14138+
14139+ return retval;
14140+}
14141+
14142+static __inline__ struct acl_object_label *
14143+full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
14144+ const struct dentry *curr_dentry,
14145+ const struct acl_subject_label *subj, char **path)
14146+{
14147+ return __full_lookup(orig_dentry, orig_mnt,
14148+ curr_dentry->d_inode->i_ino,
14149+ curr_dentry->d_inode->i_sb->s_dev, subj, path);
14150+}
14151+
14152+static struct acl_object_label *
14153+__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14154+ const struct acl_subject_label *subj, char *path)
14155+{
14156+ struct dentry *dentry = (struct dentry *) l_dentry;
14157+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
14158+ struct acl_object_label *retval;
14159+
14160+ spin_lock(&dcache_lock);
14161+
14162+ if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
14163+ retval = fakefs_obj;
14164+ goto out;
14165+ }
14166+
14167+ for (;;) {
14168+ if (dentry == real_root && mnt == real_root_mnt)
14169+ break;
14170+
14171+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
14172+ if (mnt->mnt_parent == mnt)
14173+ break;
14174+
14175+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
14176+ if (retval != NULL)
14177+ goto out;
14178+
14179+ dentry = mnt->mnt_mountpoint;
14180+ mnt = mnt->mnt_parent;
14181+ continue;
14182+ }
14183+
14184+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
14185+ if (retval != NULL)
14186+ goto out;
14187+
14188+ dentry = dentry->d_parent;
14189+ }
14190+
14191+ retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
14192+
14193+ if (retval == NULL)
14194+ retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
14195+out:
14196+ spin_unlock(&dcache_lock);
14197+ return retval;
14198+}
14199+
14200+static __inline__ struct acl_object_label *
14201+chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14202+ const struct acl_subject_label *subj)
14203+{
14204+ char *path = NULL;
14205+ return __chk_obj_label(l_dentry, l_mnt, subj, path);
14206+}
14207+
14208+static __inline__ struct acl_object_label *
14209+chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14210+ const struct acl_subject_label *subj, char *path)
14211+{
14212+ return __chk_obj_label(l_dentry, l_mnt, subj, path);
14213+}
14214+
14215+static struct acl_subject_label *
14216+chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
14217+ const struct acl_role_label *role)
14218+{
14219+ struct dentry *dentry = (struct dentry *) l_dentry;
14220+ struct vfsmount *mnt = (struct vfsmount *) l_mnt;
14221+ struct acl_subject_label *retval;
14222+
14223+ spin_lock(&dcache_lock);
14224+
14225+ for (;;) {
14226+ if (dentry == real_root && mnt == real_root_mnt)
14227+ break;
14228+ if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
14229+ if (mnt->mnt_parent == mnt)
14230+ break;
14231+
14232+ read_lock(&gr_inode_lock);
14233+ retval =
14234+ lookup_acl_subj_label(dentry->d_inode->i_ino,
14235+ dentry->d_inode->i_sb->s_dev, role);
14236+ read_unlock(&gr_inode_lock);
14237+ if (retval != NULL)
14238+ goto out;
14239+
14240+ dentry = mnt->mnt_mountpoint;
14241+ mnt = mnt->mnt_parent;
14242+ continue;
14243+ }
14244+
14245+ read_lock(&gr_inode_lock);
14246+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
14247+ dentry->d_inode->i_sb->s_dev, role);
14248+ read_unlock(&gr_inode_lock);
14249+ if (retval != NULL)
14250+ goto out;
14251+
14252+ dentry = dentry->d_parent;
14253+ }
14254+
14255+ read_lock(&gr_inode_lock);
14256+ retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
14257+ dentry->d_inode->i_sb->s_dev, role);
14258+ read_unlock(&gr_inode_lock);
14259+
14260+ if (unlikely(retval == NULL)) {
14261+ read_lock(&gr_inode_lock);
14262+ retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
14263+ real_root->d_inode->i_sb->s_dev, role);
14264+ read_unlock(&gr_inode_lock);
14265+ }
14266+out:
14267+ spin_unlock(&dcache_lock);
14268+
14269+ return retval;
14270+}
14271+
14272+static void
14273+gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
14274+{
14275+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
14276+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
14277+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
14278+ 1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
14279+
14280+ return;
14281+}
14282+
14283+static void
14284+gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real,
14285+ const unsigned int effective, const unsigned int fs)
14286+{
14287+ security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
14288+ task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
14289+ task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
14290+ type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
14291+
14292+ return;
14293+}
14294+
14295+__u32
14296+gr_check_link(const struct dentry * new_dentry,
14297+ const struct dentry * parent_dentry,
14298+ const struct vfsmount * parent_mnt,
14299+ const struct dentry * old_dentry, const struct vfsmount * old_mnt)
14300+{
14301+ struct acl_object_label *obj;
14302+ __u32 oldmode, newmode;
14303+ __u32 needmode;
14304+
14305+ if (unlikely(!(gr_status & GR_READY)))
14306+ return (GR_CREATE | GR_LINK);
14307+
14308+ obj = chk_obj_label(old_dentry, old_mnt, current->acl);
14309+ oldmode = obj->mode;
14310+
14311+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14312+ oldmode |= (GR_CREATE | GR_LINK);
14313+
14314+ needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
14315+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
14316+ needmode |= GR_SETID | GR_AUDIT_SETID;
14317+
14318+ newmode =
14319+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
14320+ oldmode | needmode);
14321+
14322+ needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
14323+ GR_SETID | GR_READ | GR_FIND | GR_DELETE |
14324+ GR_INHERIT | GR_AUDIT_INHERIT);
14325+
14326+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
14327+ goto bad;
14328+
14329+ if ((oldmode & needmode) != needmode)
14330+ goto bad;
14331+
14332+ needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
14333+ if ((newmode & needmode) != needmode)
14334+ goto bad;
14335+
14336+ if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
14337+ return newmode;
14338+bad:
14339+ needmode = oldmode;
14340+ if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
14341+ needmode |= GR_SETID;
14342+
14343+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
14344+ gr_log_learn(current, old_dentry, old_mnt, needmode);
14345+ return (GR_CREATE | GR_LINK);
14346+ } else if (newmode & GR_SUPPRESS)
14347+ return GR_SUPPRESS;
14348+ else
14349+ return 0;
14350+}
14351+
14352+__u32
14353+gr_search_file(const struct dentry * dentry, const __u32 mode,
14354+ const struct vfsmount * mnt)
14355+{
14356+ __u32 retval = mode;
14357+ struct acl_subject_label *curracl;
14358+ struct acl_object_label *currobj;
14359+
14360+ if (unlikely(!(gr_status & GR_READY)))
14361+ return (mode & ~GR_AUDITS);
14362+
14363+ curracl = current->acl;
14364+
14365+ currobj = chk_obj_label(dentry, mnt, curracl);
14366+ retval = currobj->mode & mode;
14367+
14368+ if (unlikely
14369+ ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
14370+ && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
14371+ __u32 new_mode = mode;
14372+
14373+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14374+
14375+ retval = new_mode;
14376+
14377+ if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
14378+ new_mode |= GR_INHERIT;
14379+
14380+ if (!(mode & GR_NOLEARN))
14381+ gr_log_learn(current, dentry, mnt, new_mode);
14382+ }
14383+
14384+ return retval;
14385+}
14386+
14387+__u32
14388+gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
14389+ const struct vfsmount * mnt, const __u32 mode)
14390+{
14391+ struct name_entry *match;
14392+ struct acl_object_label *matchpo;
14393+ struct acl_subject_label *curracl;
14394+ char *path;
14395+ __u32 retval;
14396+
14397+ if (unlikely(!(gr_status & GR_READY)))
14398+ return (mode & ~GR_AUDITS);
14399+
14400+ preempt_disable();
14401+ path = gr_to_filename_rbac(new_dentry, mnt);
14402+ match = lookup_name_entry(path);
14403+
14404+ if (!match)
14405+ goto check_parent;
14406+
14407+ curracl = current->acl;
14408+
14409+ read_lock(&gr_inode_lock);
14410+ matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
14411+ read_unlock(&gr_inode_lock);
14412+
14413+ if (matchpo) {
14414+ if ((matchpo->mode & mode) !=
14415+ (mode & ~(GR_AUDITS | GR_SUPPRESS))
14416+ && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
14417+ __u32 new_mode = mode;
14418+
14419+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14420+
14421+ gr_log_learn(current, new_dentry, mnt, new_mode);
14422+
14423+ preempt_enable();
14424+ return new_mode;
14425+ }
14426+ preempt_enable();
14427+ return (matchpo->mode & mode);
14428+ }
14429+
14430+ check_parent:
14431+ curracl = current->acl;
14432+
14433+ matchpo = chk_obj_create_label(parent, mnt, curracl, path);
14434+ retval = matchpo->mode & mode;
14435+
14436+ if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
14437+ && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
14438+ __u32 new_mode = mode;
14439+
14440+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
14441+
14442+ gr_log_learn(current, new_dentry, mnt, new_mode);
14443+ preempt_enable();
14444+ return new_mode;
14445+ }
14446+
14447+ preempt_enable();
14448+ return retval;
14449+}
14450+
14451+int
14452+gr_check_hidden_task(const struct task_struct *task)
14453+{
14454+ if (unlikely(!(gr_status & GR_READY)))
14455+ return 0;
14456+
14457+ if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
14458+ return 1;
14459+
14460+ return 0;
14461+}
14462+
14463+int
14464+gr_check_protected_task(const struct task_struct *task)
14465+{
14466+ if (unlikely(!(gr_status & GR_READY) || !task))
14467+ return 0;
14468+
14469+ if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
14470+ task->acl != current->acl)
14471+ return 1;
14472+
14473+ return 0;
14474+}
14475+
14476+void
14477+gr_copy_label(struct task_struct *tsk)
14478+{
14479+ tsk->signal->used_accept = 0;
14480+ tsk->acl_sp_role = 0;
14481+ tsk->acl_role_id = current->acl_role_id;
14482+ tsk->acl = current->acl;
14483+ tsk->role = current->role;
14484+ tsk->signal->curr_ip = current->signal->curr_ip;
14485+ if (current->exec_file)
14486+ get_file(current->exec_file);
14487+ tsk->exec_file = current->exec_file;
14488+ tsk->is_writable = current->is_writable;
14489+ if (unlikely(current->signal->used_accept))
14490+ current->signal->curr_ip = 0;
14491+
14492+ return;
14493+}
14494+
14495+static void
14496+gr_set_proc_res(struct task_struct *task)
14497+{
14498+ struct acl_subject_label *proc;
14499+ unsigned short i;
14500+
14501+ proc = task->acl;
14502+
14503+ if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
14504+ return;
14505+
14506+ for (i = 0; i < (GR_NLIMITS - 1); i++) {
14507+ if (!(proc->resmask & (1 << i)))
14508+ continue;
14509+
14510+ task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
14511+ task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
14512+ }
14513+
14514+ return;
14515+}
14516+
14517+int
14518+gr_check_user_change(int real, int effective, int fs)
14519+{
14520+ unsigned int i;
14521+ __u16 num;
14522+ uid_t *uidlist;
14523+ int curuid;
14524+ int realok = 0;
14525+ int effectiveok = 0;
14526+ int fsok = 0;
14527+
14528+ if (unlikely(!(gr_status & GR_READY)))
14529+ return 0;
14530+
14531+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14532+ gr_log_learn_id_change(current, 'u', real, effective, fs);
14533+
14534+ num = current->acl->user_trans_num;
14535+ uidlist = current->acl->user_transitions;
14536+
14537+ if (uidlist == NULL)
14538+ return 0;
14539+
14540+ if (real == -1)
14541+ realok = 1;
14542+ if (effective == -1)
14543+ effectiveok = 1;
14544+ if (fs == -1)
14545+ fsok = 1;
14546+
14547+ if (current->acl->user_trans_type & GR_ID_ALLOW) {
14548+ for (i = 0; i < num; i++) {
14549+ curuid = (int)uidlist[i];
14550+ if (real == curuid)
14551+ realok = 1;
14552+ if (effective == curuid)
14553+ effectiveok = 1;
14554+ if (fs == curuid)
14555+ fsok = 1;
14556+ }
14557+ } else if (current->acl->user_trans_type & GR_ID_DENY) {
14558+ for (i = 0; i < num; i++) {
14559+ curuid = (int)uidlist[i];
14560+ if (real == curuid)
14561+ break;
14562+ if (effective == curuid)
14563+ break;
14564+ if (fs == curuid)
14565+ break;
14566+ }
14567+ /* not in deny list */
14568+ if (i == num) {
14569+ realok = 1;
14570+ effectiveok = 1;
14571+ fsok = 1;
14572+ }
14573+ }
14574+
14575+ if (realok && effectiveok && fsok)
14576+ return 0;
14577+ else {
14578+ gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
14579+ return 1;
14580+ }
14581+}
14582+
14583+int
14584+gr_check_group_change(int real, int effective, int fs)
14585+{
14586+ unsigned int i;
14587+ __u16 num;
14588+ gid_t *gidlist;
14589+ int curgid;
14590+ int realok = 0;
14591+ int effectiveok = 0;
14592+ int fsok = 0;
14593+
14594+ if (unlikely(!(gr_status & GR_READY)))
14595+ return 0;
14596+
14597+ if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
14598+ gr_log_learn_id_change(current, 'g', real, effective, fs);
14599+
14600+ num = current->acl->group_trans_num;
14601+ gidlist = current->acl->group_transitions;
14602+
14603+ if (gidlist == NULL)
14604+ return 0;
14605+
14606+ if (real == -1)
14607+ realok = 1;
14608+ if (effective == -1)
14609+ effectiveok = 1;
14610+ if (fs == -1)
14611+ fsok = 1;
14612+
14613+ if (current->acl->group_trans_type & GR_ID_ALLOW) {
14614+ for (i = 0; i < num; i++) {
14615+ curgid = (int)gidlist[i];
14616+ if (real == curgid)
14617+ realok = 1;
14618+ if (effective == curgid)
14619+ effectiveok = 1;
14620+ if (fs == curgid)
14621+ fsok = 1;
14622+ }
14623+ } else if (current->acl->group_trans_type & GR_ID_DENY) {
14624+ for (i = 0; i < num; i++) {
14625+ curgid = (int)gidlist[i];
14626+ if (real == curgid)
14627+ break;
14628+ if (effective == curgid)
14629+ break;
14630+ if (fs == curgid)
14631+ break;
14632+ }
14633+ /* not in deny list */
14634+ if (i == num) {
14635+ realok = 1;
14636+ effectiveok = 1;
14637+ fsok = 1;
14638+ }
14639+ }
14640+
14641+ if (realok && effectiveok && fsok)
14642+ return 0;
14643+ else {
14644+ gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
14645+ return 1;
14646+ }
14647+}
14648+
14649+void
14650+gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
14651+{
14652+ struct acl_role_label *role = task->role;
14653+ struct acl_subject_label *subj = NULL;
14654+ struct acl_object_label *obj;
14655+ struct file *filp;
14656+
14657+ if (unlikely(!(gr_status & GR_READY)))
14658+ return;
14659+
14660+ filp = task->exec_file;
14661+
14662+ /* kernel process, we'll give them the kernel role */
14663+ if (unlikely(!filp)) {
14664+ task->role = kernel_role;
14665+ task->acl = kernel_role->root_label;
14666+ return;
14667+ } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
14668+ role = lookup_acl_role_label(task, uid, gid);
14669+
14670+ /* perform subject lookup in possibly new role
14671+ we can use this result below in the case where role == task->role
14672+ */
14673+ subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
14674+
14675+ /* if we changed uid/gid, but result in the same role
14676+ and are using inheritance, don't lose the inherited subject
14677+ if current subject is other than what normal lookup
14678+ would result in, we arrived via inheritance, don't
14679+ lose subject
14680+ */
14681+ if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
14682+ (subj == task->acl)))
14683+ task->acl = subj;
14684+
14685+ task->role = role;
14686+
14687+ task->is_writable = 0;
14688+
14689+ /* ignore additional mmap checks for processes that are writable
14690+ by the default ACL */
14691+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
14692+ if (unlikely(obj->mode & GR_WRITE))
14693+ task->is_writable = 1;
14694+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
14695+ if (unlikely(obj->mode & GR_WRITE))
14696+ task->is_writable = 1;
14697+
14698+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14699+ printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
14700+#endif
14701+
14702+ gr_set_proc_res(task);
14703+
14704+ return;
14705+}
14706+
14707+int
14708+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
14709+{
14710+ struct task_struct *task = current;
14711+ struct acl_subject_label *newacl;
14712+ struct acl_object_label *obj;
14713+ __u32 retmode;
14714+
14715+ if (unlikely(!(gr_status & GR_READY)))
14716+ return 0;
14717+
14718+ newacl = chk_subj_label(dentry, mnt, task->role);
14719+
14720+ task_lock(task);
14721+ if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
14722+ GR_POVERRIDE) && (task->acl != newacl) &&
14723+ !(task->role->roletype & GR_ROLE_GOD) &&
14724+ !gr_search_file(dentry, GR_PTRACERD, mnt) &&
14725+ !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
14726+ (atomic_read(&task->fs->count) > 1 ||
14727+ atomic_read(&task->files->count) > 1 ||
14728+ atomic_read(&task->sighand->count) > 1)) {
14729+ task_unlock(task);
14730+ gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
14731+ return -EACCES;
14732+ }
14733+ task_unlock(task);
14734+
14735+ obj = chk_obj_label(dentry, mnt, task->acl);
14736+ retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
14737+
14738+ if (!(task->acl->mode & GR_INHERITLEARN) &&
14739+ ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
14740+ if (obj->nested)
14741+ task->acl = obj->nested;
14742+ else
14743+ task->acl = newacl;
14744+ } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
14745+ gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
14746+
14747+ task->is_writable = 0;
14748+
14749+ /* ignore additional mmap checks for processes that are writable
14750+ by the default ACL */
14751+ obj = chk_obj_label(dentry, mnt, default_role->root_label);
14752+ if (unlikely(obj->mode & GR_WRITE))
14753+ task->is_writable = 1;
14754+ obj = chk_obj_label(dentry, mnt, task->role->root_label);
14755+ if (unlikely(obj->mode & GR_WRITE))
14756+ task->is_writable = 1;
14757+
14758+ gr_set_proc_res(task);
14759+
14760+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
14761+ printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
14762+#endif
14763+ return 0;
14764+}
14765+
14766+static void
14767+do_handle_delete(const ino_t ino, const dev_t dev)
14768+{
14769+ struct acl_object_label *matchpo;
14770+ struct acl_subject_label *matchps;
14771+ struct acl_subject_label *subj;
14772+ struct acl_role_label *role;
14773+ unsigned int i, x;
14774+
14775+ FOR_EACH_ROLE_START(role, i)
14776+ FOR_EACH_SUBJECT_START(role, subj, x)
14777+ if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
14778+ matchpo->mode |= GR_DELETED;
14779+ FOR_EACH_SUBJECT_END(subj,x)
14780+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
14781+ if (subj->inode == ino && subj->device == dev)
14782+ subj->mode |= GR_DELETED;
14783+ FOR_EACH_NESTED_SUBJECT_END(subj)
14784+ if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
14785+ matchps->mode |= GR_DELETED;
14786+ FOR_EACH_ROLE_END(role,i)
14787+
14788+ return;
14789+}
14790+
14791+void
14792+gr_handle_delete(const ino_t ino, const dev_t dev)
14793+{
14794+ if (unlikely(!(gr_status & GR_READY)))
14795+ return;
14796+
14797+ write_lock(&gr_inode_lock);
14798+ if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
14799+ do_handle_delete(ino, dev);
14800+ write_unlock(&gr_inode_lock);
14801+
14802+ return;
14803+}
14804+
14805+static void
14806+update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
14807+ const ino_t newinode, const dev_t newdevice,
14808+ struct acl_subject_label *subj)
14809+{
14810+ unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
14811+ struct acl_object_label *match;
14812+
14813+ match = subj->obj_hash[index];
14814+
14815+ while (match && (match->inode != oldinode ||
14816+ match->device != olddevice ||
14817+ !(match->mode & GR_DELETED)))
14818+ match = match->next;
14819+
14820+ if (match && (match->inode == oldinode)
14821+ && (match->device == olddevice)
14822+ && (match->mode & GR_DELETED)) {
14823+ if (match->prev == NULL) {
14824+ subj->obj_hash[index] = match->next;
14825+ if (match->next != NULL)
14826+ match->next->prev = NULL;
14827+ } else {
14828+ match->prev->next = match->next;
14829+ if (match->next != NULL)
14830+ match->next->prev = match->prev;
14831+ }
14832+ match->prev = NULL;
14833+ match->next = NULL;
14834+ match->inode = newinode;
14835+ match->device = newdevice;
14836+ match->mode &= ~GR_DELETED;
14837+
14838+ insert_acl_obj_label(match, subj);
14839+ }
14840+
14841+ return;
14842+}
14843+
14844+static void
14845+update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
14846+ const ino_t newinode, const dev_t newdevice,
14847+ struct acl_role_label *role)
14848+{
14849+ unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
14850+ struct acl_subject_label *match;
14851+
14852+ match = role->subj_hash[index];
14853+
14854+ while (match && (match->inode != oldinode ||
14855+ match->device != olddevice ||
14856+ !(match->mode & GR_DELETED)))
14857+ match = match->next;
14858+
14859+ if (match && (match->inode == oldinode)
14860+ && (match->device == olddevice)
14861+ && (match->mode & GR_DELETED)) {
14862+ if (match->prev == NULL) {
14863+ role->subj_hash[index] = match->next;
14864+ if (match->next != NULL)
14865+ match->next->prev = NULL;
14866+ } else {
14867+ match->prev->next = match->next;
14868+ if (match->next != NULL)
14869+ match->next->prev = match->prev;
14870+ }
14871+ match->prev = NULL;
14872+ match->next = NULL;
14873+ match->inode = newinode;
14874+ match->device = newdevice;
14875+ match->mode &= ~GR_DELETED;
14876+
14877+ insert_acl_subj_label(match, role);
14878+ }
14879+
14880+ return;
14881+}
14882+
14883+static void
14884+update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
14885+ const ino_t newinode, const dev_t newdevice)
14886+{
14887+ unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
14888+ struct inodev_entry *match;
14889+
14890+ match = inodev_set.i_hash[index];
14891+
14892+ while (match && (match->nentry->inode != oldinode ||
14893+ match->nentry->device != olddevice))
14894+ match = match->next;
14895+
14896+ if (match && (match->nentry->inode == oldinode)
14897+ && (match->nentry->device == olddevice)) {
14898+ if (match->prev == NULL) {
14899+ inodev_set.i_hash[index] = match->next;
14900+ if (match->next != NULL)
14901+ match->next->prev = NULL;
14902+ } else {
14903+ match->prev->next = match->next;
14904+ if (match->next != NULL)
14905+ match->next->prev = match->prev;
14906+ }
14907+ match->prev = NULL;
14908+ match->next = NULL;
14909+ match->nentry->inode = newinode;
14910+ match->nentry->device = newdevice;
14911+
14912+ insert_inodev_entry(match);
14913+ }
14914+
14915+ return;
14916+}
14917+
14918+static void
14919+do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
14920+ const struct vfsmount *mnt)
14921+{
14922+ struct acl_subject_label *subj;
14923+ struct acl_role_label *role;
14924+ unsigned int i, x;
14925+
14926+ FOR_EACH_ROLE_START(role, i)
14927+ update_acl_subj_label(matchn->inode, matchn->device,
14928+ dentry->d_inode->i_ino,
14929+ dentry->d_inode->i_sb->s_dev, role);
14930+
14931+ FOR_EACH_NESTED_SUBJECT_START(role, subj)
14932+ if ((subj->inode == dentry->d_inode->i_ino) &&
14933+ (subj->device == dentry->d_inode->i_sb->s_dev)) {
14934+ subj->inode = dentry->d_inode->i_ino;
14935+ subj->device = dentry->d_inode->i_sb->s_dev;
14936+ }
14937+ FOR_EACH_NESTED_SUBJECT_END(subj)
14938+ FOR_EACH_SUBJECT_START(role, subj, x)
14939+ update_acl_obj_label(matchn->inode, matchn->device,
14940+ dentry->d_inode->i_ino,
14941+ dentry->d_inode->i_sb->s_dev, subj);
14942+ FOR_EACH_SUBJECT_END(subj,x)
14943+ FOR_EACH_ROLE_END(role,i)
14944+
14945+ update_inodev_entry(matchn->inode, matchn->device,
14946+ dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
14947+
14948+ return;
14949+}
14950+
14951+void
14952+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
14953+{
14954+ struct name_entry *matchn;
14955+
14956+ if (unlikely(!(gr_status & GR_READY)))
14957+ return;
14958+
14959+ preempt_disable();
14960+ matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
14961+
14962+ if (unlikely((unsigned long)matchn)) {
14963+ write_lock(&gr_inode_lock);
14964+ do_handle_create(matchn, dentry, mnt);
14965+ write_unlock(&gr_inode_lock);
14966+ }
14967+ preempt_enable();
14968+
14969+ return;
14970+}
14971+
14972+void
14973+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
14974+ struct dentry *old_dentry,
14975+ struct dentry *new_dentry,
14976+ struct vfsmount *mnt, const __u8 replace)
14977+{
14978+ struct name_entry *matchn;
14979+
14980+ if (unlikely(!(gr_status & GR_READY)))
14981+ return;
14982+
14983+ preempt_disable();
14984+ matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
14985+
14986+ /* we wouldn't have to check d_inode if it weren't for
14987+ NFS silly-renaming
14988+ */
14989+
14990+ write_lock(&gr_inode_lock);
14991+ if (unlikely(replace && new_dentry->d_inode)) {
14992+ if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
14993+ new_dentry->d_inode->i_sb->s_dev) &&
14994+ (old_dentry->d_inode->i_nlink <= 1)))
14995+ do_handle_delete(new_dentry->d_inode->i_ino,
14996+ new_dentry->d_inode->i_sb->s_dev);
14997+ }
14998+
14999+ if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
15000+ old_dentry->d_inode->i_sb->s_dev) &&
15001+ (old_dentry->d_inode->i_nlink <= 1)))
15002+ do_handle_delete(old_dentry->d_inode->i_ino,
15003+ old_dentry->d_inode->i_sb->s_dev);
15004+
15005+ if (unlikely((unsigned long)matchn))
15006+ do_handle_create(matchn, old_dentry, mnt);
15007+
15008+ write_unlock(&gr_inode_lock);
15009+ preempt_enable();
15010+
15011+ return;
15012+}
15013+
15014+static int
15015+lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
15016+ unsigned char **sum)
15017+{
15018+ struct acl_role_label *r;
15019+ struct role_allowed_ip *ipp;
15020+ struct role_transition *trans;
15021+ unsigned int i;
15022+ int found = 0;
15023+
15024+ /* check transition table */
15025+
15026+ for (trans = current->role->transitions; trans; trans = trans->next) {
15027+ if (!strcmp(rolename, trans->rolename)) {
15028+ found = 1;
15029+ break;
15030+ }
15031+ }
15032+
15033+ if (!found)
15034+ return 0;
15035+
15036+ /* handle special roles that do not require authentication
15037+ and check ip */
15038+
15039+ FOR_EACH_ROLE_START(r, i)
15040+ if (!strcmp(rolename, r->rolename) &&
15041+ (r->roletype & GR_ROLE_SPECIAL)) {
15042+ found = 0;
15043+ if (r->allowed_ips != NULL) {
15044+ for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
15045+ if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
15046+ (ntohl(ipp->addr) & ipp->netmask))
15047+ found = 1;
15048+ }
15049+ } else
15050+ found = 2;
15051+ if (!found)
15052+ return 0;
15053+
15054+ if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
15055+ ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
15056+ *salt = NULL;
15057+ *sum = NULL;
15058+ return 1;
15059+ }
15060+ }
15061+ FOR_EACH_ROLE_END(r,i)
15062+
15063+ for (i = 0; i < num_sprole_pws; i++) {
15064+ if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
15065+ *salt = acl_special_roles[i]->salt;
15066+ *sum = acl_special_roles[i]->sum;
15067+ return 1;
15068+ }
15069+ }
15070+
15071+ return 0;
15072+}
15073+
15074+static void
15075+assign_special_role(char *rolename)
15076+{
15077+ struct acl_object_label *obj;
15078+ struct acl_role_label *r;
15079+ struct acl_role_label *assigned = NULL;
15080+ struct task_struct *tsk;
15081+ struct file *filp;
15082+ unsigned int i;
15083+
15084+ FOR_EACH_ROLE_START(r, i)
15085+ if (!strcmp(rolename, r->rolename) &&
15086+ (r->roletype & GR_ROLE_SPECIAL))
15087+ assigned = r;
15088+ FOR_EACH_ROLE_END(r,i)
15089+
15090+ if (!assigned)
15091+ return;
15092+
15093+ read_lock(&tasklist_lock);
15094+ read_lock(&grsec_exec_file_lock);
15095+
15096+ tsk = current->parent;
15097+ if (tsk == NULL)
15098+ goto out_unlock;
15099+
15100+ filp = tsk->exec_file;
15101+ if (filp == NULL)
15102+ goto out_unlock;
15103+
15104+ tsk->is_writable = 0;
15105+
15106+ tsk->acl_sp_role = 1;
15107+ tsk->acl_role_id = ++acl_sp_role_value;
15108+ tsk->role = assigned;
15109+ tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
15110+
15111+ /* ignore additional mmap checks for processes that are writable
15112+ by the default ACL */
15113+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
15114+ if (unlikely(obj->mode & GR_WRITE))
15115+ tsk->is_writable = 1;
15116+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
15117+ if (unlikely(obj->mode & GR_WRITE))
15118+ tsk->is_writable = 1;
15119+
15120+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
15121+ printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
15122+#endif
15123+
15124+out_unlock:
15125+ read_unlock(&grsec_exec_file_lock);
15126+ read_unlock(&tasklist_lock);
15127+ return;
15128+}
15129+
15130+int gr_check_secure_terminal(struct task_struct *task)
15131+{
15132+ struct task_struct *p, *p2, *p3;
15133+ struct files_struct *files;
15134+ struct fdtable *fdt;
15135+ struct file *our_file = NULL, *file;
15136+ int i;
15137+
15138+ if (task->signal->tty == NULL)
15139+ return 1;
15140+
15141+ files = get_files_struct(task);
15142+ if (files != NULL) {
15143+ rcu_read_lock();
15144+ fdt = files_fdtable(files);
15145+ for (i=0; i < fdt->max_fds; i++) {
15146+ file = fcheck_files(files, i);
15147+ if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
15148+ get_file(file);
15149+ our_file = file;
15150+ }
15151+ }
15152+ rcu_read_unlock();
15153+ put_files_struct(files);
15154+ }
15155+
15156+ if (our_file == NULL)
15157+ return 1;
15158+
15159+ read_lock(&tasklist_lock);
15160+ do_each_thread(p2, p) {
15161+ files = get_files_struct(p);
15162+ if (files == NULL ||
15163+ (p->signal && p->signal->tty == task->signal->tty)) {
15164+ if (files != NULL)
15165+ put_files_struct(files);
15166+ continue;
15167+ }
15168+ rcu_read_lock();
15169+ fdt = files_fdtable(files);
15170+ for (i=0; i < fdt->max_fds; i++) {
15171+ file = fcheck_files(files, i);
15172+ if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
15173+ file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
15174+ p3 = task;
15175+ while (p3->pid > 0) {
15176+ if (p3 == p)
15177+ break;
15178+ p3 = p3->parent;
15179+ }
15180+ if (p3 == p)
15181+ break;
15182+ gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
15183+ gr_handle_alertkill(p);
15184+ rcu_read_unlock();
15185+ put_files_struct(files);
15186+ read_unlock(&tasklist_lock);
15187+ fput(our_file);
15188+ return 0;
15189+ }
15190+ }
15191+ rcu_read_unlock();
15192+ put_files_struct(files);
15193+ } while_each_thread(p2, p);
15194+ read_unlock(&tasklist_lock);
15195+
15196+ fput(our_file);
15197+ return 1;
15198+}
15199+
15200+ssize_t
15201+write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
15202+{
15203+ struct gr_arg_wrapper uwrap;
15204+ unsigned char *sprole_salt;
15205+ unsigned char *sprole_sum;
15206+ int error = sizeof (struct gr_arg_wrapper);
15207+ int error2 = 0;
15208+
15209+ down(&gr_dev_sem);
15210+
15211+ if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
15212+ error = -EPERM;
15213+ goto out;
15214+ }
15215+
15216+ if (count != sizeof (struct gr_arg_wrapper)) {
15217+ gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
15218+ error = -EINVAL;
15219+ goto out;
15220+ }
15221+
15222+
15223+ if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
15224+ gr_auth_expires = 0;
15225+ gr_auth_attempts = 0;
15226+ }
15227+
15228+ if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
15229+ error = -EFAULT;
15230+ goto out;
15231+ }
15232+
15233+ if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
15234+ error = -EINVAL;
15235+ goto out;
15236+ }
15237+
15238+ if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
15239+ error = -EFAULT;
15240+ goto out;
15241+ }
15242+
15243+ if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
15244+ gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
15245+ time_after(gr_auth_expires, get_seconds())) {
15246+ error = -EBUSY;
15247+ goto out;
15248+ }
15249+
15250+ /* if non-root trying to do anything other than use a special role,
15251+ do not attempt authentication, do not count towards authentication
15252+ locking
15253+ */
15254+
15255+ if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
15256+ gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
15257+ current->uid) {
15258+ error = -EPERM;
15259+ goto out;
15260+ }
15261+
15262+ /* ensure pw and special role name are null terminated */
15263+
15264+ gr_usermode->pw[GR_PW_LEN - 1] = '\0';
15265+ gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
15266+
15267+ /* Okay.
15268+ * We have our enough of the argument structure..(we have yet
15269+ * to copy_from_user the tables themselves) . Copy the tables
15270+ * only if we need them, i.e. for loading operations. */
15271+
15272+ switch (gr_usermode->mode) {
15273+ case STATUS:
15274+ if (gr_status & GR_READY) {
15275+ error = 1;
15276+ if (!gr_check_secure_terminal(current))
15277+ error = 3;
15278+ } else
15279+ error = 2;
15280+ goto out;
15281+ case SHUTDOWN:
15282+ if ((gr_status & GR_READY)
15283+ && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
15284+ gr_status &= ~GR_READY;
15285+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
15286+ free_variables();
15287+ memset(gr_usermode, 0, sizeof (struct gr_arg));
15288+ memset(gr_system_salt, 0, GR_SALT_LEN);
15289+ memset(gr_system_sum, 0, GR_SHA_LEN);
15290+ } else if (gr_status & GR_READY) {
15291+ gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
15292+ error = -EPERM;
15293+ } else {
15294+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
15295+ error = -EAGAIN;
15296+ }
15297+ break;
15298+ case ENABLE:
15299+ if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
15300+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
15301+ else {
15302+ if (gr_status & GR_READY)
15303+ error = -EAGAIN;
15304+ else
15305+ error = error2;
15306+ gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
15307+ }
15308+ break;
15309+ case RELOAD:
15310+ if (!(gr_status & GR_READY)) {
15311+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
15312+ error = -EAGAIN;
15313+ } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
15314+ lock_kernel();
15315+ gr_status &= ~GR_READY;
15316+ free_variables();
15317+ if (!(error2 = gracl_init(gr_usermode))) {
15318+ unlock_kernel();
15319+ gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
15320+ } else {
15321+ unlock_kernel();
15322+ error = error2;
15323+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
15324+ }
15325+ } else {
15326+ gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
15327+ error = -EPERM;
15328+ }
15329+ break;
15330+ case SEGVMOD:
15331+ if (unlikely(!(gr_status & GR_READY))) {
15332+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
15333+ error = -EAGAIN;
15334+ break;
15335+ }
15336+
15337+ if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
15338+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
15339+ if (gr_usermode->segv_device && gr_usermode->segv_inode) {
15340+ struct acl_subject_label *segvacl;
15341+ segvacl =
15342+ lookup_acl_subj_label(gr_usermode->segv_inode,
15343+ gr_usermode->segv_device,
15344+ current->role);
15345+ if (segvacl) {
15346+ segvacl->crashes = 0;
15347+ segvacl->expires = 0;
15348+ }
15349+ } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
15350+ gr_remove_uid(gr_usermode->segv_uid);
15351+ }
15352+ } else {
15353+ gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
15354+ error = -EPERM;
15355+ }
15356+ break;
15357+ case SPROLE:
15358+ case SPROLEPAM:
15359+ if (unlikely(!(gr_status & GR_READY))) {
15360+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
15361+ error = -EAGAIN;
15362+ break;
15363+ }
15364+
15365+ if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
15366+ current->role->expires = 0;
15367+ current->role->auth_attempts = 0;
15368+ }
15369+
15370+ if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
15371+ time_after(current->role->expires, get_seconds())) {
15372+ error = -EBUSY;
15373+ goto out;
15374+ }
15375+
15376+ if (lookup_special_role_auth
15377+ (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
15378+ && ((!sprole_salt && !sprole_sum)
15379+ || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
15380+ char *p = "";
15381+ assign_special_role(gr_usermode->sp_role);
15382+ read_lock(&tasklist_lock);
15383+ if (current->parent)
15384+ p = current->parent->role->rolename;
15385+ read_unlock(&tasklist_lock);
15386+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
15387+ p, acl_sp_role_value);
15388+ } else {
15389+ gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
15390+ error = -EPERM;
15391+ if(!(current->role->auth_attempts++))
15392+ current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
15393+
15394+ goto out;
15395+ }
15396+ break;
15397+ case UNSPROLE:
15398+ if (unlikely(!(gr_status & GR_READY))) {
15399+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
15400+ error = -EAGAIN;
15401+ break;
15402+ }
15403+
15404+ if (current->role->roletype & GR_ROLE_SPECIAL) {
15405+ char *p = "";
15406+ int i = 0;
15407+
15408+ read_lock(&tasklist_lock);
15409+ if (current->parent) {
15410+ p = current->parent->role->rolename;
15411+ i = current->parent->acl_role_id;
15412+ }
15413+ read_unlock(&tasklist_lock);
15414+
15415+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
15416+ gr_set_acls(1);
15417+ } else {
15418+ gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
15419+ error = -EPERM;
15420+ goto out;
15421+ }
15422+ break;
15423+ default:
15424+ gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
15425+ error = -EINVAL;
15426+ break;
15427+ }
15428+
15429+ if (error != -EPERM)
15430+ goto out;
15431+
15432+ if(!(gr_auth_attempts++))
15433+ gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
15434+
15435+ out:
15436+ up(&gr_dev_sem);
15437+ return error;
15438+}
15439+
15440+int
15441+gr_set_acls(const int type)
15442+{
15443+ struct acl_object_label *obj;
15444+ struct task_struct *task, *task2;
15445+ struct file *filp;
15446+ struct acl_role_label *role = current->role;
15447+ __u16 acl_role_id = current->acl_role_id;
15448+
15449+ read_lock(&tasklist_lock);
15450+ read_lock(&grsec_exec_file_lock);
15451+ do_each_thread(task2, task) {
15452+ /* check to see if we're called from the exit handler,
15453+ if so, only replace ACLs that have inherited the admin
15454+ ACL */
15455+
15456+ if (type && (task->role != role ||
15457+ task->acl_role_id != acl_role_id))
15458+ continue;
15459+
15460+ task->acl_role_id = 0;
15461+ task->acl_sp_role = 0;
15462+
15463+ if ((filp = task->exec_file)) {
15464+ task->role = lookup_acl_role_label(task, task->uid, task->gid);
15465+
15466+ task->acl =
15467+ chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
15468+ task->role);
15469+ if (task->acl) {
15470+ struct acl_subject_label *curr;
15471+ curr = task->acl;
15472+
15473+ task->is_writable = 0;
15474+ /* ignore additional mmap checks for processes that are writable
15475+ by the default ACL */
15476+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
15477+ if (unlikely(obj->mode & GR_WRITE))
15478+ task->is_writable = 1;
15479+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
15480+ if (unlikely(obj->mode & GR_WRITE))
15481+ task->is_writable = 1;
15482+
15483+ gr_set_proc_res(task);
15484+
15485+#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
15486+ printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
15487+#endif
15488+ } else {
15489+ read_unlock(&grsec_exec_file_lock);
15490+ read_unlock(&tasklist_lock);
15491+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
15492+ return 1;
15493+ }
15494+ } else {
15495+ // it's a kernel process
15496+ task->role = kernel_role;
15497+ task->acl = kernel_role->root_label;
15498+#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
15499+ task->acl->mode &= ~GR_PROCFIND;
15500+#endif
15501+ }
15502+ } while_each_thread(task2, task);
15503+ read_unlock(&grsec_exec_file_lock);
15504+ read_unlock(&tasklist_lock);
15505+ return 0;
15506+}
15507+
15508+void
15509+gr_learn_resource(const struct task_struct *task,
15510+ const int res, const unsigned long wanted, const int gt)
15511+{
15512+ struct acl_subject_label *acl;
15513+
15514+ if (unlikely((gr_status & GR_READY) &&
15515+ task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
15516+ goto skip_reslog;
15517+
15518+#ifdef CONFIG_GRKERNSEC_RESLOG
15519+ gr_log_resource(task, res, wanted, gt);
15520+#endif
15521+ skip_reslog:
15522+
15523+ if (unlikely(!(gr_status & GR_READY) || !wanted))
15524+ return;
15525+
15526+ acl = task->acl;
15527+
15528+ if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
15529+ !(acl->resmask & (1 << (unsigned short) res))))
15530+ return;
15531+
15532+ if (wanted >= acl->res[res].rlim_cur) {
15533+ unsigned long res_add;
15534+
15535+ res_add = wanted;
15536+ switch (res) {
15537+ case RLIMIT_CPU:
15538+ res_add += GR_RLIM_CPU_BUMP;
15539+ break;
15540+ case RLIMIT_FSIZE:
15541+ res_add += GR_RLIM_FSIZE_BUMP;
15542+ break;
15543+ case RLIMIT_DATA:
15544+ res_add += GR_RLIM_DATA_BUMP;
15545+ break;
15546+ case RLIMIT_STACK:
15547+ res_add += GR_RLIM_STACK_BUMP;
15548+ break;
15549+ case RLIMIT_CORE:
15550+ res_add += GR_RLIM_CORE_BUMP;
15551+ break;
15552+ case RLIMIT_RSS:
15553+ res_add += GR_RLIM_RSS_BUMP;
15554+ break;
15555+ case RLIMIT_NPROC:
15556+ res_add += GR_RLIM_NPROC_BUMP;
15557+ break;
15558+ case RLIMIT_NOFILE:
15559+ res_add += GR_RLIM_NOFILE_BUMP;
15560+ break;
15561+ case RLIMIT_MEMLOCK:
15562+ res_add += GR_RLIM_MEMLOCK_BUMP;
15563+ break;
15564+ case RLIMIT_AS:
15565+ res_add += GR_RLIM_AS_BUMP;
15566+ break;
15567+ case RLIMIT_LOCKS:
15568+ res_add += GR_RLIM_LOCKS_BUMP;
15569+ break;
15570+ }
15571+
15572+ acl->res[res].rlim_cur = res_add;
15573+
15574+ if (wanted > acl->res[res].rlim_max)
15575+ acl->res[res].rlim_max = res_add;
15576+
15577+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
15578+ task->role->roletype, acl->filename,
15579+ acl->res[res].rlim_cur, acl->res[res].rlim_max,
15580+ "", (unsigned long) res);
15581+ }
15582+
15583+ return;
15584+}
15585+
15586+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
15587+void
15588+pax_set_initial_flags(struct linux_binprm *bprm)
15589+{
15590+ struct task_struct *task = current;
15591+ struct acl_subject_label *proc;
15592+ unsigned long flags;
15593+
15594+ if (unlikely(!(gr_status & GR_READY)))
15595+ return;
15596+
15597+ flags = pax_get_flags(task);
15598+
15599+ proc = task->acl;
15600+
15601+ if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
15602+ flags &= ~MF_PAX_PAGEEXEC;
15603+ if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
15604+ flags &= ~MF_PAX_SEGMEXEC;
15605+ if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
15606+ flags &= ~MF_PAX_RANDMMAP;
15607+ if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
15608+ flags &= ~MF_PAX_EMUTRAMP;
15609+ if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
15610+ flags &= ~MF_PAX_MPROTECT;
15611+
15612+ if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
15613+ flags |= MF_PAX_PAGEEXEC;
15614+ if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
15615+ flags |= MF_PAX_SEGMEXEC;
15616+ if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
15617+ flags |= MF_PAX_RANDMMAP;
15618+ if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
15619+ flags |= MF_PAX_EMUTRAMP;
15620+ if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
15621+ flags |= MF_PAX_MPROTECT;
15622+
15623+ pax_set_flags(task, flags);
15624+
15625+ return;
15626+}
15627+#endif
15628+
15629+#ifdef CONFIG_SYSCTL
15630+extern struct proc_dir_entry *proc_sys_root;
15631+
15632+/* the following function is called under the BKL */
15633+
15634+__u32
15635+gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
15636+ const void *newval)
15637+{
15638+ struct proc_dir_entry *tmp;
15639+ struct nameidata nd;
15640+ const char *proc_sys = "/proc/sys";
15641+ char *path;
15642+ struct acl_object_label *obj;
15643+ unsigned short len = 0, pos = 0, depth = 0, i;
15644+ __u32 err = 0;
15645+ __u32 mode = 0;
15646+
15647+ if (unlikely(!(gr_status & GR_READY)))
15648+ return 1;
15649+
15650+ path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
15651+
15652+ if (oldval)
15653+ mode |= GR_READ;
15654+ if (newval)
15655+ mode |= GR_WRITE;
15656+
15657+ /* convert the requested sysctl entry into a pathname */
15658+
15659+ for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
15660+ len += strlen(tmp->name);
15661+ len++;
15662+ depth++;
15663+ }
15664+
15665+ if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
15666+ return 0; /* deny */
15667+
15668+ memset(path, 0, PAGE_SIZE);
15669+
15670+ memcpy(path, proc_sys, strlen(proc_sys));
15671+
15672+ pos += strlen(proc_sys);
15673+
15674+ for (; depth > 0; depth--) {
15675+ path[pos] = '/';
15676+ pos++;
15677+ for (i = 1, tmp = table->de; tmp != proc_sys_root;
15678+ tmp = tmp->parent) {
15679+ if (depth == i) {
15680+ memcpy(path + pos, tmp->name,
15681+ strlen(tmp->name));
15682+ pos += strlen(tmp->name);
15683+ }
15684+ i++;
15685+ }
15686+ }
15687+
15688+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
15689+
15690+ if (err)
15691+ goto out;
15692+
15693+ obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
15694+ err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
15695+
15696+ if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
15697+ ((err & mode) != mode))) {
15698+ __u32 new_mode = mode;
15699+
15700+ new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
15701+
15702+ err = new_mode;
15703+ gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
15704+ } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
15705+ gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
15706+ path, (mode & GR_READ) ? " reading" : "",
15707+ (mode & GR_WRITE) ? " writing" : "");
15708+ err = 0;
15709+ } else if ((err & mode) != mode) {
15710+ err = 0;
15711+ } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
15712+ gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
15713+ path, (mode & GR_READ) ? " reading" : "",
15714+ (mode & GR_WRITE) ? " writing" : "");
15715+ }
15716+
15717+ path_release(&nd);
15718+
15719+ out:
15720+ return err;
15721+}
15722+#endif
15723+
15724+int
15725+gr_handle_proc_ptrace(struct task_struct *task)
15726+{
15727+ struct file *filp;
15728+ struct task_struct *tmp = task;
15729+ struct task_struct *curtemp = current;
15730+ __u32 retmode;
15731+
15732+ if (unlikely(!(gr_status & GR_READY)))
15733+ return 0;
15734+
15735+ read_lock(&tasklist_lock);
15736+ read_lock(&grsec_exec_file_lock);
15737+ filp = task->exec_file;
15738+
15739+ while (tmp->pid > 0) {
15740+ if (tmp == curtemp)
15741+ break;
15742+ tmp = tmp->parent;
15743+ }
15744+
15745+ if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
15746+ read_unlock(&grsec_exec_file_lock);
15747+ read_unlock(&tasklist_lock);
15748+ return 1;
15749+ }
15750+
15751+ retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
15752+ read_unlock(&grsec_exec_file_lock);
15753+ read_unlock(&tasklist_lock);
15754+
15755+ if (retmode & GR_NOPTRACE)
15756+ return 1;
15757+
15758+ if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
15759+ && (current->acl != task->acl || (current->acl != current->role->root_label
15760+ && current->pid != task->pid)))
15761+ return 1;
15762+
15763+ return 0;
15764+}
15765+
15766+int
15767+gr_handle_ptrace(struct task_struct *task, const long request)
15768+{
15769+ struct task_struct *tmp = task;
15770+ struct task_struct *curtemp = current;
15771+ __u32 retmode;
15772+
15773+ if (unlikely(!(gr_status & GR_READY)))
15774+ return 0;
15775+
15776+ read_lock(&tasklist_lock);
15777+ while (tmp->pid > 0) {
15778+ if (tmp == curtemp)
15779+ break;
15780+ tmp = tmp->parent;
15781+ }
15782+
15783+ if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
15784+ read_unlock(&tasklist_lock);
15785+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15786+ return 1;
15787+ }
15788+ read_unlock(&tasklist_lock);
15789+
15790+ read_lock(&grsec_exec_file_lock);
15791+ if (unlikely(!task->exec_file)) {
15792+ read_unlock(&grsec_exec_file_lock);
15793+ return 0;
15794+ }
15795+
15796+ retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
15797+ read_unlock(&grsec_exec_file_lock);
15798+
15799+ if (retmode & GR_NOPTRACE) {
15800+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15801+ return 1;
15802+ }
15803+
15804+ if (retmode & GR_PTRACERD) {
15805+ switch (request) {
15806+ case PTRACE_POKETEXT:
15807+ case PTRACE_POKEDATA:
15808+ case PTRACE_POKEUSR:
15809+#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
15810+ case PTRACE_SETREGS:
15811+ case PTRACE_SETFPREGS:
15812+#endif
15813+#ifdef CONFIG_X86
15814+ case PTRACE_SETFPXREGS:
15815+#endif
15816+#ifdef CONFIG_ALTIVEC
15817+ case PTRACE_SETVRREGS:
15818+#endif
15819+ return 1;
15820+ default:
15821+ return 0;
15822+ }
15823+ } else if (!(current->acl->mode & GR_POVERRIDE) &&
15824+ !(current->role->roletype & GR_ROLE_GOD) &&
15825+ (current->acl != task->acl)) {
15826+ gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
15827+ return 1;
15828+ }
15829+
15830+ return 0;
15831+}
15832+
15833+static int is_writable_mmap(const struct file *filp)
15834+{
15835+ struct task_struct *task = current;
15836+ struct acl_object_label *obj, *obj2;
15837+
15838+ if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
15839+ !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
15840+ obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
15841+ obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
15842+ task->role->root_label);
15843+ if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
15844+ gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
15845+ return 1;
15846+ }
15847+ }
15848+ return 0;
15849+}
15850+
15851+int
15852+gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
15853+{
15854+ __u32 mode;
15855+
15856+ if (unlikely(!file || !(prot & PROT_EXEC)))
15857+ return 1;
15858+
15859+ if (is_writable_mmap(file))
15860+ return 0;
15861+
15862+ mode =
15863+ gr_search_file(file->f_dentry,
15864+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
15865+ file->f_vfsmnt);
15866+
15867+ if (!gr_tpe_allow(file))
15868+ return 0;
15869+
15870+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
15871+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15872+ return 0;
15873+ } else if (unlikely(!(mode & GR_EXEC))) {
15874+ return 0;
15875+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
15876+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15877+ return 1;
15878+ }
15879+
15880+ return 1;
15881+}
15882+
15883+int
15884+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
15885+{
15886+ __u32 mode;
15887+
15888+ if (unlikely(!file || !(prot & PROT_EXEC)))
15889+ return 1;
15890+
15891+ if (is_writable_mmap(file))
15892+ return 0;
15893+
15894+ mode =
15895+ gr_search_file(file->f_dentry,
15896+ GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
15897+ file->f_vfsmnt);
15898+
15899+ if (!gr_tpe_allow(file))
15900+ return 0;
15901+
15902+ if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
15903+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15904+ return 0;
15905+ } else if (unlikely(!(mode & GR_EXEC))) {
15906+ return 0;
15907+ } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
15908+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
15909+ return 1;
15910+ }
15911+
15912+ return 1;
15913+}
15914+
15915+void
15916+gr_acl_handle_psacct(struct task_struct *task, const long code)
15917+{
15918+ unsigned long runtime;
15919+ unsigned long cputime;
15920+ unsigned int wday, cday;
15921+ __u8 whr, chr;
15922+ __u8 wmin, cmin;
15923+ __u8 wsec, csec;
15924+
15925+ if (unlikely(!(gr_status & GR_READY) || !task->acl ||
15926+ !(task->acl->mode & GR_PROCACCT)))
15927+ return;
15928+
15929+ runtime = xtime.tv_sec - task->start_time.tv_sec;
15930+ wday = runtime / (3600 * 24);
15931+ runtime -= wday * (3600 * 24);
15932+ whr = runtime / 3600;
15933+ runtime -= whr * 3600;
15934+ wmin = runtime / 60;
15935+ runtime -= wmin * 60;
15936+ wsec = runtime;
15937+
15938+ cputime = (task->utime + task->stime) / HZ;
15939+ cday = cputime / (3600 * 24);
15940+ cputime -= cday * (3600 * 24);
15941+ chr = cputime / 3600;
15942+ cputime -= chr * 3600;
15943+ cmin = cputime / 60;
15944+ cputime -= cmin * 60;
15945+ csec = cputime;
15946+
15947+ gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
15948+
15949+ return;
15950+}
15951+
15952+void gr_set_kernel_label(struct task_struct *task)
15953+{
15954+ if (gr_status & GR_READY) {
15955+ task->role = kernel_role;
15956+ task->acl = kernel_role->root_label;
15957+ }
15958+ return;
15959+}
15960+
15961+int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
15962+{
15963+ struct task_struct *task = current;
15964+ struct dentry *dentry = file->f_dentry;
15965+ struct vfsmount *mnt = file->f_vfsmnt;
15966+ struct acl_object_label *obj, *tmp;
15967+ struct acl_subject_label *subj;
15968+ unsigned int bufsize;
15969+ int is_not_root;
15970+ char *path;
15971+
15972+ if (unlikely(!(gr_status & GR_READY)))
15973+ return 1;
15974+
15975+ if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
15976+ return 1;
15977+
15978+ subj = task->acl;
15979+ do {
15980+ obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
15981+ if (obj != NULL)
15982+ return (obj->mode & GR_FIND) ? 1 : 0;
15983+ } while ((subj = subj->parent_subject));
15984+
15985+ obj = chk_obj_label(dentry, mnt, task->acl);
15986+ if (obj->globbed == NULL)
15987+ return (obj->mode & GR_FIND) ? 1 : 0;
15988+
15989+ is_not_root = ((obj->filename[0] == '/') &&
15990+ (obj->filename[1] == '\0')) ? 0 : 1;
15991+ bufsize = PAGE_SIZE - namelen - is_not_root;
15992+
15993+ /* check bufsize > PAGE_SIZE || bufsize == 0 */
15994+ if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
15995+ return 1;
15996+
15997+ preempt_disable();
15998+ path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
15999+ bufsize);
16000+
16001+ bufsize = strlen(path);
16002+
16003+ /* if base is "/", don't append an additional slash */
16004+ if (is_not_root)
16005+ *(path + bufsize) = '/';
16006+ memcpy(path + bufsize + is_not_root, name, namelen);
16007+ *(path + bufsize + namelen + is_not_root) = '\0';
16008+
16009+ tmp = obj->globbed;
16010+ while (tmp) {
16011+ if (!glob_match(tmp->filename, path)) {
16012+ preempt_enable();
16013+ return (tmp->mode & GR_FIND) ? 1 : 0;
16014+ }
16015+ tmp = tmp->next;
16016+ }
16017+ preempt_enable();
16018+ return (obj->mode & GR_FIND) ? 1 : 0;
16019+}
16020+
16021+EXPORT_SYMBOL(gr_learn_resource);
16022+EXPORT_SYMBOL(gr_set_kernel_label);
16023+#ifdef CONFIG_SECURITY
16024+EXPORT_SYMBOL(gr_check_user_change);
16025+EXPORT_SYMBOL(gr_check_group_change);
16026+#endif
16027+
16028diff -urNp linux-2.6.19.1/grsecurity/gracl_cap.c linux-2.6.19.1/grsecurity/gracl_cap.c
16029--- linux-2.6.19.1/grsecurity/gracl_cap.c 1969-12-31 19:00:00.000000000 -0500
16030+++ linux-2.6.19.1/grsecurity/gracl_cap.c 2006-12-03 15:16:32.000000000 -0500
16031@@ -0,0 +1,110 @@
16032+#include <linux/kernel.h>
16033+#include <linux/module.h>
16034+#include <linux/sched.h>
16035+#include <linux/capability.h>
16036+#include <linux/gracl.h>
16037+#include <linux/grsecurity.h>
16038+#include <linux/grinternal.h>
16039+
16040+static const char *captab_log[] = {
16041+ "CAP_CHOWN",
16042+ "CAP_DAC_OVERRIDE",
16043+ "CAP_DAC_READ_SEARCH",
16044+ "CAP_FOWNER",
16045+ "CAP_FSETID",
16046+ "CAP_KILL",
16047+ "CAP_SETGID",
16048+ "CAP_SETUID",
16049+ "CAP_SETPCAP",
16050+ "CAP_LINUX_IMMUTABLE",
16051+ "CAP_NET_BIND_SERVICE",
16052+ "CAP_NET_BROADCAST",
16053+ "CAP_NET_ADMIN",
16054+ "CAP_NET_RAW",
16055+ "CAP_IPC_LOCK",
16056+ "CAP_IPC_OWNER",
16057+ "CAP_SYS_MODULE",
16058+ "CAP_SYS_RAWIO",
16059+ "CAP_SYS_CHROOT",
16060+ "CAP_SYS_PTRACE",
16061+ "CAP_SYS_PACCT",
16062+ "CAP_SYS_ADMIN",
16063+ "CAP_SYS_BOOT",
16064+ "CAP_SYS_NICE",
16065+ "CAP_SYS_RESOURCE",
16066+ "CAP_SYS_TIME",
16067+ "CAP_SYS_TTY_CONFIG",
16068+ "CAP_MKNOD",
16069+ "CAP_LEASE"
16070+};
16071+
16072+EXPORT_SYMBOL(gr_task_is_capable);
16073+
16074+int
16075+gr_task_is_capable(struct task_struct *task, const int cap)
16076+{
16077+ struct acl_subject_label *curracl;
16078+ __u32 cap_drop = 0, cap_mask = 0;
16079+
16080+ if (!gr_acl_is_enabled())
16081+ return 1;
16082+
16083+ curracl = task->acl;
16084+
16085+ cap_drop = curracl->cap_lower;
16086+ cap_mask = curracl->cap_mask;
16087+
16088+ while ((curracl = curracl->parent_subject)) {
16089+ if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
16090+ cap_drop |= curracl->cap_lower & (1 << cap);
16091+ cap_mask |= curracl->cap_mask;
16092+ }
16093+
16094+ if (!cap_raised(cap_drop, cap))
16095+ return 1;
16096+
16097+ curracl = task->acl;
16098+
16099+ if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
16100+ && cap_raised(task->cap_effective, cap)) {
16101+ security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
16102+ task->role->roletype, task->uid,
16103+ task->gid, task->exec_file ?
16104+ gr_to_filename(task->exec_file->f_dentry,
16105+ task->exec_file->f_vfsmnt) : curracl->filename,
16106+ curracl->filename, 0UL,
16107+ 0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
16108+ return 1;
16109+ }
16110+
16111+ if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
16112+ gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
16113+
16114+ return 0;
16115+}
16116+
16117+int
16118+gr_is_capable_nolog(const int cap)
16119+{
16120+ struct acl_subject_label *curracl;
16121+ __u32 cap_drop = 0, cap_mask = 0;
16122+
16123+ if (!gr_acl_is_enabled())
16124+ return 1;
16125+
16126+ curracl = current->acl;
16127+
16128+ cap_drop = curracl->cap_lower;
16129+ cap_mask = curracl->cap_mask;
16130+
16131+ while ((curracl = curracl->parent_subject)) {
16132+ cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
16133+ cap_mask |= curracl->cap_mask;
16134+ }
16135+
16136+ if (!cap_raised(cap_drop, cap))
16137+ return 1;
16138+
16139+ return 0;
16140+}
16141+
16142diff -urNp linux-2.6.19.1/grsecurity/gracl_fs.c linux-2.6.19.1/grsecurity/gracl_fs.c
16143--- linux-2.6.19.1/grsecurity/gracl_fs.c 1969-12-31 19:00:00.000000000 -0500
16144+++ linux-2.6.19.1/grsecurity/gracl_fs.c 2006-12-03 15:16:32.000000000 -0500
16145@@ -0,0 +1,423 @@
16146+#include <linux/kernel.h>
16147+#include <linux/sched.h>
16148+#include <linux/types.h>
16149+#include <linux/fs.h>
16150+#include <linux/file.h>
16151+#include <linux/stat.h>
16152+#include <linux/grsecurity.h>
16153+#include <linux/grinternal.h>
16154+#include <linux/gracl.h>
16155+
16156+__u32
16157+gr_acl_handle_hidden_file(const struct dentry * dentry,
16158+ const struct vfsmount * mnt)
16159+{
16160+ __u32 mode;
16161+
16162+ if (unlikely(!dentry->d_inode))
16163+ return GR_FIND;
16164+
16165+ mode =
16166+ gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
16167+
16168+ if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
16169+ gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
16170+ return mode;
16171+ } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
16172+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
16173+ return 0;
16174+ } else if (unlikely(!(mode & GR_FIND)))
16175+ return 0;
16176+
16177+ return GR_FIND;
16178+}
16179+
16180+__u32
16181+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
16182+ const int fmode)
16183+{
16184+ __u32 reqmode = GR_FIND;
16185+ __u32 mode;
16186+
16187+ if (unlikely(!dentry->d_inode))
16188+ return reqmode;
16189+
16190+ if (unlikely(fmode & O_APPEND))
16191+ reqmode |= GR_APPEND;
16192+ else if (unlikely(fmode & FMODE_WRITE))
16193+ reqmode |= GR_WRITE;
16194+ if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
16195+ reqmode |= GR_READ;
16196+
16197+ mode =
16198+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
16199+ mnt);
16200+
16201+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
16202+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
16203+ reqmode & GR_READ ? " reading" : "",
16204+ reqmode & GR_WRITE ? " writing" : reqmode &
16205+ GR_APPEND ? " appending" : "");
16206+ return reqmode;
16207+ } else
16208+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
16209+ {
16210+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
16211+ reqmode & GR_READ ? " reading" : "",
16212+ reqmode & GR_WRITE ? " writing" : reqmode &
16213+ GR_APPEND ? " appending" : "");
16214+ return 0;
16215+ } else if (unlikely((mode & reqmode) != reqmode))
16216+ return 0;
16217+
16218+ return reqmode;
16219+}
16220+
16221+__u32
16222+gr_acl_handle_creat(const struct dentry * dentry,
16223+ const struct dentry * p_dentry,
16224+ const struct vfsmount * p_mnt, const int fmode,
16225+ const int imode)
16226+{
16227+ __u32 reqmode = GR_WRITE | GR_CREATE;
16228+ __u32 mode;
16229+
16230+ if (unlikely(fmode & O_APPEND))
16231+ reqmode |= GR_APPEND;
16232+ if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
16233+ reqmode |= GR_READ;
16234+ if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
16235+ reqmode |= GR_SETID;
16236+
16237+ mode =
16238+ gr_check_create(dentry, p_dentry, p_mnt,
16239+ reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
16240+
16241+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
16242+ gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
16243+ reqmode & GR_READ ? " reading" : "",
16244+ reqmode & GR_WRITE ? " writing" : reqmode &
16245+ GR_APPEND ? " appending" : "");
16246+ return reqmode;
16247+ } else
16248+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
16249+ {
16250+ gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
16251+ reqmode & GR_READ ? " reading" : "",
16252+ reqmode & GR_WRITE ? " writing" : reqmode &
16253+ GR_APPEND ? " appending" : "");
16254+ return 0;
16255+ } else if (unlikely((mode & reqmode) != reqmode))
16256+ return 0;
16257+
16258+ return reqmode;
16259+}
16260+
16261+__u32
16262+gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
16263+ const int fmode)
16264+{
16265+ __u32 mode, reqmode = GR_FIND;
16266+
16267+ if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
16268+ reqmode |= GR_EXEC;
16269+ if (fmode & S_IWOTH)
16270+ reqmode |= GR_WRITE;
16271+ if (fmode & S_IROTH)
16272+ reqmode |= GR_READ;
16273+
16274+ mode =
16275+ gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
16276+ mnt);
16277+
16278+ if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
16279+ gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
16280+ reqmode & GR_READ ? " reading" : "",
16281+ reqmode & GR_WRITE ? " writing" : "",
16282+ reqmode & GR_EXEC ? " executing" : "");
16283+ return reqmode;
16284+ } else
16285+ if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
16286+ {
16287+ gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
16288+ reqmode & GR_READ ? " reading" : "",
16289+ reqmode & GR_WRITE ? " writing" : "",
16290+ reqmode & GR_EXEC ? " executing" : "");
16291+ return 0;
16292+ } else if (unlikely((mode & reqmode) != reqmode))
16293+ return 0;
16294+
16295+ return reqmode;
16296+}
16297+
16298+static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
16299+{
16300+ __u32 mode;
16301+
16302+ mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
16303+
16304+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
16305+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
16306+ return mode;
16307+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
16308+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
16309+ return 0;
16310+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
16311+ return 0;
16312+
16313+ return (reqmode);
16314+}
16315+
16316+__u32
16317+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
16318+{
16319+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
16320+}
16321+
16322+__u32
16323+gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
16324+{
16325+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
16326+}
16327+
16328+__u32
16329+gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
16330+{
16331+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
16332+}
16333+
16334+__u32
16335+gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
16336+{
16337+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
16338+}
16339+
16340+__u32
16341+gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
16342+ mode_t mode)
16343+{
16344+ if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
16345+ return 1;
16346+
16347+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
16348+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
16349+ GR_FCHMOD_ACL_MSG);
16350+ } else {
16351+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
16352+ }
16353+}
16354+
16355+__u32
16356+gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
16357+ mode_t mode)
16358+{
16359+ if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
16360+ return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
16361+ GR_CHMOD_ACL_MSG);
16362+ } else {
16363+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
16364+ }
16365+}
16366+
16367+__u32
16368+gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
16369+{
16370+ return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
16371+}
16372+
16373+__u32
16374+gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
16375+{
16376+ return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
16377+}
16378+
16379+__u32
16380+gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
16381+{
16382+ return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
16383+ GR_UNIXCONNECT_ACL_MSG);
16384+}
16385+
16386+/* hardlinks require at minimum create permission,
16387+ any additional privilege required is based on the
16388+ privilege of the file being linked to
16389+*/
16390+__u32
16391+gr_acl_handle_link(const struct dentry * new_dentry,
16392+ const struct dentry * parent_dentry,
16393+ const struct vfsmount * parent_mnt,
16394+ const struct dentry * old_dentry,
16395+ const struct vfsmount * old_mnt, const char *to)
16396+{
16397+ __u32 mode;
16398+ __u32 needmode = GR_CREATE | GR_LINK;
16399+ __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
16400+
16401+ mode =
16402+ gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
16403+ old_mnt);
16404+
16405+ if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
16406+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
16407+ return mode;
16408+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
16409+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
16410+ return 0;
16411+ } else if (unlikely((mode & needmode) != needmode))
16412+ return 0;
16413+
16414+ return 1;
16415+}
16416+
16417+__u32
16418+gr_acl_handle_symlink(const struct dentry * new_dentry,
16419+ const struct dentry * parent_dentry,
16420+ const struct vfsmount * parent_mnt, const char *from)
16421+{
16422+ __u32 needmode = GR_WRITE | GR_CREATE;
16423+ __u32 mode;
16424+
16425+ mode =
16426+ gr_check_create(new_dentry, parent_dentry, parent_mnt,
16427+ GR_CREATE | GR_AUDIT_CREATE |
16428+ GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
16429+
16430+ if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
16431+ gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
16432+ return mode;
16433+ } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
16434+ gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
16435+ return 0;
16436+ } else if (unlikely((mode & needmode) != needmode))
16437+ return 0;
16438+
16439+ return (GR_WRITE | GR_CREATE);
16440+}
16441+
16442+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)
16443+{
16444+ __u32 mode;
16445+
16446+ mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
16447+
16448+ if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
16449+ gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
16450+ return mode;
16451+ } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
16452+ gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
16453+ return 0;
16454+ } else if (unlikely((mode & (reqmode)) != (reqmode)))
16455+ return 0;
16456+
16457+ return (reqmode);
16458+}
16459+
16460+__u32
16461+gr_acl_handle_mknod(const struct dentry * new_dentry,
16462+ const struct dentry * parent_dentry,
16463+ const struct vfsmount * parent_mnt,
16464+ const int mode)
16465+{
16466+ __u32 reqmode = GR_WRITE | GR_CREATE;
16467+ if (unlikely(mode & (S_ISUID | S_ISGID)))
16468+ reqmode |= GR_SETID;
16469+
16470+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
16471+ reqmode, GR_MKNOD_ACL_MSG);
16472+}
16473+
16474+__u32
16475+gr_acl_handle_mkdir(const struct dentry *new_dentry,
16476+ const struct dentry *parent_dentry,
16477+ const struct vfsmount *parent_mnt)
16478+{
16479+ return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
16480+ GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
16481+}
16482+
16483+#define RENAME_CHECK_SUCCESS(old, new) \
16484+ (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
16485+ ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
16486+
16487+int
16488+gr_acl_handle_rename(struct dentry *new_dentry,
16489+ struct dentry *parent_dentry,
16490+ const struct vfsmount *parent_mnt,
16491+ struct dentry *old_dentry,
16492+ struct inode *old_parent_inode,
16493+ struct vfsmount *old_mnt, const char *newname)
16494+{
16495+ __u32 comp1, comp2;
16496+ int error = 0;
16497+
16498+ if (unlikely(!gr_acl_is_enabled()))
16499+ return 0;
16500+
16501+ if (!new_dentry->d_inode) {
16502+ comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
16503+ GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
16504+ GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
16505+ comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
16506+ GR_DELETE | GR_AUDIT_DELETE |
16507+ GR_AUDIT_READ | GR_AUDIT_WRITE |
16508+ GR_SUPPRESS, old_mnt);
16509+ } else {
16510+ comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
16511+ GR_CREATE | GR_DELETE |
16512+ GR_AUDIT_CREATE | GR_AUDIT_DELETE |
16513+ GR_AUDIT_READ | GR_AUDIT_WRITE |
16514+ GR_SUPPRESS, parent_mnt);
16515+ comp2 =
16516+ gr_search_file(old_dentry,
16517+ GR_READ | GR_WRITE | GR_AUDIT_READ |
16518+ GR_DELETE | GR_AUDIT_DELETE |
16519+ GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
16520+ }
16521+
16522+ if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
16523+ ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
16524+ gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
16525+ else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
16526+ && !(comp2 & GR_SUPPRESS)) {
16527+ gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
16528+ error = -EACCES;
16529+ } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
16530+ error = -EACCES;
16531+
16532+ return error;
16533+}
16534+
16535+void
16536+gr_acl_handle_exit(void)
16537+{
16538+ u16 id;
16539+ char *rolename;
16540+ struct file *exec_file;
16541+
16542+ if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
16543+ id = current->acl_role_id;
16544+ rolename = current->role->rolename;
16545+ gr_set_acls(1);
16546+ gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
16547+ }
16548+
16549+ write_lock(&grsec_exec_file_lock);
16550+ exec_file = current->exec_file;
16551+ current->exec_file = NULL;
16552+ write_unlock(&grsec_exec_file_lock);
16553+
16554+ if (exec_file)
16555+ fput(exec_file);
16556+}
16557+
16558+int
16559+gr_acl_handle_procpidmem(const struct task_struct *task)
16560+{
16561+ if (unlikely(!gr_acl_is_enabled()))
16562+ return 0;
16563+
16564+ if (task->acl->mode & GR_PROTPROCFD)
16565+ return -EACCES;
16566+
16567+ return 0;
16568+}
16569diff -urNp linux-2.6.19.1/grsecurity/gracl_ip.c linux-2.6.19.1/grsecurity/gracl_ip.c
16570--- linux-2.6.19.1/grsecurity/gracl_ip.c 1969-12-31 19:00:00.000000000 -0500
16571+++ linux-2.6.19.1/grsecurity/gracl_ip.c 2006-12-03 15:16:32.000000000 -0500
16572@@ -0,0 +1,313 @@
16573+#include <linux/kernel.h>
16574+#include <asm/uaccess.h>
16575+#include <asm/errno.h>
16576+#include <net/sock.h>
16577+#include <linux/file.h>
16578+#include <linux/fs.h>
16579+#include <linux/net.h>
16580+#include <linux/in.h>
16581+#include <linux/skbuff.h>
16582+#include <linux/ip.h>
16583+#include <linux/udp.h>
16584+#include <linux/smp_lock.h>
16585+#include <linux/types.h>
16586+#include <linux/sched.h>
16587+#include <linux/netdevice.h>
16588+#include <linux/inetdevice.h>
16589+#include <linux/gracl.h>
16590+#include <linux/grsecurity.h>
16591+#include <linux/grinternal.h>
16592+
16593+#define GR_BIND 0x01
16594+#define GR_CONNECT 0x02
16595+#define GR_INVERT 0x04
16596+
16597+static const char * gr_protocols[256] = {
16598+ "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
16599+ "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
16600+ "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
16601+ "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
16602+ "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
16603+ "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
16604+ "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
16605+ "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
16606+ "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
16607+ "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak",
16608+ "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf",
16609+ "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
16610+ "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
16611+ "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
16612+ "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
16613+ "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
16614+ "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
16615+ "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
16616+ "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
16617+ "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
16618+ "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
16619+ "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
16620+ "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
16621+ "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
16622+ "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
16623+ "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
16624+ "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
16625+ "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
16626+ "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
16627+ "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
16628+ "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
16629+ "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
16630+ };
16631+
16632+static const char * gr_socktypes[11] = {
16633+ "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6",
16634+ "unknown:7", "unknown:8", "unknown:9", "packet"
16635+ };
16636+
16637+const char *
16638+gr_proto_to_name(unsigned char proto)
16639+{
16640+ return gr_protocols[proto];
16641+}
16642+
16643+const char *
16644+gr_socktype_to_name(unsigned char type)
16645+{
16646+ return gr_socktypes[type];
16647+}
16648+
16649+int
16650+gr_search_socket(const int domain, const int type, const int protocol)
16651+{
16652+ struct acl_subject_label *curr;
16653+
16654+ if (unlikely(!gr_acl_is_enabled()))
16655+ goto exit;
16656+
16657+ if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
16658+ || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
16659+ goto exit; // let the kernel handle it
16660+
16661+ curr = current->acl;
16662+
16663+ if (!curr->ips)
16664+ goto exit;
16665+
16666+ if ((curr->ip_type & (1 << type)) &&
16667+ (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
16668+ goto exit;
16669+
16670+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
16671+ /* we don't place acls on raw sockets , and sometimes
16672+ dgram/ip sockets are opened for ioctl and not
16673+ bind/connect, so we'll fake a bind learn log */
16674+ if (type == SOCK_RAW || type == SOCK_PACKET) {
16675+ __u32 fakeip = 0;
16676+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
16677+ current->role->roletype, current->uid,
16678+ current->gid, current->exec_file ?
16679+ gr_to_filename(current->exec_file->f_dentry,
16680+ current->exec_file->f_vfsmnt) :
16681+ curr->filename, curr->filename,
16682+ NIPQUAD(fakeip), 0, type,
16683+ protocol, GR_CONNECT,
16684+NIPQUAD(current->signal->curr_ip));
16685+ } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
16686+ __u32 fakeip = 0;
16687+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
16688+ current->role->roletype, current->uid,
16689+ current->gid, current->exec_file ?
16690+ gr_to_filename(current->exec_file->f_dentry,
16691+ current->exec_file->f_vfsmnt) :
16692+ curr->filename, curr->filename,
16693+ NIPQUAD(fakeip), 0, type,
16694+ protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
16695+ }
16696+ /* we'll log when they use connect or bind */
16697+ goto exit;
16698+ }
16699+
16700+ gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet",
16701+ gr_socktype_to_name(type), gr_proto_to_name(protocol));
16702+
16703+ return 0;
16704+ exit:
16705+ return 1;
16706+}
16707+
16708+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)
16709+{
16710+ if ((ip->mode & mode) &&
16711+ (ip_port >= ip->low) &&
16712+ (ip_port <= ip->high) &&
16713+ ((ntohl(ip_addr) & our_netmask) ==
16714+ (ntohl(our_addr) & our_netmask))
16715+ && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
16716+ && (ip->type & (1 << type))) {
16717+ if (ip->mode & GR_INVERT)
16718+ return 2; // specifically denied
16719+ else
16720+ return 1; // allowed
16721+ }
16722+
16723+ return 0; // not specifically allowed, may continue parsing
16724+}
16725+
16726+static int
16727+gr_search_connectbind(const int mode, const struct sock *sk,
16728+ const struct sockaddr_in *addr, const int type)
16729+{
16730+ char iface[IFNAMSIZ] = {0};
16731+ struct acl_subject_label *curr;
16732+ struct acl_ip_label *ip;
16733+ struct net_device *dev;
16734+ struct in_device *idev;
16735+ unsigned long i;
16736+ int ret;
16737+ __u32 ip_addr = 0;
16738+ __u32 our_addr;
16739+ __u32 our_netmask;
16740+ char *p;
16741+ __u16 ip_port = 0;
16742+
16743+ if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
16744+ return 1;
16745+
16746+ curr = current->acl;
16747+
16748+ if (!curr->ips)
16749+ return 1;
16750+
16751+ ip_addr = addr->sin_addr.s_addr;
16752+ ip_port = ntohs(addr->sin_port);
16753+
16754+ if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
16755+ security_learn(GR_IP_LEARN_MSG, current->role->rolename,
16756+ current->role->roletype, current->uid,
16757+ current->gid, current->exec_file ?
16758+ gr_to_filename(current->exec_file->f_dentry,
16759+ current->exec_file->f_vfsmnt) :
16760+ curr->filename, curr->filename,
16761+ NIPQUAD(ip_addr), ip_port, type,
16762+ sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
16763+ return 1;
16764+ }
16765+
16766+ for (i = 0; i < curr->ip_num; i++) {
16767+ ip = *(curr->ips + i);
16768+ if (ip->iface != NULL) {
16769+ strncpy(iface, ip->iface, IFNAMSIZ - 1);
16770+ p = strchr(iface, ':');
16771+ if (p != NULL)
16772+ *p = '\0';
16773+ dev = dev_get_by_name(iface);
16774+ if (dev == NULL)
16775+ continue;
16776+ idev = in_dev_get(dev);
16777+ if (idev == NULL) {
16778+ dev_put(dev);
16779+ continue;
16780+ }
16781+ rcu_read_lock();
16782+ for_ifa(idev) {
16783+ if (!strcmp(ip->iface, ifa->ifa_label)) {
16784+ our_addr = ifa->ifa_address;
16785+ our_netmask = 0xffffffff;
16786+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
16787+ if (ret == 1) {
16788+ rcu_read_unlock();
16789+ in_dev_put(idev);
16790+ dev_put(dev);
16791+ return 1;
16792+ } else if (ret == 2) {
16793+ rcu_read_unlock();
16794+ in_dev_put(idev);
16795+ dev_put(dev);
16796+ goto denied;
16797+ }
16798+ }
16799+ } endfor_ifa(idev);
16800+ rcu_read_unlock();
16801+ in_dev_put(idev);
16802+ dev_put(dev);
16803+ } else {
16804+ our_addr = ip->addr;
16805+ our_netmask = ip->netmask;
16806+ ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
16807+ if (ret == 1)
16808+ return 1;
16809+ else if (ret == 2)
16810+ goto denied;
16811+ }
16812+ }
16813+
16814+denied:
16815+ if (mode == GR_BIND)
16816+ 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));
16817+ else if (mode == GR_CONNECT)
16818+ 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));
16819+
16820+ return 0;
16821+}
16822+
16823+int
16824+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
16825+{
16826+ return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
16827+}
16828+
16829+int
16830+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
16831+{
16832+ return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
16833+}
16834+
16835+int gr_search_listen(const struct socket *sock)
16836+{
16837+ struct sock *sk = sock->sk;
16838+ struct sockaddr_in addr;
16839+
16840+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
16841+ addr.sin_port = inet_sk(sk)->sport;
16842+
16843+ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
16844+}
16845+
16846+int gr_search_accept(const struct socket *sock)
16847+{
16848+ struct sock *sk = sock->sk;
16849+ struct sockaddr_in addr;
16850+
16851+ addr.sin_addr.s_addr = inet_sk(sk)->saddr;
16852+ addr.sin_port = inet_sk(sk)->sport;
16853+
16854+ return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
16855+}
16856+
16857+int
16858+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
16859+{
16860+ if (addr)
16861+ return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
16862+ else {
16863+ struct sockaddr_in sin;
16864+ const struct inet_sock *inet = inet_sk(sk);
16865+
16866+ sin.sin_addr.s_addr = inet->daddr;
16867+ sin.sin_port = inet->dport;
16868+
16869+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
16870+ }
16871+}
16872+
16873+int
16874+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
16875+{
16876+ struct sockaddr_in sin;
16877+
16878+ if (unlikely(skb->len < sizeof (struct udphdr)))
16879+ return 1; // skip this packet
16880+
16881+ sin.sin_addr.s_addr = skb->nh.iph->saddr;
16882+ sin.sin_port = skb->h.uh->source;
16883+
16884+ return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
16885+}
16886diff -urNp linux-2.6.19.1/grsecurity/gracl_learn.c linux-2.6.19.1/grsecurity/gracl_learn.c
16887--- linux-2.6.19.1/grsecurity/gracl_learn.c 1969-12-31 19:00:00.000000000 -0500
16888+++ linux-2.6.19.1/grsecurity/gracl_learn.c 2006-12-03 15:16:32.000000000 -0500
16889@@ -0,0 +1,204 @@
16890+#include <linux/kernel.h>
16891+#include <linux/mm.h>
16892+#include <linux/sched.h>
16893+#include <linux/poll.h>
16894+#include <linux/smp_lock.h>
16895+#include <linux/string.h>
16896+#include <linux/file.h>
16897+#include <linux/types.h>
16898+#include <linux/vmalloc.h>
16899+#include <linux/grinternal.h>
16900+
16901+extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
16902+ size_t count, loff_t *ppos);
16903+extern int gr_acl_is_enabled(void);
16904+
16905+static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
16906+static int gr_learn_attached;
16907+
16908+/* use a 512k buffer */
16909+#define LEARN_BUFFER_SIZE (512 * 1024)
16910+
16911+static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
16912+static DECLARE_MUTEX(gr_learn_user_sem);
16913+
16914+/* we need to maintain two buffers, so that the kernel context of grlearn
16915+ uses a semaphore around the userspace copying, and the other kernel contexts
16916+ use a spinlock when copying into the buffer, since they cannot sleep
16917+*/
16918+static char *learn_buffer;
16919+static char *learn_buffer_user;
16920+static int learn_buffer_len;
16921+static int learn_buffer_user_len;
16922+
16923+static ssize_t
16924+read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
16925+{
16926+ DECLARE_WAITQUEUE(wait, current);
16927+ ssize_t retval = 0;
16928+
16929+ add_wait_queue(&learn_wait, &wait);
16930+ set_current_state(TASK_INTERRUPTIBLE);
16931+ do {
16932+ down(&gr_learn_user_sem);
16933+ spin_lock(&gr_learn_lock);
16934+ if (learn_buffer_len)
16935+ break;
16936+ spin_unlock(&gr_learn_lock);
16937+ up(&gr_learn_user_sem);
16938+ if (file->f_flags & O_NONBLOCK) {
16939+ retval = -EAGAIN;
16940+ goto out;
16941+ }
16942+ if (signal_pending(current)) {
16943+ retval = -ERESTARTSYS;
16944+ goto out;
16945+ }
16946+
16947+ schedule();
16948+ } while (1);
16949+
16950+ memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
16951+ learn_buffer_user_len = learn_buffer_len;
16952+ retval = learn_buffer_len;
16953+ learn_buffer_len = 0;
16954+
16955+ spin_unlock(&gr_learn_lock);
16956+
16957+ if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
16958+ retval = -EFAULT;
16959+
16960+ up(&gr_learn_user_sem);
16961+out:
16962+ set_current_state(TASK_RUNNING);
16963+ remove_wait_queue(&learn_wait, &wait);
16964+ return retval;
16965+}
16966+
16967+static unsigned int
16968+poll_learn(struct file * file, poll_table * wait)
16969+{
16970+ poll_wait(file, &learn_wait, wait);
16971+
16972+ if (learn_buffer_len)
16973+ return (POLLIN | POLLRDNORM);
16974+
16975+ return 0;
16976+}
16977+
16978+void
16979+gr_clear_learn_entries(void)
16980+{
16981+ char *tmp;
16982+
16983+ down(&gr_learn_user_sem);
16984+ if (learn_buffer != NULL) {
16985+ spin_lock(&gr_learn_lock);
16986+ tmp = learn_buffer;
16987+ learn_buffer = NULL;
16988+ spin_unlock(&gr_learn_lock);
16989+ vfree(learn_buffer);
16990+ }
16991+ if (learn_buffer_user != NULL) {
16992+ vfree(learn_buffer_user);
16993+ learn_buffer_user = NULL;
16994+ }
16995+ learn_buffer_len = 0;
16996+ up(&gr_learn_user_sem);
16997+
16998+ return;
16999+}
17000+
17001+void
17002+gr_add_learn_entry(const char *fmt, ...)
17003+{
17004+ va_list args;
17005+ unsigned int len;
17006+
17007+ if (!gr_learn_attached)
17008+ return;
17009+
17010+ spin_lock(&gr_learn_lock);
17011+
17012+ /* leave a gap at the end so we know when it's "full" but don't have to
17013+ compute the exact length of the string we're trying to append
17014+ */
17015+ if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
17016+ spin_unlock(&gr_learn_lock);
17017+ wake_up_interruptible(&learn_wait);
17018+ return;
17019+ }
17020+ if (learn_buffer == NULL) {
17021+ spin_unlock(&gr_learn_lock);
17022+ return;
17023+ }
17024+
17025+ va_start(args, fmt);
17026+ len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
17027+ va_end(args);
17028+
17029+ learn_buffer_len += len + 1;
17030+
17031+ spin_unlock(&gr_learn_lock);
17032+ wake_up_interruptible(&learn_wait);
17033+
17034+ return;
17035+}
17036+
17037+static int
17038+open_learn(struct inode *inode, struct file *file)
17039+{
17040+ if (file->f_mode & FMODE_READ && gr_learn_attached)
17041+ return -EBUSY;
17042+ if (file->f_mode & FMODE_READ) {
17043+ down(&gr_learn_user_sem);
17044+ if (learn_buffer == NULL)
17045+ learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
17046+ if (learn_buffer_user == NULL)
17047+ learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
17048+ if (learn_buffer == NULL)
17049+ return -ENOMEM;
17050+ if (learn_buffer_user == NULL)
17051+ return -ENOMEM;
17052+ learn_buffer_len = 0;
17053+ learn_buffer_user_len = 0;
17054+ gr_learn_attached = 1;
17055+ up(&gr_learn_user_sem);
17056+ }
17057+ return 0;
17058+}
17059+
17060+static int
17061+close_learn(struct inode *inode, struct file *file)
17062+{
17063+ char *tmp;
17064+
17065+ if (file->f_mode & FMODE_READ) {
17066+ down(&gr_learn_user_sem);
17067+ if (learn_buffer != NULL) {
17068+ spin_lock(&gr_learn_lock);
17069+ tmp = learn_buffer;
17070+ learn_buffer = NULL;
17071+ spin_unlock(&gr_learn_lock);
17072+ vfree(tmp);
17073+ }
17074+ if (learn_buffer_user != NULL) {
17075+ vfree(learn_buffer_user);
17076+ learn_buffer_user = NULL;
17077+ }
17078+ learn_buffer_len = 0;
17079+ learn_buffer_user_len = 0;
17080+ gr_learn_attached = 0;
17081+ up(&gr_learn_user_sem);
17082+ }
17083+
17084+ return 0;
17085+}
17086+
17087+struct file_operations grsec_fops = {
17088+ .read = read_learn,
17089+ .write = write_grsec_handler,
17090+ .open = open_learn,
17091+ .release = close_learn,
17092+ .poll = poll_learn,
17093+};
17094diff -urNp linux-2.6.19.1/grsecurity/gracl_res.c linux-2.6.19.1/grsecurity/gracl_res.c
17095--- linux-2.6.19.1/grsecurity/gracl_res.c 1969-12-31 19:00:00.000000000 -0500
17096+++ linux-2.6.19.1/grsecurity/gracl_res.c 2006-12-03 15:16:32.000000000 -0500
17097@@ -0,0 +1,45 @@
17098+#include <linux/kernel.h>
17099+#include <linux/sched.h>
17100+#include <linux/gracl.h>
17101+#include <linux/grinternal.h>
17102+
17103+static const char *restab_log[] = {
17104+ [RLIMIT_CPU] = "RLIMIT_CPU",
17105+ [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
17106+ [RLIMIT_DATA] = "RLIMIT_DATA",
17107+ [RLIMIT_STACK] = "RLIMIT_STACK",
17108+ [RLIMIT_CORE] = "RLIMIT_CORE",
17109+ [RLIMIT_RSS] = "RLIMIT_RSS",
17110+ [RLIMIT_NPROC] = "RLIMIT_NPROC",
17111+ [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
17112+ [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
17113+ [RLIMIT_AS] = "RLIMIT_AS",
17114+ [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
17115+ [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
17116+};
17117+
17118+void
17119+gr_log_resource(const struct task_struct *task,
17120+ const int res, const unsigned long wanted, const int gt)
17121+{
17122+ if (res == RLIMIT_NPROC &&
17123+ (cap_raised(task->cap_effective, CAP_SYS_ADMIN) ||
17124+ cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
17125+ return;
17126+ else if (res == RLIMIT_MEMLOCK &&
17127+ cap_raised(task->cap_effective, CAP_IPC_LOCK))
17128+ return;
17129+
17130+ if (!gr_acl_is_enabled() && !grsec_resource_logging)
17131+ return;
17132+
17133+ preempt_disable();
17134+
17135+ if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
17136+ (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
17137+ task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
17138+ gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
17139+ preempt_enable_no_resched();
17140+
17141+ return;
17142+}
17143diff -urNp linux-2.6.19.1/grsecurity/gracl_segv.c linux-2.6.19.1/grsecurity/gracl_segv.c
17144--- linux-2.6.19.1/grsecurity/gracl_segv.c 1969-12-31 19:00:00.000000000 -0500
17145+++ linux-2.6.19.1/grsecurity/gracl_segv.c 2006-12-03 15:16:32.000000000 -0500
17146@@ -0,0 +1,295 @@
17147+#include <linux/kernel.h>
17148+#include <linux/mm.h>
17149+#include <asm/uaccess.h>
17150+#include <asm/errno.h>
17151+#include <asm/mman.h>
17152+#include <net/sock.h>
17153+#include <linux/file.h>
17154+#include <linux/fs.h>
17155+#include <linux/net.h>
17156+#include <linux/in.h>
17157+#include <linux/smp_lock.h>
17158+#include <linux/slab.h>
17159+#include <linux/types.h>
17160+#include <linux/sched.h>
17161+#include <linux/timer.h>
17162+#include <linux/gracl.h>
17163+#include <linux/grsecurity.h>
17164+#include <linux/grinternal.h>
17165+
17166+static struct crash_uid *uid_set;
17167+static unsigned short uid_used;
17168+static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
17169+extern rwlock_t gr_inode_lock;
17170+extern struct acl_subject_label *
17171+ lookup_acl_subj_label(const ino_t inode, const dev_t dev,
17172+ struct acl_role_label *role);
17173+extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
17174+
17175+int
17176+gr_init_uidset(void)
17177+{
17178+ uid_set =
17179+ kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
17180+ uid_used = 0;
17181+
17182+ return uid_set ? 1 : 0;
17183+}
17184+
17185+void
17186+gr_free_uidset(void)
17187+{
17188+ if (uid_set)
17189+ kfree(uid_set);
17190+
17191+ return;
17192+}
17193+
17194+int
17195+gr_find_uid(const uid_t uid)
17196+{
17197+ struct crash_uid *tmp = uid_set;
17198+ uid_t buid;
17199+ int low = 0, high = uid_used - 1, mid;
17200+
17201+ while (high >= low) {
17202+ mid = (low + high) >> 1;
17203+ buid = tmp[mid].uid;
17204+ if (buid == uid)
17205+ return mid;
17206+ if (buid > uid)
17207+ high = mid - 1;
17208+ if (buid < uid)
17209+ low = mid + 1;
17210+ }
17211+
17212+ return -1;
17213+}
17214+
17215+static __inline__ void
17216+gr_insertsort(void)
17217+{
17218+ unsigned short i, j;
17219+ struct crash_uid index;
17220+
17221+ for (i = 1; i < uid_used; i++) {
17222+ index = uid_set[i];
17223+ j = i;
17224+ while ((j > 0) && uid_set[j - 1].uid > index.uid) {
17225+ uid_set[j] = uid_set[j - 1];
17226+ j--;
17227+ }
17228+ uid_set[j] = index;
17229+ }
17230+
17231+ return;
17232+}
17233+
17234+static __inline__ void
17235+gr_insert_uid(const uid_t uid, const unsigned long expires)
17236+{
17237+ int loc;
17238+
17239+ if (uid_used == GR_UIDTABLE_MAX)
17240+ return;
17241+
17242+ loc = gr_find_uid(uid);
17243+
17244+ if (loc >= 0) {
17245+ uid_set[loc].expires = expires;
17246+ return;
17247+ }
17248+
17249+ uid_set[uid_used].uid = uid;
17250+ uid_set[uid_used].expires = expires;
17251+ uid_used++;
17252+
17253+ gr_insertsort();
17254+
17255+ return;
17256+}
17257+
17258+void
17259+gr_remove_uid(const unsigned short loc)
17260+{
17261+ unsigned short i;
17262+
17263+ for (i = loc + 1; i < uid_used; i++)
17264+ uid_set[i - 1] = uid_set[i];
17265+
17266+ uid_used--;
17267+
17268+ return;
17269+}
17270+
17271+int
17272+gr_check_crash_uid(const uid_t uid)
17273+{
17274+ int loc;
17275+ int ret = 0;
17276+
17277+ if (unlikely(!gr_acl_is_enabled()))
17278+ return 0;
17279+
17280+ spin_lock(&gr_uid_lock);
17281+ loc = gr_find_uid(uid);
17282+
17283+ if (loc < 0)
17284+ goto out_unlock;
17285+
17286+ if (time_before_eq(uid_set[loc].expires, get_seconds()))
17287+ gr_remove_uid(loc);
17288+ else
17289+ ret = 1;
17290+
17291+out_unlock:
17292+ spin_unlock(&gr_uid_lock);
17293+ return ret;
17294+}
17295+
17296+static __inline__ int
17297+proc_is_setxid(const struct task_struct *task)
17298+{
17299+ if (task->uid != task->euid || task->uid != task->suid ||
17300+ task->uid != task->fsuid)
17301+ return 1;
17302+ if (task->gid != task->egid || task->gid != task->sgid ||
17303+ task->gid != task->fsgid)
17304+ return 1;
17305+
17306+ return 0;
17307+}
17308+static __inline__ int
17309+gr_fake_force_sig(int sig, struct task_struct *t)
17310+{
17311+ unsigned long int flags;
17312+ int ret;
17313+
17314+ spin_lock_irqsave(&t->sighand->siglock, flags);
17315+ if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
17316+ t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
17317+ sigdelset(&t->blocked, sig);
17318+ recalc_sigpending_tsk(t);
17319+ }
17320+ ret = specific_send_sig_info(sig, (void*)1L, t);
17321+ spin_unlock_irqrestore(&t->sighand->siglock, flags);
17322+
17323+ return ret;
17324+}
17325+
17326+void
17327+gr_handle_crash(struct task_struct *task, const int sig)
17328+{
17329+ struct acl_subject_label *curr;
17330+ struct acl_subject_label *curr2;
17331+ struct task_struct *tsk, *tsk2;
17332+
17333+ if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
17334+ return;
17335+
17336+ if (unlikely(!gr_acl_is_enabled()))
17337+ return;
17338+
17339+ curr = task->acl;
17340+
17341+ if (!(curr->resmask & (1 << GR_CRASH_RES)))
17342+ return;
17343+
17344+ if (time_before_eq(curr->expires, get_seconds())) {
17345+ curr->expires = 0;
17346+ curr->crashes = 0;
17347+ }
17348+
17349+ curr->crashes++;
17350+
17351+ if (!curr->expires)
17352+ curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
17353+
17354+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
17355+ time_after(curr->expires, get_seconds())) {
17356+ if (task->uid && proc_is_setxid(task)) {
17357+ gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
17358+ spin_lock(&gr_uid_lock);
17359+ gr_insert_uid(task->uid, curr->expires);
17360+ spin_unlock(&gr_uid_lock);
17361+ curr->expires = 0;
17362+ curr->crashes = 0;
17363+ read_lock(&tasklist_lock);
17364+ do_each_thread(tsk2, tsk) {
17365+ if (tsk != task && tsk->uid == task->uid)
17366+ gr_fake_force_sig(SIGKILL, tsk);
17367+ } while_each_thread(tsk2, tsk);
17368+ read_unlock(&tasklist_lock);
17369+ } else {
17370+ gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
17371+ read_lock(&tasklist_lock);
17372+ do_each_thread(tsk2, tsk) {
17373+ if (likely(tsk != task)) {
17374+ curr2 = tsk->acl;
17375+
17376+ if (curr2->device == curr->device &&
17377+ curr2->inode == curr->inode)
17378+ gr_fake_force_sig(SIGKILL, tsk);
17379+ }
17380+ } while_each_thread(tsk2, tsk);
17381+ read_unlock(&tasklist_lock);
17382+ }
17383+ }
17384+
17385+ return;
17386+}
17387+
17388+int
17389+gr_check_crash_exec(const struct file *filp)
17390+{
17391+ struct acl_subject_label *curr;
17392+
17393+ if (unlikely(!gr_acl_is_enabled()))
17394+ return 0;
17395+
17396+ read_lock(&gr_inode_lock);
17397+ curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
17398+ filp->f_dentry->d_inode->i_sb->s_dev,
17399+ current->role);
17400+ read_unlock(&gr_inode_lock);
17401+
17402+ if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
17403+ (!curr->crashes && !curr->expires))
17404+ return 0;
17405+
17406+ if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
17407+ time_after(curr->expires, get_seconds()))
17408+ return 1;
17409+ else if (time_before_eq(curr->expires, get_seconds())) {
17410+ curr->crashes = 0;
17411+ curr->expires = 0;
17412+ }
17413+
17414+ return 0;
17415+}
17416+
17417+void
17418+gr_handle_alertkill(struct task_struct *task)
17419+{
17420+ struct acl_subject_label *curracl;
17421+ __u32 curr_ip;
17422+ struct task_struct *p, *p2;
17423+
17424+ if (unlikely(!gr_acl_is_enabled()))
17425+ return;
17426+
17427+ curracl = task->acl;
17428+ curr_ip = task->signal->curr_ip;
17429+
17430+ if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
17431+ read_lock(&tasklist_lock);
17432+ do_each_thread(p2, p) {
17433+ if (p->signal->curr_ip == curr_ip)
17434+ gr_fake_force_sig(SIGKILL, p);
17435+ } while_each_thread(p2, p);
17436+ read_unlock(&tasklist_lock);
17437+ } else if (curracl->mode & GR_KILLPROC)
17438+ gr_fake_force_sig(SIGKILL, task);
17439+
17440+ return;
17441+}
17442diff -urNp linux-2.6.19.1/grsecurity/gracl_shm.c linux-2.6.19.1/grsecurity/gracl_shm.c
17443--- linux-2.6.19.1/grsecurity/gracl_shm.c 1969-12-31 19:00:00.000000000 -0500
17444+++ linux-2.6.19.1/grsecurity/gracl_shm.c 2006-12-03 15:16:32.000000000 -0500
fbd7084a 17445@@ -0,0 +1,34 @@
c3e8c1b5 17446+#include <linux/kernel.h>
17447+#include <linux/mm.h>
17448+#include <linux/sched.h>
17449+#include <linux/file.h>
17450+#include <linux/ipc.h>
17451+#include <linux/gracl.h>
17452+#include <linux/grsecurity.h>
17453+#include <linux/grinternal.h>
fbd7084a 17454+#include <linux/vs_pid.h>
c3e8c1b5 17455+
17456+int
17457+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17458+ const time_t shm_createtime, const uid_t cuid, const int shmid)
17459+{
17460+ struct task_struct *task;
17461+
17462+ if (!gr_acl_is_enabled())
17463+ return 1;
17464+
17465+ task = find_task_by_pid(shm_cprid);
17466+
17467+ if (unlikely(!task))
17468+ task = find_task_by_pid(shm_lapid);
17469+
17470+ if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
17471+ (task->pid == shm_lapid)) &&
17472+ (task->acl->mode & GR_PROTSHM) &&
17473+ (task->acl != current->acl))) {
17474+ gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
17475+ return 0;
17476+ }
17477+
17478+ return 1;
17479+}
17480diff -urNp linux-2.6.19.1/grsecurity/grsec_chdir.c linux-2.6.19.1/grsecurity/grsec_chdir.c
17481--- linux-2.6.19.1/grsecurity/grsec_chdir.c 1969-12-31 19:00:00.000000000 -0500
17482+++ linux-2.6.19.1/grsecurity/grsec_chdir.c 2006-12-03 15:16:32.000000000 -0500
17483@@ -0,0 +1,19 @@
17484+#include <linux/kernel.h>
17485+#include <linux/sched.h>
17486+#include <linux/fs.h>
17487+#include <linux/file.h>
17488+#include <linux/grsecurity.h>
17489+#include <linux/grinternal.h>
17490+
17491+void
17492+gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
17493+{
17494+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
17495+ if ((grsec_enable_chdir && grsec_enable_group &&
17496+ in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
17497+ !grsec_enable_group)) {
17498+ gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
17499+ }
17500+#endif
17501+ return;
17502+}
17503diff -urNp linux-2.6.19.1/grsecurity/grsec_chroot.c linux-2.6.19.1/grsecurity/grsec_chroot.c
17504--- linux-2.6.19.1/grsecurity/grsec_chroot.c 1969-12-31 19:00:00.000000000 -0500
17505+++ linux-2.6.19.1/grsecurity/grsec_chroot.c 2006-12-03 15:16:32.000000000 -0500
17506@@ -0,0 +1,332 @@
17507+#include <linux/kernel.h>
17508+#include <linux/module.h>
17509+#include <linux/sched.h>
17510+#include <linux/file.h>
17511+#include <linux/fs.h>
17512+#include <linux/mount.h>
17513+#include <linux/types.h>
17514+#include <linux/grinternal.h>
17515+
17516+int
17517+gr_handle_chroot_unix(const pid_t pid)
17518+{
17519+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
17520+ struct pid *spid = NULL;
17521+
17522+ if (unlikely(!grsec_enable_chroot_unix))
17523+ return 1;
17524+
17525+ if (likely(!proc_is_chrooted(current)))
17526+ return 1;
17527+
17528+ read_lock(&tasklist_lock);
17529+
17530+ spid = find_pid(pid);
17531+ if (spid) {
17532+ struct task_struct *p;
17533+ p = pid_task(spid, PIDTYPE_PID);
17534+ task_lock(p);
17535+ if (unlikely(!have_same_root(current, p))) {
17536+ task_unlock(p);
17537+ read_unlock(&tasklist_lock);
17538+ gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
17539+ return 0;
17540+ }
17541+ task_unlock(p);
17542+ }
17543+ read_unlock(&tasklist_lock);
17544+#endif
17545+ return 1;
17546+}
17547+
17548+int
17549+gr_handle_chroot_nice(void)
17550+{
17551+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17552+ if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
17553+ gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
17554+ return -EPERM;
17555+ }
17556+#endif
17557+ return 0;
17558+}
17559+
17560+int
17561+gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
17562+{
17563+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
17564+ if (grsec_enable_chroot_nice && (niceval < task_nice(p))
17565+ && proc_is_chrooted(current)) {
17566+ gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
17567+ return -EACCES;
17568+ }
17569+#endif
17570+ return 0;
17571+}
17572+
17573+int
17574+gr_handle_chroot_rawio(const struct inode *inode)
17575+{
17576+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17577+ if (grsec_enable_chroot_caps && proc_is_chrooted(current) &&
17578+ inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
17579+ return 1;
17580+#endif
17581+ return 0;
17582+}
17583+
17584+int
17585+gr_pid_is_chrooted(struct task_struct *p)
17586+{
17587+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
17588+ if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !p)
17589+ return 0;
17590+
17591+ task_lock(p);
17592+ if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
17593+ !have_same_root(current, p)) {
17594+ task_unlock(p);
17595+ return 1;
17596+ }
17597+ task_unlock(p);
17598+#endif
17599+ return 0;
17600+}
17601+
17602+EXPORT_SYMBOL(gr_pid_is_chrooted);
17603+
17604+#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
17605+int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
17606+{
17607+ struct dentry *dentry = (struct dentry *)u_dentry;
17608+ struct vfsmount *mnt = (struct vfsmount *)u_mnt;
17609+ struct dentry *realroot;
17610+ struct vfsmount *realrootmnt;
17611+ struct dentry *currentroot;
17612+ struct vfsmount *currentmnt;
17613+ int ret = 1;
17614+
17615+ read_lock(&child_reaper->fs->lock);
17616+ realrootmnt = mntget(child_reaper->fs->rootmnt);
17617+ realroot = dget(child_reaper->fs->root);
17618+ read_unlock(&child_reaper->fs->lock);
17619+
17620+ read_lock(&current->fs->lock);
17621+ currentmnt = mntget(current->fs->rootmnt);
17622+ currentroot = dget(current->fs->root);
17623+ read_unlock(&current->fs->lock);
17624+
17625+ spin_lock(&dcache_lock);
17626+ for (;;) {
17627+ if (unlikely((dentry == realroot && mnt == realrootmnt)
17628+ || (dentry == currentroot && mnt == currentmnt)))
17629+ break;
17630+ if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
17631+ if (mnt->mnt_parent == mnt)
17632+ break;
17633+ dentry = mnt->mnt_mountpoint;
17634+ mnt = mnt->mnt_parent;
17635+ continue;
17636+ }
17637+ dentry = dentry->d_parent;
17638+ }
17639+ spin_unlock(&dcache_lock);
17640+
17641+ dput(currentroot);
17642+ mntput(currentmnt);
17643+
17644+ /* access is outside of chroot */
17645+ if (dentry == realroot && mnt == realrootmnt)
17646+ ret = 0;
17647+
17648+ dput(realroot);
17649+ mntput(realrootmnt);
17650+ return ret;
17651+}
17652+#endif
17653+
17654+int
17655+gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
17656+{
17657+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
17658+ if (!grsec_enable_chroot_fchdir)
17659+ return 1;
17660+
17661+ if (!proc_is_chrooted(current))
17662+ return 1;
17663+ else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
17664+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
17665+ return 0;
17666+ }
17667+#endif
17668+ return 1;
17669+}
17670+
17671+int
17672+gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
17673+ const time_t shm_createtime)
17674+{
17675+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
17676+ struct pid *pid = NULL;
17677+ time_t starttime;
17678+
17679+ if (unlikely(!grsec_enable_chroot_shmat))
17680+ return 1;
17681+
17682+ if (likely(!proc_is_chrooted(current)))
17683+ return 1;
17684+
17685+ read_lock(&tasklist_lock);
17686+
17687+ pid = find_pid(shm_cprid);
17688+ if (pid) {
17689+ struct task_struct *p;
17690+ p = pid_task(pid, PIDTYPE_PID);
17691+ task_lock(p);
17692+ starttime = p->start_time.tv_sec;
17693+ if (unlikely(!have_same_root(current, p) &&
17694+ time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
17695+ task_unlock(p);
17696+ read_unlock(&tasklist_lock);
17697+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
17698+ return 0;
17699+ }
17700+ task_unlock(p);
17701+ } else {
17702+ pid = find_pid(shm_lapid);
17703+ if (pid) {
17704+ struct task_struct *p;
17705+ p = pid_task(pid, PIDTYPE_PID);
17706+ task_lock(p);
17707+ if (unlikely(!have_same_root(current, p))) {
17708+ task_unlock(p);
17709+ read_unlock(&tasklist_lock);
17710+ gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
17711+ return 0;
17712+ }
17713+ task_unlock(p);
17714+ }
17715+ }
17716+
17717+ read_unlock(&tasklist_lock);
17718+#endif
17719+ return 1;
17720+}
17721+
17722+void
17723+gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
17724+{
17725+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
17726+ if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
17727+ gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
17728+#endif
17729+ return;
17730+}
17731+
17732+int
17733+gr_handle_chroot_mknod(const struct dentry *dentry,
17734+ const struct vfsmount *mnt, const int mode)
17735+{
17736+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
17737+ if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) &&
17738+ proc_is_chrooted(current)) {
17739+ gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
17740+ return -EPERM;
17741+ }
17742+#endif
17743+ return 0;
17744+}
17745+
17746+int
17747+gr_handle_chroot_mount(const struct dentry *dentry,
17748+ const struct vfsmount *mnt, const char *dev_name)
17749+{
17750+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
17751+ if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
17752+ gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
17753+ return -EPERM;
17754+ }
17755+#endif
17756+ return 0;
17757+}
17758+
17759+int
17760+gr_handle_chroot_pivot(void)
17761+{
17762+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
17763+ if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
17764+ gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
17765+ return -EPERM;
17766+ }
17767+#endif
17768+ return 0;
17769+}
17770+
17771+int
17772+gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
17773+{
17774+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
17775+ if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
17776+ !gr_is_outside_chroot(dentry, mnt)) {
17777+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
17778+ return -EPERM;
17779+ }
17780+#endif
17781+ return 0;
17782+}
17783+
17784+void
17785+gr_handle_chroot_caps(struct task_struct *task)
17786+{
17787+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17788+ if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
17789+ task->cap_permitted =
17790+ cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
17791+ task->cap_inheritable =
17792+ cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
17793+ task->cap_effective =
17794+ cap_drop(task->cap_effective, GR_CHROOT_CAPS);
17795+ }
17796+#endif
17797+ return;
17798+}
17799+
17800+int
17801+gr_handle_chroot_sysctl(const int op)
17802+{
17803+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
17804+ if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
17805+ && (op & 002))
17806+ return -EACCES;
17807+#endif
17808+ return 0;
17809+}
17810+
17811+void
17812+gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
17813+{
17814+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
17815+ if (grsec_enable_chroot_chdir)
17816+ set_fs_pwd(current->fs, mnt, dentry);
17817+#endif
17818+ return;
17819+}
17820+
17821+int
17822+gr_handle_chroot_chmod(const struct dentry *dentry,
17823+ const struct vfsmount *mnt, const int mode)
17824+{
17825+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
17826+ if (grsec_enable_chroot_chmod &&
17827+ ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
17828+ proc_is_chrooted(current)) {
17829+ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
17830+ return -EPERM;
17831+ }
17832+#endif
17833+ return 0;
17834+}
17835+
17836+#ifdef CONFIG_SECURITY
17837+EXPORT_SYMBOL(gr_handle_chroot_caps);
17838+#endif
17839diff -urNp linux-2.6.19.1/grsecurity/grsec_disabled.c linux-2.6.19.1/grsecurity/grsec_disabled.c
17840--- linux-2.6.19.1/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
17841+++ linux-2.6.19.1/grsecurity/grsec_disabled.c 2006-12-03 16:58:13.000000000 -0500
17842@@ -0,0 +1,417 @@
17843+#include <linux/kernel.h>
17844+#include <linux/module.h>
17845+#include <linux/sched.h>
17846+#include <linux/file.h>
17847+#include <linux/fs.h>
17848+#include <linux/kdev_t.h>
17849+#include <linux/net.h>
17850+#include <linux/in.h>
17851+#include <linux/ip.h>
17852+#include <linux/skbuff.h>
17853+#include <linux/sysctl.h>
17854+
17855+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17856+void
17857+pax_set_initial_flags(struct linux_binprm *bprm)
17858+{
17859+ return;
17860+}
17861+#endif
17862+
17863+#ifdef CONFIG_SYSCTL
17864+__u32
17865+gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
17866+{
17867+ return mode;
17868+}
17869+#endif
17870+
17871+int
17872+gr_acl_is_enabled(void)
17873+{
17874+ return 0;
17875+}
17876+
17877+int
17878+gr_handle_rawio(const struct inode *inode)
17879+{
17880+ return 0;
17881+}
17882+
17883+void
17884+gr_acl_handle_psacct(struct task_struct *task, const long code)
17885+{
17886+ return;
17887+}
17888+
17889+int
17890+gr_handle_ptrace(struct task_struct *task, const long request)
17891+{
17892+ return 0;
17893+}
17894+
17895+int
17896+gr_handle_proc_ptrace(struct task_struct *task)
17897+{
17898+ return 0;
17899+}
17900+
17901+void
17902+gr_learn_resource(const struct task_struct *task,
17903+ const int res, const unsigned long wanted, const int gt)
17904+{
17905+ return;
17906+}
17907+
17908+int
17909+gr_set_acls(const int type)
17910+{
17911+ return 0;
17912+}
17913+
17914+int
17915+gr_check_hidden_task(const struct task_struct *tsk)
17916+{
17917+ return 0;
17918+}
17919+
17920+int
17921+gr_check_protected_task(const struct task_struct *task)
17922+{
17923+ return 0;
17924+}
17925+
17926+void
17927+gr_copy_label(struct task_struct *tsk)
17928+{
17929+ return;
17930+}
17931+
17932+void
17933+gr_set_pax_flags(struct task_struct *task)
17934+{
17935+ return;
17936+}
17937+
17938+int
17939+gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
17940+{
17941+ return 0;
17942+}
17943+
17944+void
17945+gr_handle_delete(const ino_t ino, const dev_t dev)
17946+{
17947+ return;
17948+}
17949+
17950+void
17951+gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
17952+{
17953+ return;
17954+}
17955+
17956+void
17957+gr_handle_crash(struct task_struct *task, const int sig)
17958+{
17959+ return;
17960+}
17961+
17962+int
17963+gr_check_crash_exec(const struct file *filp)
17964+{
17965+ return 0;
17966+}
17967+
17968+int
17969+gr_check_crash_uid(const uid_t uid)
17970+{
17971+ return 0;
17972+}
17973+
17974+void
17975+gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
17976+ struct dentry *old_dentry,
17977+ struct dentry *new_dentry,
17978+ struct vfsmount *mnt, const __u8 replace)
17979+{
17980+ return;
17981+}
17982+
17983+int
17984+gr_search_socket(const int family, const int type, const int protocol)
17985+{
17986+ return 1;
17987+}
17988+
17989+int
17990+gr_search_connectbind(const int mode, const struct socket *sock,
17991+ const struct sockaddr_in *addr)
17992+{
17993+ return 1;
17994+}
17995+
17996+int
17997+gr_task_is_capable(struct task_struct *task, const int cap)
17998+{
17999+ return 1;
18000+}
18001+
18002+int
18003+gr_is_capable_nolog(const int cap)
18004+{
18005+ return 1;
18006+}
18007+
18008+void
18009+gr_handle_alertkill(struct task_struct *task)
18010+{
18011+ return;
18012+}
18013+
18014+__u32
18015+gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
18016+{
18017+ return 1;
18018+}
18019+
18020+__u32
18021+gr_acl_handle_hidden_file(const struct dentry * dentry,
18022+ const struct vfsmount * mnt)
18023+{
18024+ return 1;
18025+}
18026+
18027+__u32
18028+gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
18029+ const int fmode)
18030+{
18031+ return 1;
18032+}
18033+
18034+__u32
18035+gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
18036+{
18037+ return 1;
18038+}
18039+
18040+__u32
18041+gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
18042+{
18043+ return 1;
18044+}
18045+
18046+int
18047+gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
18048+ unsigned int *vm_flags)
18049+{
18050+ return 1;
18051+}
18052+
18053+__u32
18054+gr_acl_handle_truncate(const struct dentry * dentry,
18055+ const struct vfsmount * mnt)
18056+{
18057+ return 1;
18058+}
18059+
18060+__u32
18061+gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
18062+{
18063+ return 1;
18064+}
18065+
18066+__u32
18067+gr_acl_handle_access(const struct dentry * dentry,
18068+ const struct vfsmount * mnt, const int fmode)
18069+{
18070+ return 1;
18071+}
18072+
18073+__u32
18074+gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
18075+ mode_t mode)
18076+{
18077+ return 1;
18078+}
18079+
18080+__u32
18081+gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
18082+ mode_t mode)
18083+{
18084+ return 1;
18085+}
18086+
18087+__u32
18088+gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
18089+{
18090+ return 1;
18091+}
18092+
18093+void
18094+grsecurity_init(void)
18095+{
18096+ return;
18097+}
18098+
18099+__u32
18100+gr_acl_handle_mknod(const struct dentry * new_dentry,
18101+ const struct dentry * parent_dentry,
18102+ const struct vfsmount * parent_mnt,
18103+ const int mode)
18104+{
18105+ return 1;
18106+}
18107+
18108+__u32
18109+gr_acl_handle_mkdir(const struct dentry * new_dentry,
18110+ const struct dentry * parent_dentry,
18111+ const struct vfsmount * parent_mnt)
18112+{
18113+ return 1;
18114+}
18115+
18116+__u32
18117+gr_acl_handle_symlink(const struct dentry * new_dentry,
18118+ const struct dentry * parent_dentry,
18119+ const struct vfsmount * parent_mnt, const char *from)
18120+{
18121+ return 1;
18122+}
18123+
18124+__u32
18125+gr_acl_handle_link(const struct dentry * new_dentry,
18126+ const struct dentry * parent_dentry,
18127+ const struct vfsmount * parent_mnt,
18128+ const struct dentry * old_dentry,
18129+ const struct vfsmount * old_mnt, const char *to)
18130+{
18131+ return 1;
18132+}
18133+
18134+int
18135+gr_acl_handle_rename(const struct dentry *new_dentry,
18136+ const struct dentry *parent_dentry,
18137+ const struct vfsmount *parent_mnt,
18138+ const struct dentry *old_dentry,
18139+ const struct inode *old_parent_inode,
18140+ const struct vfsmount *old_mnt, const char *newname)
18141+{
18142+ return 0;
18143+}
18144+
18145+int
18146+gr_acl_handle_filldir(const struct file *file, const char *name,
18147+ const int namelen, const ino_t ino)
18148+{
18149+ return 1;
18150+}
18151+
18152+int
18153+gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
18154+ const time_t shm_createtime, const uid_t cuid, const int shmid)
18155+{
18156+ return 1;
18157+}
18158+
18159+int
18160+gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
18161+{
18162+ return 1;
18163+}
18164+
18165+int
18166+gr_search_accept(const struct socket *sock)
18167+{
18168+ return 1;
18169+}
18170+
18171+int
18172+gr_search_listen(const struct socket *sock)
18173+{
18174+ return 1;
18175+}
18176+
18177+int
18178+gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
18179+{
18180+ return 1;
18181+}
18182+
18183+__u32
18184+gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
18185+{
18186+ return 1;
18187+}
18188+
18189+__u32
18190+gr_acl_handle_creat(const struct dentry * dentry,
18191+ const struct dentry * p_dentry,
18192+ const struct vfsmount * p_mnt, const int fmode,
18193+ const int imode)
18194+{
18195+ return 1;
18196+}
18197+
18198+void
18199+gr_acl_handle_exit(void)
18200+{
18201+ return;
18202+}
18203+
18204+int
18205+gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
18206+{
18207+ return 1;
18208+}
18209+
18210+void
18211+gr_set_role_label(const uid_t uid, const gid_t gid)
18212+{
18213+ return;
18214+}
18215+
18216+int
18217+gr_acl_handle_procpidmem(const struct task_struct *task)
18218+{
18219+ return 0;
18220+}
18221+
18222+int
18223+gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
18224+{
18225+ return 1;
18226+}
18227+
18228+int
18229+gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
18230+{
18231+ return 1;
18232+}
18233+
18234+void
18235+gr_set_kernel_label(struct task_struct *task)
18236+{
18237+ return;
18238+}
18239+
18240+int
18241+gr_check_user_change(int real, int effective, int fs)
18242+{
18243+ return 0;
18244+}
18245+
18246+int
18247+gr_check_group_change(int real, int effective, int fs)
18248+{
18249+ return 0;
18250+}
18251+
18252+
18253+EXPORT_SYMBOL(gr_task_is_capable);
18254+EXPORT_SYMBOL(gr_learn_resource);
18255+EXPORT_SYMBOL(gr_set_kernel_label);
18256+#ifdef CONFIG_SECURITY
18257+EXPORT_SYMBOL(gr_check_user_change);
18258+EXPORT_SYMBOL(gr_check_group_change);
18259+#endif
18260diff -urNp linux-2.6.19.1/grsecurity/grsec_exec.c linux-2.6.19.1/grsecurity/grsec_exec.c
18261--- linux-2.6.19.1/grsecurity/grsec_exec.c 1969-12-31 19:00:00.000000000 -0500
18262+++ linux-2.6.19.1/grsecurity/grsec_exec.c 2006-12-03 15:16:32.000000000 -0500
18263@@ -0,0 +1,88 @@
18264+#include <linux/kernel.h>
18265+#include <linux/sched.h>
18266+#include <linux/file.h>
18267+#include <linux/binfmts.h>
18268+#include <linux/smp_lock.h>
18269+#include <linux/fs.h>
18270+#include <linux/types.h>
18271+#include <linux/grdefs.h>
18272+#include <linux/grinternal.h>
18273+#include <linux/capability.h>
18274+
18275+#include <asm/uaccess.h>
18276+
18277+#ifdef CONFIG_GRKERNSEC_EXECLOG
18278+static char gr_exec_arg_buf[132];
18279+static DECLARE_MUTEX(gr_exec_arg_sem);
18280+#endif
18281+
18282+int
18283+gr_handle_nproc(void)
18284+{
18285+#ifdef CONFIG_GRKERNSEC_EXECVE
18286+ if (grsec_enable_execve && current->user &&
18287+ (atomic_read(&current->user->processes) >
18288+ current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
18289+ !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
18290+ gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
18291+ return -EAGAIN;
18292+ }
18293+#endif
18294+ return 0;
18295+}
18296+
18297+void
18298+gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
18299+{
18300+#ifdef CONFIG_GRKERNSEC_EXECLOG
18301+ char *grarg = gr_exec_arg_buf;
18302+ unsigned int i, x, execlen = 0;
18303+ char c;
18304+
18305+ if (!((grsec_enable_execlog && grsec_enable_group &&
18306+ in_group_p(grsec_audit_gid))
18307+ || (grsec_enable_execlog && !grsec_enable_group)))
18308+ return;
18309+
18310+ down(&gr_exec_arg_sem);
18311+ memset(grarg, 0, sizeof(gr_exec_arg_buf));
18312+
18313+ if (unlikely(argv == NULL))
18314+ goto log;
18315+
18316+ for (i = 0; i < bprm->argc && execlen < 128; i++) {
18317+ const char __user *p;
18318+ unsigned int len;
18319+
18320+ if (copy_from_user(&p, argv + i, sizeof(p)))
18321+ goto log;
18322+ if (!p)
18323+ goto log;
18324+ len = strnlen_user(p, 128 - execlen);
18325+ if (len > 128 - execlen)
18326+ len = 128 - execlen;
18327+ else if (len > 0)
18328+ len--;
18329+ if (copy_from_user(grarg + execlen, p, len))
18330+ goto log;
18331+
18332+ /* rewrite unprintable characters */
18333+ for (x = 0; x < len; x++) {
18334+ c = *(grarg + execlen + x);
18335+ if (c < 32 || c > 126)
18336+ *(grarg + execlen + x) = ' ';
18337+ }
18338+
18339+ execlen += len;
18340+ *(grarg + execlen) = ' ';
18341+ *(grarg + execlen + 1) = '\0';
18342+ execlen++;
18343+ }
18344+
18345+ log:
18346+ gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
18347+ bprm->file->f_vfsmnt, grarg);
18348+ up(&gr_exec_arg_sem);
18349+#endif
18350+ return;
18351+}
18352diff -urNp linux-2.6.19.1/grsecurity/grsec_fifo.c linux-2.6.19.1/grsecurity/grsec_fifo.c
18353--- linux-2.6.19.1/grsecurity/grsec_fifo.c 1969-12-31 19:00:00.000000000 -0500
18354+++ linux-2.6.19.1/grsecurity/grsec_fifo.c 2006-12-03 15:16:32.000000000 -0500
18355@@ -0,0 +1,22 @@
18356+#include <linux/kernel.h>
18357+#include <linux/sched.h>
18358+#include <linux/fs.h>
18359+#include <linux/file.h>
18360+#include <linux/grinternal.h>
18361+
18362+int
18363+gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
18364+ const struct dentry *dir, const int flag, const int acc_mode)
18365+{
18366+#ifdef CONFIG_GRKERNSEC_FIFO
18367+ if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
18368+ !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
18369+ (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
18370+ (current->fsuid != dentry->d_inode->i_uid)) {
18371+ if (!generic_permission(dentry->d_inode, acc_mode, NULL))
18372+ gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
18373+ return -EACCES;
18374+ }
18375+#endif
18376+ return 0;
18377+}
18378diff -urNp linux-2.6.19.1/grsecurity/grsec_fork.c linux-2.6.19.1/grsecurity/grsec_fork.c
18379--- linux-2.6.19.1/grsecurity/grsec_fork.c 1969-12-31 19:00:00.000000000 -0500
18380+++ linux-2.6.19.1/grsecurity/grsec_fork.c 2006-12-03 15:16:32.000000000 -0500
18381@@ -0,0 +1,15 @@
18382+#include <linux/kernel.h>
18383+#include <linux/sched.h>
18384+#include <linux/grsecurity.h>
18385+#include <linux/grinternal.h>
18386+#include <linux/errno.h>
18387+
18388+void
18389+gr_log_forkfail(const int retval)
18390+{
18391+#ifdef CONFIG_GRKERNSEC_FORKFAIL
18392+ if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
18393+ gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
18394+#endif
18395+ return;
18396+}
18397diff -urNp linux-2.6.19.1/grsecurity/grsec_init.c linux-2.6.19.1/grsecurity/grsec_init.c
18398--- linux-2.6.19.1/grsecurity/grsec_init.c 1969-12-31 19:00:00.000000000 -0500
18399+++ linux-2.6.19.1/grsecurity/grsec_init.c 2006-12-03 15:16:32.000000000 -0500
18400@@ -0,0 +1,236 @@
18401+#include <linux/kernel.h>
18402+#include <linux/sched.h>
18403+#include <linux/mm.h>
18404+#include <linux/smp_lock.h>
18405+#include <linux/gracl.h>
18406+#include <linux/slab.h>
18407+#include <linux/vmalloc.h>
18408+#include <linux/percpu.h>
18409+
18410+int grsec_enable_shm;
18411+int grsec_enable_link;
18412+int grsec_enable_dmesg;
18413+int grsec_enable_fifo;
18414+int grsec_enable_execve;
18415+int grsec_enable_execlog;
18416+int grsec_enable_signal;
18417+int grsec_enable_forkfail;
18418+int grsec_enable_time;
18419+int grsec_enable_audit_textrel;
18420+int grsec_enable_group;
18421+int grsec_audit_gid;
18422+int grsec_enable_chdir;
18423+int grsec_enable_audit_ipc;
18424+int grsec_enable_mount;
18425+int grsec_enable_chroot_findtask;
18426+int grsec_enable_chroot_mount;
18427+int grsec_enable_chroot_shmat;
18428+int grsec_enable_chroot_fchdir;
18429+int grsec_enable_chroot_double;
18430+int grsec_enable_chroot_pivot;
18431+int grsec_enable_chroot_chdir;
18432+int grsec_enable_chroot_chmod;
18433+int grsec_enable_chroot_mknod;
18434+int grsec_enable_chroot_nice;
18435+int grsec_enable_chroot_execlog;
18436+int grsec_enable_chroot_caps;
18437+int grsec_enable_chroot_sysctl;
18438+int grsec_enable_chroot_unix;
18439+int grsec_enable_tpe;
18440+int grsec_tpe_gid;
18441+int grsec_enable_tpe_all;
18442+int grsec_enable_randpid;
18443+int grsec_enable_socket_all;
18444+int grsec_socket_all_gid;
18445+int grsec_enable_socket_client;
18446+int grsec_socket_client_gid;
18447+int grsec_enable_socket_server;
18448+int grsec_socket_server_gid;
18449+int grsec_resource_logging;
18450+int grsec_lock;
18451+
18452+spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
18453+unsigned long grsec_alert_wtime = 0;
18454+unsigned long grsec_alert_fyet = 0;
18455+
18456+spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
18457+
18458+rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
18459+
18460+char *gr_shared_page[4];
18461+
18462+char *gr_alert_log_fmt;
18463+char *gr_audit_log_fmt;
18464+char *gr_alert_log_buf;
18465+char *gr_audit_log_buf;
18466+
18467+extern struct gr_arg *gr_usermode;
18468+extern unsigned char *gr_system_salt;
18469+extern unsigned char *gr_system_sum;
18470+
18471+void
18472+grsecurity_init(void)
18473+{
18474+ int j;
18475+ /* create the per-cpu shared pages */
18476+
18477+ preempt_disable();
18478+ for (j = 0; j < 4; j++) {
18479+ gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
18480+ if (gr_shared_page[j] == NULL) {
18481+ panic("Unable to allocate grsecurity shared page");
18482+ return;
18483+ }
18484+ }
18485+ preempt_enable();
18486+
18487+ /* allocate log buffers */
18488+ gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
18489+ if (!gr_alert_log_fmt) {
18490+ panic("Unable to allocate grsecurity alert log format buffer");
18491+ return;
18492+ }
18493+ gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
18494+ if (!gr_audit_log_fmt) {
18495+ panic("Unable to allocate grsecurity audit log format buffer");
18496+ return;
18497+ }
18498+ gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
18499+ if (!gr_alert_log_buf) {
18500+ panic("Unable to allocate grsecurity alert log buffer");
18501+ return;
18502+ }
18503+ gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
18504+ if (!gr_audit_log_buf) {
18505+ panic("Unable to allocate grsecurity audit log buffer");
18506+ return;
18507+ }
18508+
18509+ /* allocate memory for authentication structure */
18510+ gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
18511+ gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
18512+ gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
18513+
18514+ if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
18515+ panic("Unable to allocate grsecurity authentication structure");
18516+ return;
18517+ }
18518+
18519+#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
18520+#ifndef CONFIG_GRKERNSEC_SYSCTL
18521+ grsec_lock = 1;
18522+#endif
18523+#ifdef CONFIG_GRKERNSEC_SHM
18524+ grsec_enable_shm = 1;
18525+#endif
18526+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
18527+ grsec_enable_audit_textrel = 1;
18528+#endif
18529+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
18530+ grsec_enable_group = 1;
18531+ grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
18532+#endif
18533+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
18534+ grsec_enable_chdir = 1;
18535+#endif
18536+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18537+ grsec_enable_audit_ipc = 1;
18538+#endif
18539+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
18540+ grsec_enable_mount = 1;
18541+#endif
18542+#ifdef CONFIG_GRKERNSEC_LINK
18543+ grsec_enable_link = 1;
18544+#endif
18545+#ifdef CONFIG_GRKERNSEC_DMESG
18546+ grsec_enable_dmesg = 1;
18547+#endif
18548+#ifdef CONFIG_GRKERNSEC_FIFO
18549+ grsec_enable_fifo = 1;
18550+#endif
18551+#ifdef CONFIG_GRKERNSEC_EXECVE
18552+ grsec_enable_execve = 1;
18553+#endif
18554+#ifdef CONFIG_GRKERNSEC_EXECLOG
18555+ grsec_enable_execlog = 1;
18556+#endif
18557+#ifdef CONFIG_GRKERNSEC_SIGNAL
18558+ grsec_enable_signal = 1;
18559+#endif
18560+#ifdef CONFIG_GRKERNSEC_FORKFAIL
18561+ grsec_enable_forkfail = 1;
18562+#endif
18563+#ifdef CONFIG_GRKERNSEC_TIME
18564+ grsec_enable_time = 1;
18565+#endif
18566+#ifdef CONFIG_GRKERNSEC_RESLOG
18567+ grsec_resource_logging = 1;
18568+#endif
18569+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
18570+ grsec_enable_chroot_findtask = 1;
18571+#endif
18572+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
18573+ grsec_enable_chroot_unix = 1;
18574+#endif
18575+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
18576+ grsec_enable_chroot_mount = 1;
18577+#endif
18578+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
18579+ grsec_enable_chroot_fchdir = 1;
18580+#endif
18581+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
18582+ grsec_enable_chroot_shmat = 1;
18583+#endif
18584+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
18585+ grsec_enable_chroot_double = 1;
18586+#endif
18587+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
18588+ grsec_enable_chroot_pivot = 1;
18589+#endif
18590+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
18591+ grsec_enable_chroot_chdir = 1;
18592+#endif
18593+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
18594+ grsec_enable_chroot_chmod = 1;
18595+#endif
18596+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
18597+ grsec_enable_chroot_mknod = 1;
18598+#endif
18599+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
18600+ grsec_enable_chroot_nice = 1;
18601+#endif
18602+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
18603+ grsec_enable_chroot_execlog = 1;
18604+#endif
18605+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
18606+ grsec_enable_chroot_caps = 1;
18607+#endif
18608+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
18609+ grsec_enable_chroot_sysctl = 1;
18610+#endif
18611+#ifdef CONFIG_GRKERNSEC_TPE
18612+ grsec_enable_tpe = 1;
18613+ grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
18614+#ifdef CONFIG_GRKERNSEC_TPE_ALL
18615+ grsec_enable_tpe_all = 1;
18616+#endif
18617+#endif
18618+#ifdef CONFIG_GRKERNSEC_RANDPID
18619+ grsec_enable_randpid = 1;
18620+#endif
18621+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
18622+ grsec_enable_socket_all = 1;
18623+ grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
18624+#endif
18625+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
18626+ grsec_enable_socket_client = 1;
18627+ grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
18628+#endif
18629+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
18630+ grsec_enable_socket_server = 1;
18631+ grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
18632+#endif
18633+#endif
18634+
18635+ return;
18636+}
18637diff -urNp linux-2.6.19.1/grsecurity/grsec_ipc.c linux-2.6.19.1/grsecurity/grsec_ipc.c
18638--- linux-2.6.19.1/grsecurity/grsec_ipc.c 1969-12-31 19:00:00.000000000 -0500
18639+++ linux-2.6.19.1/grsecurity/grsec_ipc.c 2006-12-03 15:16:32.000000000 -0500
18640@@ -0,0 +1,81 @@
18641+#include <linux/kernel.h>
18642+#include <linux/sched.h>
18643+#include <linux/types.h>
18644+#include <linux/ipc.h>
18645+#include <linux/grsecurity.h>
18646+#include <linux/grinternal.h>
18647+
18648+void
18649+gr_log_msgget(const int ret, const int msgflg)
18650+{
18651+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18652+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18653+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
18654+ !grsec_enable_group)) && (ret >= 0)
18655+ && (msgflg & IPC_CREAT))
18656+ gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
18657+#endif
18658+ return;
18659+}
18660+
18661+void
18662+gr_log_msgrm(const uid_t uid, const uid_t cuid)
18663+{
18664+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18665+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18666+ grsec_enable_audit_ipc) ||
18667+ (grsec_enable_audit_ipc && !grsec_enable_group))
18668+ gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
18669+#endif
18670+ return;
18671+}
18672+
18673+void
18674+gr_log_semget(const int err, const int semflg)
18675+{
18676+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18677+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18678+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
18679+ !grsec_enable_group)) && (err >= 0)
18680+ && (semflg & IPC_CREAT))
18681+ gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
18682+#endif
18683+ return;
18684+}
18685+
18686+void
18687+gr_log_semrm(const uid_t uid, const uid_t cuid)
18688+{
18689+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18690+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18691+ grsec_enable_audit_ipc) ||
18692+ (grsec_enable_audit_ipc && !grsec_enable_group))
18693+ gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
18694+#endif
18695+ return;
18696+}
18697+
18698+void
18699+gr_log_shmget(const int err, const int shmflg, const size_t size)
18700+{
18701+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18702+ if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18703+ grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
18704+ !grsec_enable_group)) && (err >= 0)
18705+ && (shmflg & IPC_CREAT))
18706+ gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
18707+#endif
18708+ return;
18709+}
18710+
18711+void
18712+gr_log_shmrm(const uid_t uid, const uid_t cuid)
18713+{
18714+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
18715+ if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
18716+ grsec_enable_audit_ipc) ||
18717+ (grsec_enable_audit_ipc && !grsec_enable_group))
18718+ gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
18719+#endif
18720+ return;
18721+}
18722diff -urNp linux-2.6.19.1/grsecurity/grsec_link.c linux-2.6.19.1/grsecurity/grsec_link.c
18723--- linux-2.6.19.1/grsecurity/grsec_link.c 1969-12-31 19:00:00.000000000 -0500
18724+++ linux-2.6.19.1/grsecurity/grsec_link.c 2006-12-03 15:16:32.000000000 -0500
18725@@ -0,0 +1,39 @@
18726+#include <linux/kernel.h>
18727+#include <linux/sched.h>
18728+#include <linux/fs.h>
18729+#include <linux/file.h>
18730+#include <linux/grinternal.h>
18731+
18732+int
18733+gr_handle_follow_link(const struct inode *parent,
18734+ const struct inode *inode,
18735+ const struct dentry *dentry, const struct vfsmount *mnt)
18736+{
18737+#ifdef CONFIG_GRKERNSEC_LINK
18738+ if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
18739+ (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
18740+ (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
18741+ gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
18742+ return -EACCES;
18743+ }
18744+#endif
18745+ return 0;
18746+}
18747+
18748+int
18749+gr_handle_hardlink(const struct dentry *dentry,
18750+ const struct vfsmount *mnt,
18751+ struct inode *inode, const int mode, const char *to)
18752+{
18753+#ifdef CONFIG_GRKERNSEC_LINK
18754+ if (grsec_enable_link && current->fsuid != inode->i_uid &&
18755+ (!S_ISREG(mode) || (mode & S_ISUID) ||
18756+ ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
18757+ (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
18758+ !capable(CAP_FOWNER) && current->uid) {
18759+ gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
18760+ return -EPERM;
18761+ }
18762+#endif
18763+ return 0;
18764+}
18765diff -urNp linux-2.6.19.1/grsecurity/grsec_log.c linux-2.6.19.1/grsecurity/grsec_log.c
18766--- linux-2.6.19.1/grsecurity/grsec_log.c 1969-12-31 19:00:00.000000000 -0500
18767+++ linux-2.6.19.1/grsecurity/grsec_log.c 2006-12-03 15:16:32.000000000 -0500
18768@@ -0,0 +1,265 @@
18769+#include <linux/kernel.h>
18770+#include <linux/sched.h>
18771+#include <linux/file.h>
18772+#include <linux/tty.h>
18773+#include <linux/fs.h>
18774+#include <linux/grinternal.h>
18775+
18776+#define BEGIN_LOCKS(x) \
18777+ read_lock(&tasklist_lock); \
18778+ read_lock(&grsec_exec_file_lock); \
18779+ if (x != GR_DO_AUDIT) \
18780+ spin_lock(&grsec_alert_lock); \
18781+ else \
18782+ spin_lock(&grsec_audit_lock)
18783+
18784+#define END_LOCKS(x) \
18785+ if (x != GR_DO_AUDIT) \
18786+ spin_unlock(&grsec_alert_lock); \
18787+ else \
18788+ spin_unlock(&grsec_audit_lock); \
18789+ read_unlock(&grsec_exec_file_lock); \
18790+ read_unlock(&tasklist_lock); \
18791+ if (x == GR_DONT_AUDIT) \
18792+ gr_handle_alertkill(current)
18793+
18794+enum {
18795+ FLOODING,
18796+ NO_FLOODING
18797+};
18798+
18799+extern char *gr_alert_log_fmt;
18800+extern char *gr_audit_log_fmt;
18801+extern char *gr_alert_log_buf;
18802+extern char *gr_audit_log_buf;
18803+
18804+static int gr_log_start(int audit)
18805+{
18806+ char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
18807+ char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
18808+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18809+
18810+ if (audit == GR_DO_AUDIT)
18811+ goto set_fmt;
18812+
18813+ if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
18814+ grsec_alert_wtime = jiffies;
18815+ grsec_alert_fyet = 0;
18816+ } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
18817+ grsec_alert_fyet++;
18818+ } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
18819+ grsec_alert_wtime = jiffies;
18820+ grsec_alert_fyet++;
18821+ printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
18822+ return FLOODING;
18823+ } else return FLOODING;
18824+
18825+set_fmt:
18826+ memset(buf, 0, PAGE_SIZE);
18827+ if (current->signal->curr_ip && gr_acl_is_enabled()) {
18828+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
18829+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
18830+ } else if (current->signal->curr_ip) {
18831+ sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
18832+ snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
18833+ } else if (gr_acl_is_enabled()) {
18834+ sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
18835+ snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
18836+ } else {
18837+ sprintf(fmt, "%s%s", loglevel, "grsec: ");
18838+ strcpy(buf, fmt);
18839+ }
18840+
18841+ return NO_FLOODING;
18842+}
18843+
18844+static void gr_log_middle(int audit, const char *msg, va_list ap)
18845+{
18846+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18847+ unsigned int len = strlen(buf);
18848+
18849+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
18850+
18851+ return;
18852+}
18853+
18854+static void gr_log_middle_varargs(int audit, const char *msg, ...)
18855+{
18856+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18857+ unsigned int len = strlen(buf);
18858+ va_list ap;
18859+
18860+ va_start(ap, msg);
18861+ vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
18862+ va_end(ap);
18863+
18864+ return;
18865+}
18866+
18867+static void gr_log_end(int audit)
18868+{
18869+ char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
18870+ unsigned int len = strlen(buf);
18871+
18872+ snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
18873+ printk("%s\n", buf);
18874+
18875+ return;
18876+}
18877+
18878+void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
18879+{
18880+ int logtype;
18881+ char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
18882+ char *str1, *str2, *str3;
18883+ int num1, num2;
18884+ unsigned long ulong1, ulong2;
18885+ struct dentry *dentry;
18886+ struct vfsmount *mnt;
18887+ struct file *file;
18888+ struct task_struct *task;
18889+ va_list ap;
18890+
18891+ BEGIN_LOCKS(audit);
18892+ logtype = gr_log_start(audit);
18893+ if (logtype == FLOODING) {
18894+ END_LOCKS(audit);
18895+ return;
18896+ }
18897+ va_start(ap, argtypes);
18898+ switch (argtypes) {
18899+ case GR_TTYSNIFF:
18900+ task = va_arg(ap, struct task_struct *);
18901+ 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);
18902+ break;
18903+ case GR_RBAC:
18904+ dentry = va_arg(ap, struct dentry *);
18905+ mnt = va_arg(ap, struct vfsmount *);
18906+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
18907+ break;
18908+ case GR_RBAC_STR:
18909+ dentry = va_arg(ap, struct dentry *);
18910+ mnt = va_arg(ap, struct vfsmount *);
18911+ str1 = va_arg(ap, char *);
18912+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
18913+ break;
18914+ case GR_STR_RBAC:
18915+ str1 = va_arg(ap, char *);
18916+ dentry = va_arg(ap, struct dentry *);
18917+ mnt = va_arg(ap, struct vfsmount *);
18918+ gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
18919+ break;
18920+ case GR_RBAC_MODE2:
18921+ dentry = va_arg(ap, struct dentry *);
18922+ mnt = va_arg(ap, struct vfsmount *);
18923+ str1 = va_arg(ap, char *);
18924+ str2 = va_arg(ap, char *);
18925+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
18926+ break;
18927+ case GR_RBAC_MODE3:
18928+ dentry = va_arg(ap, struct dentry *);
18929+ mnt = va_arg(ap, struct vfsmount *);
18930+ str1 = va_arg(ap, char *);
18931+ str2 = va_arg(ap, char *);
18932+ str3 = va_arg(ap, char *);
18933+ gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
18934+ break;
18935+ case GR_FILENAME:
18936+ dentry = va_arg(ap, struct dentry *);
18937+ mnt = va_arg(ap, struct vfsmount *);
18938+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
18939+ break;
18940+ case GR_STR_FILENAME:
18941+ str1 = va_arg(ap, char *);
18942+ dentry = va_arg(ap, struct dentry *);
18943+ mnt = va_arg(ap, struct vfsmount *);
18944+ gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
18945+ break;
18946+ case GR_FILENAME_STR:
18947+ dentry = va_arg(ap, struct dentry *);
18948+ mnt = va_arg(ap, struct vfsmount *);
18949+ str1 = va_arg(ap, char *);
18950+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
18951+ break;
18952+ case GR_FILENAME_TWO_INT:
18953+ dentry = va_arg(ap, struct dentry *);
18954+ mnt = va_arg(ap, struct vfsmount *);
18955+ num1 = va_arg(ap, int);
18956+ num2 = va_arg(ap, int);
18957+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
18958+ break;
18959+ case GR_FILENAME_TWO_INT_STR:
18960+ dentry = va_arg(ap, struct dentry *);
18961+ mnt = va_arg(ap, struct vfsmount *);
18962+ num1 = va_arg(ap, int);
18963+ num2 = va_arg(ap, int);
18964+ str1 = va_arg(ap, char *);
18965+ gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
18966+ break;
18967+ case GR_TEXTREL:
18968+ file = va_arg(ap, struct file *);
18969+ ulong1 = va_arg(ap, unsigned long);
18970+ ulong2 = va_arg(ap, unsigned long);
18971+ gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
18972+ break;
18973+ case GR_PTRACE:
18974+ task = va_arg(ap, struct task_struct *);
18975+ 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);
18976+ break;
18977+ case GR_RESOURCE:
18978+ task = va_arg(ap, struct task_struct *);
18979+ ulong1 = va_arg(ap, unsigned long);
18980+ str1 = va_arg(ap, char *);
18981+ ulong2 = va_arg(ap, unsigned long);
18982+ 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);
18983+ break;
18984+ case GR_CAP:
18985+ task = va_arg(ap, struct task_struct *);
18986+ str1 = va_arg(ap, char *);
18987+ 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);
18988+ break;
18989+ case GR_SIG:
18990+ task = va_arg(ap, struct task_struct *);
18991+ num1 = va_arg(ap, int);
18992+ 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);
18993+ break;
18994+ case GR_CRASH1:
18995+ task = va_arg(ap, struct task_struct *);
18996+ ulong1 = va_arg(ap, unsigned long);
18997+ 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);
18998+ break;
18999+ case GR_CRASH2:
19000+ task = va_arg(ap, struct task_struct *);
19001+ ulong1 = va_arg(ap, unsigned long);
19002+ 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);
19003+ break;
19004+ case GR_PSACCT:
19005+ {
19006+ unsigned int wday, cday;
19007+ __u8 whr, chr;
19008+ __u8 wmin, cmin;
19009+ __u8 wsec, csec;
19010+ char cur_tty[64] = { 0 };
19011+ char parent_tty[64] = { 0 };
19012+
19013+ task = va_arg(ap, struct task_struct *);
19014+ wday = va_arg(ap, unsigned int);
19015+ cday = va_arg(ap, unsigned int);
19016+ whr = va_arg(ap, int);
19017+ chr = va_arg(ap, int);
19018+ wmin = va_arg(ap, int);
19019+ cmin = va_arg(ap, int);
19020+ wsec = va_arg(ap, int);
19021+ csec = va_arg(ap, int);
19022+ ulong1 = va_arg(ap, unsigned long);
19023+
19024+ 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);
19025+ }
19026+ break;
19027+ default:
19028+ gr_log_middle(audit, msg, ap);
19029+ }
19030+ va_end(ap);
19031+ gr_log_end(audit);
19032+ END_LOCKS(audit);
19033+}
19034diff -urNp linux-2.6.19.1/grsecurity/grsec_mem.c linux-2.6.19.1/grsecurity/grsec_mem.c
19035--- linux-2.6.19.1/grsecurity/grsec_mem.c 1969-12-31 19:00:00.000000000 -0500
19036+++ linux-2.6.19.1/grsecurity/grsec_mem.c 2006-12-03 15:16:32.000000000 -0500
19037@@ -0,0 +1,71 @@
19038+#include <linux/kernel.h>
19039+#include <linux/sched.h>
19040+#include <linux/mm.h>
19041+#include <linux/mman.h>
19042+#include <linux/grinternal.h>
19043+
19044+void
19045+gr_handle_ioperm(void)
19046+{
19047+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
19048+ return;
19049+}
19050+
19051+void
19052+gr_handle_iopl(void)
19053+{
19054+ gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
19055+ return;
19056+}
19057+
19058+void
19059+gr_handle_mem_write(void)
19060+{
19061+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
19062+ return;
19063+}
19064+
19065+void
19066+gr_handle_kmem_write(void)
19067+{
19068+ gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
19069+ return;
19070+}
19071+
19072+void
19073+gr_handle_open_port(void)
19074+{
19075+ gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
19076+ return;
19077+}
19078+
19079+int
19080+gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
19081+{
19082+ unsigned long start, end;
19083+
19084+ start = offset;
19085+ end = start + vma->vm_end - vma->vm_start;
19086+
19087+ if (start > end) {
19088+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
19089+ return -EPERM;
19090+ }
19091+
19092+ /* allowed ranges : ISA I/O BIOS */
19093+ if ((start >= __pa(high_memory))
19094+#ifdef CONFIG_X86
19095+ || (start >= 0x000a0000 && end <= 0x00100000)
19096+ || (start >= 0x00000000 && end <= 0x00001000)
19097+#endif
19098+ )
19099+ return 0;
19100+
19101+ if (vma->vm_flags & VM_WRITE) {
19102+ gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
19103+ return -EPERM;
19104+ } else
19105+ vma->vm_flags &= ~VM_MAYWRITE;
19106+
19107+ return 0;
19108+}
19109diff -urNp linux-2.6.19.1/grsecurity/grsec_mount.c linux-2.6.19.1/grsecurity/grsec_mount.c
19110--- linux-2.6.19.1/grsecurity/grsec_mount.c 1969-12-31 19:00:00.000000000 -0500
19111+++ linux-2.6.19.1/grsecurity/grsec_mount.c 2006-12-03 15:16:32.000000000 -0500
19112@@ -0,0 +1,34 @@
19113+#include <linux/kernel.h>
19114+#include <linux/sched.h>
19115+#include <linux/grsecurity.h>
19116+#include <linux/grinternal.h>
19117+
19118+void
19119+gr_log_remount(const char *devname, const int retval)
19120+{
19121+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
19122+ if (grsec_enable_mount && (retval >= 0))
19123+ gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
19124+#endif
19125+ return;
19126+}
19127+
19128+void
19129+gr_log_unmount(const char *devname, const int retval)
19130+{
19131+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
19132+ if (grsec_enable_mount && (retval >= 0))
19133+ gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
19134+#endif
19135+ return;
19136+}
19137+
19138+void
19139+gr_log_mount(const char *from, const char *to, const int retval)
19140+{
19141+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
19142+ if (grsec_enable_mount && (retval >= 0))
19143+ gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
19144+#endif
19145+ return;
19146+}
19147diff -urNp linux-2.6.19.1/grsecurity/grsec_rand.c linux-2.6.19.1/grsecurity/grsec_rand.c
19148--- linux-2.6.19.1/grsecurity/grsec_rand.c 1969-12-31 19:00:00.000000000 -0500
19149+++ linux-2.6.19.1/grsecurity/grsec_rand.c 2006-12-03 15:16:32.000000000 -0500
19150@@ -0,0 +1,26 @@
19151+#include <linux/kernel.h>
19152+#include <linux/sched.h>
19153+#include <linux/smp_lock.h>
19154+#include <linux/grsecurity.h>
19155+#include <linux/grinternal.h>
19156+
19157+extern int pid_max;
19158+
19159+int
19160+gr_random_pid(void)
19161+{
19162+#ifdef CONFIG_GRKERNSEC_RANDPID
19163+ int pid;
19164+
19165+ if (grsec_enable_randpid && current->fs->root) {
19166+ /* return a pid in the range 1 ... pid_max - 1
19167+ optimize this so we don't have to do a real division
19168+ */
19169+ pid = 1 + (get_random_long() % pid_max);
19170+ if (pid == pid_max)
19171+ pid = pid_max - 1;
19172+ return pid;
19173+ }
19174+#endif
19175+ return 0;
19176+}
19177diff -urNp linux-2.6.19.1/grsecurity/grsec_sig.c linux-2.6.19.1/grsecurity/grsec_sig.c
19178--- linux-2.6.19.1/grsecurity/grsec_sig.c 1969-12-31 19:00:00.000000000 -0500
19179+++ linux-2.6.19.1/grsecurity/grsec_sig.c 2006-12-03 15:16:32.000000000 -0500
19180@@ -0,0 +1,59 @@
19181+#include <linux/kernel.h>
19182+#include <linux/sched.h>
19183+#include <linux/grsecurity.h>
19184+#include <linux/grinternal.h>
19185+
19186+void
19187+gr_log_signal(const int sig, const struct task_struct *t)
19188+{
19189+#ifdef CONFIG_GRKERNSEC_SIGNAL
19190+ if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
19191+ (sig == SIGABRT) || (sig == SIGBUS))) {
19192+ if (t->pid == current->pid) {
19193+ gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
19194+ } else {
19195+ gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
19196+ }
19197+ }
19198+#endif
19199+ return;
19200+}
19201+
19202+int
19203+gr_handle_signal(const struct task_struct *p, const int sig)
19204+{
19205+#ifdef CONFIG_GRKERNSEC
19206+ if (current->pid > 1 && gr_check_protected_task(p)) {
19207+ gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
19208+ return -EPERM;
19209+ } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
19210+ return -EPERM;
19211+ }
19212+#endif
19213+ return 0;
19214+}
19215+
19216+void gr_handle_brute_attach(struct task_struct *p)
19217+{
19218+#ifdef CONFIG_GRKERNSEC_BRUTE
19219+ read_lock(&tasklist_lock);
19220+ read_lock(&grsec_exec_file_lock);
19221+ if (p->parent && p->parent->exec_file == p->exec_file)
19222+ p->parent->brute = 1;
19223+ read_unlock(&grsec_exec_file_lock);
19224+ read_unlock(&tasklist_lock);
19225+#endif
19226+ return;
19227+}
19228+
19229+void gr_handle_brute_check(void)
19230+{
19231+#ifdef CONFIG_GRKERNSEC_BRUTE
19232+ if (current->brute) {
19233+ set_current_state(TASK_UNINTERRUPTIBLE);
19234+ schedule_timeout(30 * HZ);
19235+ }
19236+#endif
19237+ return;
19238+}
19239+
19240diff -urNp linux-2.6.19.1/grsecurity/grsec_sock.c linux-2.6.19.1/grsecurity/grsec_sock.c
19241--- linux-2.6.19.1/grsecurity/grsec_sock.c 1969-12-31 19:00:00.000000000 -0500
19242+++ linux-2.6.19.1/grsecurity/grsec_sock.c 2006-12-03 15:16:32.000000000 -0500
19243@@ -0,0 +1,263 @@
19244+#include <linux/kernel.h>
19245+#include <linux/module.h>
19246+#include <linux/sched.h>
19247+#include <linux/file.h>
19248+#include <linux/net.h>
19249+#include <linux/in.h>
19250+#include <linux/ip.h>
19251+#include <net/sock.h>
19252+#include <net/inet_sock.h>
19253+#include <linux/grsecurity.h>
19254+#include <linux/grinternal.h>
19255+#include <linux/gracl.h>
19256+
19257+#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
19258+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
19259+EXPORT_SYMBOL(udp_v4_lookup);
19260+#endif
19261+
19262+EXPORT_SYMBOL(gr_cap_rtnetlink);
19263+
19264+extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
19265+extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
19266+
19267+EXPORT_SYMBOL(gr_search_udp_recvmsg);
19268+EXPORT_SYMBOL(gr_search_udp_sendmsg);
19269+
19270+#ifdef CONFIG_UNIX_MODULE
19271+EXPORT_SYMBOL(gr_acl_handle_unix);
19272+EXPORT_SYMBOL(gr_acl_handle_mknod);
19273+EXPORT_SYMBOL(gr_handle_chroot_unix);
19274+EXPORT_SYMBOL(gr_handle_create);
19275+#endif
19276+
19277+#ifdef CONFIG_GRKERNSEC
19278+#define gr_conn_table_size 32749
19279+struct conn_table_entry {
19280+ struct conn_table_entry *next;
19281+ struct signal_struct *sig;
19282+};
19283+
19284+struct conn_table_entry *gr_conn_table[gr_conn_table_size];
19285+spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
19286+
19287+extern const char * gr_socktype_to_name(unsigned char type);
19288+extern const char * gr_proto_to_name(unsigned char proto);
19289+
19290+static __inline__ int
19291+conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
19292+{
19293+ return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
19294+}
19295+
19296+static __inline__ int
19297+conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr,
19298+ __u16 sport, __u16 dport)
19299+{
19300+ if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
19301+ sig->gr_sport == sport && sig->gr_dport == dport))
19302+ return 1;
19303+ else
19304+ return 0;
19305+}
19306+
19307+static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
19308+{
19309+ struct conn_table_entry **match;
19310+ unsigned int index;
19311+
19312+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
19313+ sig->gr_sport, sig->gr_dport,
19314+ gr_conn_table_size);
19315+
19316+ newent->sig = sig;
19317+
19318+ match = &gr_conn_table[index];
19319+ newent->next = *match;
19320+ *match = newent;
19321+
19322+ return;
19323+}
19324+
19325+static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
19326+{
19327+ struct conn_table_entry *match, *last = NULL;
19328+ unsigned int index;
19329+
19330+ index = conn_hash(sig->gr_saddr, sig->gr_daddr,
19331+ sig->gr_sport, sig->gr_dport,
19332+ gr_conn_table_size);
19333+
19334+ match = gr_conn_table[index];
19335+ while (match && !conn_match(match->sig,
19336+ sig->gr_saddr, sig->gr_daddr, sig->gr_sport,
19337+ sig->gr_dport)) {
19338+ last = match;
19339+ match = match->next;
19340+ }
19341+
19342+ if (match) {
19343+ if (last)
19344+ last->next = match->next;
19345+ else
19346+ gr_conn_table[index] = NULL;
19347+ kfree(match);
19348+ }
19349+
19350+ return;
19351+}
19352+
19353+static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
19354+ __u16 sport, __u16 dport)
19355+{
19356+ struct conn_table_entry *match;
19357+ unsigned int index;
19358+
19359+ index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
19360+
19361+ match = gr_conn_table[index];
19362+ while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
19363+ match = match->next;
19364+
19365+ if (match)
19366+ return match->sig;
19367+ else
19368+ return NULL;
19369+}
19370+
19371+#endif
19372+
19373+void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
19374+{
19375+#ifdef CONFIG_GRKERNSEC
19376+ struct signal_struct *sig = task->signal;
19377+ struct conn_table_entry *newent;
19378+
19379+ newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
19380+ if (newent == NULL)
19381+ return;
19382+ /* no bh lock needed since we are called with bh disabled */
19383+ spin_lock(&gr_conn_table_lock);
19384+ gr_del_task_from_ip_table_nolock(sig);
19385+ sig->gr_saddr = inet->rcv_saddr;
19386+ sig->gr_daddr = inet->daddr;
19387+ sig->gr_sport = inet->sport;
19388+ sig->gr_dport = inet->dport;
19389+ gr_add_to_task_ip_table_nolock(sig, newent);
19390+ spin_unlock(&gr_conn_table_lock);
19391+#endif
19392+ return;
19393+}
19394+
19395+void gr_del_task_from_ip_table(struct task_struct *task)
19396+{
19397+#ifdef CONFIG_GRKERNSEC
19398+ spin_lock(&gr_conn_table_lock);
19399+ gr_del_task_from_ip_table_nolock(task->signal);
19400+ spin_unlock(&gr_conn_table_lock);
19401+#endif
19402+ return;
19403+}
19404+
19405+void
19406+gr_attach_curr_ip(const struct sock *sk)
19407+{
19408+#ifdef CONFIG_GRKERNSEC
19409+ struct signal_struct *p, *set;
19410+ const struct inet_sock *inet = inet_sk(sk);
19411+
19412+ if (unlikely(sk->sk_protocol != IPPROTO_TCP))
19413+ return;
19414+
19415+ set = current->signal;
19416+
19417+ spin_lock_bh(&gr_conn_table_lock);
19418+ p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
19419+ inet->dport, inet->sport);
19420+ if (unlikely(p != NULL)) {
19421+ set->curr_ip = p->curr_ip;
19422+ set->used_accept = 1;
19423+ gr_del_task_from_ip_table_nolock(p);
19424+ spin_unlock_bh(&gr_conn_table_lock);
19425+ return;
19426+ }
19427+ spin_unlock_bh(&gr_conn_table_lock);
19428+
19429+ set->curr_ip = inet->daddr;
19430+ set->used_accept = 1;
19431+#endif
19432+ return;
19433+}
19434+
19435+int
19436+gr_handle_sock_all(const int family, const int type, const int protocol)
19437+{
19438+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
19439+ if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
19440+ (family != AF_UNIX) && (family != AF_LOCAL)) {
19441+ gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
19442+ return -EACCES;
19443+ }
19444+#endif
19445+ return 0;
19446+}
19447+
19448+int
19449+gr_handle_sock_server(const struct sockaddr *sck)
19450+{
19451+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19452+ if (grsec_enable_socket_server &&
19453+ in_group_p(grsec_socket_server_gid) &&
19454+ sck && (sck->sa_family != AF_UNIX) &&
19455+ (sck->sa_family != AF_LOCAL)) {
19456+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
19457+ return -EACCES;
19458+ }
19459+#endif
19460+ return 0;
19461+}
19462+
19463+int
19464+gr_handle_sock_server_other(const struct sock *sck)
19465+{
19466+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19467+ if (grsec_enable_socket_server &&
19468+ in_group_p(grsec_socket_server_gid) &&
19469+ sck && (sck->sk_family != AF_UNIX) &&
19470+ (sck->sk_family != AF_LOCAL)) {
19471+ gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
19472+ return -EACCES;
19473+ }
19474+#endif
19475+ return 0;
19476+}
19477+
19478+int
19479+gr_handle_sock_client(const struct sockaddr *sck)
19480+{
19481+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
19482+ if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
19483+ sck && (sck->sa_family != AF_UNIX) &&
19484+ (sck->sa_family != AF_LOCAL)) {
19485+ gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
19486+ return -EACCES;
19487+ }
19488+#endif
19489+ return 0;
19490+}
19491+
19492+__u32
19493+gr_cap_rtnetlink(void)
19494+{
19495+#ifdef CONFIG_GRKERNSEC
19496+ if (!gr_acl_is_enabled())
19497+ return current->cap_effective;
19498+ else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
19499+ gr_task_is_capable(current, CAP_NET_ADMIN))
19500+ return current->cap_effective;
19501+ else
19502+ return 0;
19503+#else
19504+ return current->cap_effective;
19505+#endif
19506+}
19507diff -urNp linux-2.6.19.1/grsecurity/grsec_sysctl.c linux-2.6.19.1/grsecurity/grsec_sysctl.c
19508--- linux-2.6.19.1/grsecurity/grsec_sysctl.c 1969-12-31 19:00:00.000000000 -0500
19509+++ linux-2.6.19.1/grsecurity/grsec_sysctl.c 2006-12-03 15:16:32.000000000 -0500
19510@@ -0,0 +1,466 @@
19511+#include <linux/kernel.h>
19512+#include <linux/sched.h>
19513+#include <linux/sysctl.h>
19514+#include <linux/grsecurity.h>
19515+#include <linux/grinternal.h>
19516+
19517+#ifdef CONFIG_GRKERNSEC_MODSTOP
19518+int grsec_modstop;
19519+#endif
19520+
19521+int
19522+gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
19523+{
19524+#ifdef CONFIG_GRKERNSEC_SYSCTL
19525+ if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
19526+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
19527+ return -EACCES;
19528+ }
19529+#endif
19530+#ifdef CONFIG_GRKERNSEC_MODSTOP
19531+ if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
19532+ grsec_modstop && (op & 002)) {
19533+ gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
19534+ return -EACCES;
19535+ }
19536+#endif
19537+ return 0;
19538+}
19539+
19540+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
19541+enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
19542+GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
19543+GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
19544+GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
19545+GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
19546+GS_RANDPID, GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
19547+GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID,
19548+GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
19549+GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
19550+
19551+
19552+ctl_table grsecurity_table[] = {
19553+#ifdef CONFIG_GRKERNSEC_SYSCTL
19554+#ifdef CONFIG_GRKERNSEC_LINK
19555+ {
19556+ .ctl_name = GS_LINK,
19557+ .procname = "linking_restrictions",
19558+ .data = &grsec_enable_link,
19559+ .maxlen = sizeof(int),
19560+ .mode = 0600,
19561+ .proc_handler = &proc_dointvec,
19562+ },
19563+#endif
19564+#ifdef CONFIG_GRKERNSEC_FIFO
19565+ {
19566+ .ctl_name = GS_FIFO,
19567+ .procname = "fifo_restrictions",
19568+ .data = &grsec_enable_fifo,
19569+ .maxlen = sizeof(int),
19570+ .mode = 0600,
19571+ .proc_handler = &proc_dointvec,
19572+ },
19573+#endif
19574+#ifdef CONFIG_GRKERNSEC_EXECVE
19575+ {
19576+ .ctl_name = GS_EXECVE,
19577+ .procname = "execve_limiting",
19578+ .data = &grsec_enable_execve,
19579+ .maxlen = sizeof(int),
19580+ .mode = 0600,
19581+ .proc_handler = &proc_dointvec,
19582+ },
19583+#endif
19584+#ifdef CONFIG_GRKERNSEC_EXECLOG
19585+ {
19586+ .ctl_name = GS_EXECLOG,
19587+ .procname = "exec_logging",
19588+ .data = &grsec_enable_execlog,
19589+ .maxlen = sizeof(int),
19590+ .mode = 0600,
19591+ .proc_handler = &proc_dointvec,
19592+ },
19593+#endif
19594+#ifdef CONFIG_GRKERNSEC_SIGNAL
19595+ {
19596+ .ctl_name = GS_SIGNAL,
19597+ .procname = "signal_logging",
19598+ .data = &grsec_enable_signal,
19599+ .maxlen = sizeof(int),
19600+ .mode = 0600,
19601+ .proc_handler = &proc_dointvec,
19602+ },
19603+#endif
19604+#ifdef CONFIG_GRKERNSEC_FORKFAIL
19605+ {
19606+ .ctl_name = GS_FORKFAIL,
19607+ .procname = "forkfail_logging",
19608+ .data = &grsec_enable_forkfail,
19609+ .maxlen = sizeof(int),
19610+ .mode = 0600,
19611+ .proc_handler = &proc_dointvec,
19612+ },
19613+#endif
19614+#ifdef CONFIG_GRKERNSEC_TIME
19615+ {
19616+ .ctl_name = GS_TIME,
19617+ .procname = "timechange_logging",
19618+ .data = &grsec_enable_time,
19619+ .maxlen = sizeof(int),
19620+ .mode = 0600,
19621+ .proc_handler = &proc_dointvec,
19622+ },
19623+#endif
19624+#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
19625+ {
19626+ .ctl_name = GS_CHROOT_SHMAT,
19627+ .procname = "chroot_deny_shmat",
19628+ .data = &grsec_enable_chroot_shmat,
19629+ .maxlen = sizeof(int),
19630+ .mode = 0600,
19631+ .proc_handler = &proc_dointvec,
19632+ },
19633+#endif
19634+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
19635+ {
19636+ .ctl_name = GS_CHROOT_UNIX,
19637+ .procname = "chroot_deny_unix",
19638+ .data = &grsec_enable_chroot_unix,
19639+ .maxlen = sizeof(int),
19640+ .mode = 0600,
19641+ .proc_handler = &proc_dointvec,
19642+ },
19643+#endif
19644+#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
19645+ {
19646+ .ctl_name = GS_CHROOT_MNT,
19647+ .procname = "chroot_deny_mount",
19648+ .data = &grsec_enable_chroot_mount,
19649+ .maxlen = sizeof(int),
19650+ .mode = 0600,
19651+ .proc_handler = &proc_dointvec,
19652+ },
19653+#endif
19654+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
19655+ {
19656+ .ctl_name = GS_CHROOT_FCHDIR,
19657+ .procname = "chroot_deny_fchdir",
19658+ .data = &grsec_enable_chroot_fchdir,
19659+ .maxlen = sizeof(int),
19660+ .mode = 0600,
19661+ .proc_handler = &proc_dointvec,
19662+ },
19663+#endif
19664+#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
19665+ {
19666+ .ctl_name = GS_CHROOT_DBL,
19667+ .procname = "chroot_deny_chroot",
19668+ .data = &grsec_enable_chroot_double,
19669+ .maxlen = sizeof(int),
19670+ .mode = 0600,
19671+ .proc_handler = &proc_dointvec,
19672+ },
19673+#endif
19674+#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
19675+ {
19676+ .ctl_name = GS_CHROOT_PVT,
19677+ .procname = "chroot_deny_pivot",
19678+ .data = &grsec_enable_chroot_pivot,
19679+ .maxlen = sizeof(int),
19680+ .mode = 0600,
19681+ .proc_handler = &proc_dointvec,
19682+ },
19683+#endif
19684+#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
19685+ {
19686+ .ctl_name = GS_CHROOT_CD,
19687+ .procname = "chroot_enforce_chdir",
19688+ .data = &grsec_enable_chroot_chdir,
19689+ .maxlen = sizeof(int),
19690+ .mode = 0600,
19691+ .proc_handler = &proc_dointvec,
19692+ },
19693+#endif
19694+#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
19695+ {
19696+ .ctl_name = GS_CHROOT_CM,
19697+ .procname = "chroot_deny_chmod",
19698+ .data = &grsec_enable_chroot_chmod,
19699+ .maxlen = sizeof(int),
19700+ .mode = 0600,
19701+ .proc_handler = &proc_dointvec,
19702+ },
19703+#endif
19704+#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
19705+ {
19706+ .ctl_name = GS_CHROOT_MK,
19707+ .procname = "chroot_deny_mknod",
19708+ .data = &grsec_enable_chroot_mknod,
19709+ .maxlen = sizeof(int),
19710+ .mode = 0600,
19711+ .proc_handler = &proc_dointvec,
19712+ },
19713+#endif
19714+#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
19715+ {
19716+ .ctl_name = GS_CHROOT_NI,
19717+ .procname = "chroot_restrict_nice",
19718+ .data = &grsec_enable_chroot_nice,
19719+ .maxlen = sizeof(int),
19720+ .mode = 0600,
19721+ .proc_handler = &proc_dointvec,
19722+ },
19723+#endif
19724+#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
19725+ {
19726+ .ctl_name = GS_CHROOT_EXECLOG,
19727+ .procname = "chroot_execlog",
19728+ .data = &grsec_enable_chroot_execlog,
19729+ .maxlen = sizeof(int),
19730+ .mode = 0600,
19731+ .proc_handler = &proc_dointvec,
19732+ },
19733+#endif
19734+#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
19735+ {
19736+ .ctl_name = GS_CHROOT_CAPS,
19737+ .procname = "chroot_caps",
19738+ .data = &grsec_enable_chroot_caps,
19739+ .maxlen = sizeof(int),
19740+ .mode = 0600,
19741+ .proc_handler = &proc_dointvec,
19742+ },
19743+#endif
19744+#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
19745+ {
19746+ .ctl_name = GS_CHROOT_SYSCTL,
19747+ .procname = "chroot_deny_sysctl",
19748+ .data = &grsec_enable_chroot_sysctl,
19749+ .maxlen = sizeof(int),
19750+ .mode = 0600,
19751+ .proc_handler = &proc_dointvec,
19752+ },
19753+#endif
19754+#ifdef CONFIG_GRKERNSEC_TPE
19755+ {
19756+ .ctl_name = GS_TPE,
19757+ .procname = "tpe",
19758+ .data = &grsec_enable_tpe,
19759+ .maxlen = sizeof(int),
19760+ .mode = 0600,
19761+ .proc_handler = &proc_dointvec,
19762+ },
19763+ {
19764+ .ctl_name = GS_TPE_GID,
19765+ .procname = "tpe_gid",
19766+ .data = &grsec_tpe_gid,
19767+ .maxlen = sizeof(int),
19768+ .mode = 0600,
19769+ .proc_handler = &proc_dointvec,
19770+ },
19771+#endif
19772+#ifdef CONFIG_GRKERNSEC_TPE_ALL
19773+ {
19774+ .ctl_name = GS_TPE_ALL,
19775+ .procname = "tpe_restrict_all",
19776+ .data = &grsec_enable_tpe_all,
19777+ .maxlen = sizeof(int),
19778+ .mode = 0600,
19779+ .proc_handler = &proc_dointvec,
19780+ },
19781+#endif
19782+#ifdef CONFIG_GRKERNSEC_RANDPID
19783+ {
19784+ .ctl_name = GS_RANDPID,
19785+ .procname = "rand_pids",
19786+ .data = &grsec_enable_randpid,
19787+ .maxlen = sizeof(int),
19788+ .mode = 0600,
19789+ .proc_handler = &proc_dointvec,
19790+ },
19791+#endif
19792+#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
19793+ {
19794+ .ctl_name = GS_SOCKET_ALL,
19795+ .procname = "socket_all",
19796+ .data = &grsec_enable_socket_all,
19797+ .maxlen = sizeof(int),
19798+ .mode = 0600,
19799+ .proc_handler = &proc_dointvec,
19800+ },
19801+ {
19802+ .ctl_name = GS_SOCKET_ALL_GID,
19803+ .procname = "socket_all_gid",
19804+ .data = &grsec_socket_all_gid,
19805+ .maxlen = sizeof(int),
19806+ .mode = 0600,
19807+ .proc_handler = &proc_dointvec,
19808+ },
19809+#endif
19810+#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
19811+ {
19812+ .ctl_name = GS_SOCKET_CLIENT,
19813+ .procname = "socket_client",
19814+ .data = &grsec_enable_socket_client,
19815+ .maxlen = sizeof(int),
19816+ .mode = 0600,
19817+ .proc_handler = &proc_dointvec,
19818+ },
19819+ {
19820+ .ctl_name = GS_SOCKET_CLIENT_GID,
19821+ .procname = "socket_client_gid",
19822+ .data = &grsec_socket_client_gid,
19823+ .maxlen = sizeof(int),
19824+ .mode = 0600,
19825+ .proc_handler = &proc_dointvec,
19826+ },
19827+#endif
19828+#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
19829+ {
19830+ .ctl_name = GS_SOCKET_SERVER,
19831+ .procname = "socket_server",
19832+ .data = &grsec_enable_socket_server,
19833+ .maxlen = sizeof(int),
19834+ .mode = 0600,
19835+ .proc_handler = &proc_dointvec,
19836+ },
19837+ {
19838+ .ctl_name = GS_SOCKET_SERVER_GID,
19839+ .procname = "socket_server_gid",
19840+ .data = &grsec_socket_server_gid,
19841+ .maxlen = sizeof(int),
19842+ .mode = 0600,
19843+ .proc_handler = &proc_dointvec,
19844+ },
19845+#endif
19846+#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
19847+ {
19848+ .ctl_name = GS_GROUP,
19849+ .procname = "audit_group",
19850+ .data = &grsec_enable_group,
19851+ .maxlen = sizeof(int),
19852+ .mode = 0600,
19853+ .proc_handler = &proc_dointvec,
19854+ },
19855+ {
19856+ .ctl_name = GS_GID,
19857+ .procname = "audit_gid",
19858+ .data = &grsec_audit_gid,
19859+ .maxlen = sizeof(int),
19860+ .mode = 0600,
19861+ .proc_handler = &proc_dointvec,
19862+ },
19863+#endif
19864+#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
19865+ {
19866+ .ctl_name = GS_ACHDIR,
19867+ .procname = "audit_chdir",
19868+ .data = &grsec_enable_chdir,
19869+ .maxlen = sizeof(int),
19870+ .mode = 0600,
19871+ .proc_handler = &proc_dointvec,
19872+ },
19873+#endif
19874+#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
19875+ {
19876+ .ctl_name = GS_AMOUNT,
19877+ .procname = "audit_mount",
19878+ .data = &grsec_enable_mount,
19879+ .maxlen = sizeof(int),
19880+ .mode = 0600,
19881+ .proc_handler = &proc_dointvec,
19882+ },
19883+#endif
19884+#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
19885+ {
19886+ .ctl_name = GS_AIPC,
19887+ .procname = "audit_ipc",
19888+ .data = &grsec_enable_audit_ipc,
19889+ .maxlen = sizeof(int),
19890+ .mode = 0600,
19891+ .proc_handler = &proc_dointvec,
19892+ },
19893+#endif
19894+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
19895+ {
19896+ .ctl_name = GS_TEXTREL,
19897+ .procname = "audit_textrel",
19898+ .data = &grsec_enable_audit_textrel,
19899+ .maxlen = sizeof(int),
19900+ .mode = 0600,
19901+ .proc_handler = &proc_dointvec,
19902+ },
19903+#endif
19904+#ifdef CONFIG_GRKERNSEC_DMESG
19905+ {
19906+ .ctl_name = GS_DMSG,
19907+ .procname = "dmesg",
19908+ .data = &grsec_enable_dmesg,
19909+ .maxlen = sizeof(int),
19910+ .mode = 0600,
19911+ .proc_handler = &proc_dointvec,
19912+ },
19913+#endif
19914+#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
19915+ {
19916+ .ctl_name = GS_FINDTASK,
19917+ .procname = "chroot_findtask",
19918+ .data = &grsec_enable_chroot_findtask,
19919+ .maxlen = sizeof(int),
19920+ .mode = 0600,
19921+ .proc_handler = &proc_dointvec,
19922+ },
19923+#endif
19924+#ifdef CONFIG_GRKERNSEC_SHM
19925+ {
19926+ .ctl_name = GS_SHM,
19927+ .procname = "destroy_unused_shm",
19928+ .data = &grsec_enable_shm,
19929+ .maxlen = sizeof(int),
19930+ .mode = 0600,
19931+ .proc_handler = &proc_dointvec,
19932+ },
19933+#endif
19934+#ifdef CONFIG_GRKERNSEC_RESLOG
19935+ {
19936+ .ctl_name = GS_RESLOG,
19937+ .procname = "resource_logging",
19938+ .data = &grsec_resource_logging,
19939+ .maxlen = sizeof(int),
19940+ .mode = 0600,
19941+ .proc_handler = &proc_dointvec,
19942+ },
19943+#endif
19944+ {
19945+ .ctl_name = GS_LOCK,
19946+ .procname = "grsec_lock",
19947+ .data = &grsec_lock,
19948+ .maxlen = sizeof(int),
19949+ .mode = 0600,
19950+ .proc_handler = &proc_dointvec,
19951+ },
19952+#endif
19953+#ifdef CONFIG_GRKERNSEC_MODSTOP
19954+ {
19955+ .ctl_name = GS_MODSTOP,
19956+ .procname = "disable_modules",
19957+ .data = &grsec_modstop,
19958+ .maxlen = sizeof(int),
19959+ .mode = 0600,
19960+ .proc_handler = &proc_dointvec,
19961+ },
19962+#endif
19963+ { .ctl_name = 0 }
19964+};
19965+#endif
19966+
19967+int gr_check_modstop(void)
19968+{
19969+#ifdef CONFIG_GRKERNSEC_MODSTOP
19970+ if (grsec_modstop == 1) {
19971+ gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
19972+ return 1;
19973+ }
19974+#endif
19975+ return 0;
19976+}
19977diff -urNp linux-2.6.19.1/grsecurity/grsec_textrel.c linux-2.6.19.1/grsecurity/grsec_textrel.c
19978--- linux-2.6.19.1/grsecurity/grsec_textrel.c 1969-12-31 19:00:00.000000000 -0500
19979+++ linux-2.6.19.1/grsecurity/grsec_textrel.c 2006-12-03 15:16:32.000000000 -0500
19980@@ -0,0 +1,16 @@
19981+#include <linux/kernel.h>
19982+#include <linux/sched.h>
19983+#include <linux/mm.h>
19984+#include <linux/file.h>
19985+#include <linux/grinternal.h>
19986+#include <linux/grsecurity.h>
19987+
19988+void
19989+gr_log_textrel(struct vm_area_struct * vma)
19990+{
19991+#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
19992+ if (grsec_enable_audit_textrel)
19993+ gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
19994+#endif
19995+ return;
19996+}
19997diff -urNp linux-2.6.19.1/grsecurity/grsec_time.c linux-2.6.19.1/grsecurity/grsec_time.c
19998--- linux-2.6.19.1/grsecurity/grsec_time.c 1969-12-31 19:00:00.000000000 -0500
19999+++ linux-2.6.19.1/grsecurity/grsec_time.c 2006-12-03 15:16:32.000000000 -0500
20000@@ -0,0 +1,13 @@
20001+#include <linux/kernel.h>
20002+#include <linux/sched.h>
20003+#include <linux/grinternal.h>
20004+
20005+void
20006+gr_log_timechange(void)
20007+{
20008+#ifdef CONFIG_GRKERNSEC_TIME
20009+ if (grsec_enable_time)
20010+ gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
20011+#endif
20012+ return;
20013+}
20014diff -urNp linux-2.6.19.1/grsecurity/grsec_tpe.c linux-2.6.19.1/grsecurity/grsec_tpe.c
20015--- linux-2.6.19.1/grsecurity/grsec_tpe.c 1969-12-31 19:00:00.000000000 -0500
20016+++ linux-2.6.19.1/grsecurity/grsec_tpe.c 2006-12-03 15:16:32.000000000 -0500
20017@@ -0,0 +1,37 @@
20018+#include <linux/kernel.h>
20019+#include <linux/sched.h>
20020+#include <linux/file.h>
20021+#include <linux/fs.h>
20022+#include <linux/grinternal.h>
20023+
20024+extern int gr_acl_tpe_check(void);
20025+
20026+int
20027+gr_tpe_allow(const struct file *file)
20028+{
20029+#ifdef CONFIG_GRKERNSEC
20030+ struct inode *inode = file->f_dentry->d_parent->d_inode;
20031+
20032+ if (current->uid && ((grsec_enable_tpe &&
20033+#ifdef CONFIG_GRKERNSEC_TPE_INVERT
20034+ !in_group_p(grsec_tpe_gid)
20035+#else
20036+ in_group_p(grsec_tpe_gid)
20037+#endif
20038+ ) || gr_acl_tpe_check()) &&
20039+ (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
20040+ (inode->i_mode & S_IWOTH))))) {
20041+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
20042+ return 0;
20043+ }
20044+#ifdef CONFIG_GRKERNSEC_TPE_ALL
20045+ if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
20046+ ((inode->i_uid && (inode->i_uid != current->uid)) ||
20047+ (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
20048+ gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
20049+ return 0;
20050+ }
20051+#endif
20052+#endif
20053+ return 1;
20054+}
20055diff -urNp linux-2.6.19.1/grsecurity/grsum.c linux-2.6.19.1/grsecurity/grsum.c
20056--- linux-2.6.19.1/grsecurity/grsum.c 1969-12-31 19:00:00.000000000 -0500
20057+++ linux-2.6.19.1/grsecurity/grsum.c 2006-12-03 15:16:32.000000000 -0500
20058@@ -0,0 +1,59 @@
20059+#include <linux/kernel.h>
20060+#include <linux/sched.h>
20061+#include <linux/mm.h>
20062+#include <asm/scatterlist.h>
20063+#include <linux/crypto.h>
20064+#include <linux/gracl.h>
20065+
20066+
20067+#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
20068+#error "crypto and sha256 must be built into the kernel"
20069+#endif
20070+
20071+int
20072+chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
20073+{
20074+ char *p;
20075+ struct crypto_tfm *tfm;
20076+ unsigned char temp_sum[GR_SHA_LEN];
20077+ struct scatterlist sg[2];
20078+ volatile int retval = 0;
20079+ volatile int dummy = 0;
20080+ unsigned int i;
20081+
20082+ tfm = crypto_alloc_tfm("sha256", 0);
20083+ if (tfm == NULL) {
20084+ /* should never happen, since sha256 should be built in */
20085+ return 1;
20086+ }
20087+
20088+ crypto_digest_init(tfm);
20089+
20090+ p = salt;
20091+ sg[0].page = virt_to_page(p);
20092+ sg[0].offset = ((long) p & ~PAGE_MASK);
20093+ sg[0].length = GR_SALT_LEN;
20094+
20095+ crypto_digest_update(tfm, sg, 1);
20096+
20097+ p = entry->pw;
20098+ sg[0].page = virt_to_page(p);
20099+ sg[0].offset = ((long) p & ~PAGE_MASK);
20100+ sg[0].length = strlen(entry->pw);
20101+
20102+ crypto_digest_update(tfm, sg, 1);
20103+
20104+ crypto_digest_final(tfm, temp_sum);
20105+
20106+ memset(entry->pw, 0, GR_PW_LEN);
20107+
20108+ for (i = 0; i < GR_SHA_LEN; i++)
20109+ if (sum[i] != temp_sum[i])
20110+ retval = 1;
20111+ else
20112+ dummy = 1; // waste a cycle
20113+
20114+ crypto_free_tfm(tfm);
20115+
20116+ return retval;
20117+}
20118diff -urNp linux-2.6.19.1/grsecurity/Kconfig linux-2.6.19.1/grsecurity/Kconfig
20119--- linux-2.6.19.1/grsecurity/Kconfig 1969-12-31 19:00:00.000000000 -0500
20120+++ linux-2.6.19.1/grsecurity/Kconfig 2006-12-03 15:16:32.000000000 -0500
20121@@ -0,0 +1,888 @@
20122+#
20123+# grecurity configuration
20124+#
20125+
20126+menu "Grsecurity"
20127+
20128+config GRKERNSEC
20129+ bool "Grsecurity"
20130+ select CRYPTO
20131+ select CRYPTO_SHA256
20132+ help
20133+ If you say Y here, you will be able to configure many features
20134+ that will enhance the security of your system. It is highly
20135+ recommended that you say Y here and read through the help
20136+ for each option so that you fully understand the features and
20137+ can evaluate their usefulness for your machine.
20138+
20139+choice
20140+ prompt "Security Level"
20141+ depends GRKERNSEC
20142+ default GRKERNSEC_CUSTOM
20143+
20144+config GRKERNSEC_LOW
20145+ bool "Low"
20146+ select GRKERNSEC_LINK
20147+ select GRKERNSEC_FIFO
20148+ select GRKERNSEC_RANDPID
20149+ select GRKERNSEC_EXECVE
20150+ select GRKERNSEC_RANDNET
20151+ select GRKERNSEC_DMESG
20152+ select GRKERNSEC_CHROOT_CHDIR
20153+ select GRKERNSEC_MODSTOP if (MODULES)
20154+
20155+ help
20156+ If you choose this option, several of the grsecurity options will
20157+ be enabled that will give you greater protection against a number
20158+ of attacks, while assuring that none of your software will have any
20159+ conflicts with the additional security measures. If you run a lot
20160+ of unusual software, or you are having problems with the higher
20161+ security levels, you should say Y here. With this option, the
20162+ following features are enabled:
20163+
20164+ - Linking restrictions
20165+ - FIFO restrictions
20166+ - Randomized PIDs
20167+ - Enforcing RLIMIT_NPROC on execve
20168+ - Restricted dmesg
20169+ - Enforced chdir("/") on chroot
20170+ - Runtime module disabling
20171+
20172+config GRKERNSEC_MEDIUM
20173+ bool "Medium"
20174+ select PAX
20175+ select PAX_EI_PAX
20176+ select PAX_PT_PAX_FLAGS
20177+ select PAX_HAVE_ACL_FLAGS
20178+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
20179+ select GRKERNSEC_CHROOT_SYSCTL
20180+ select GRKERNSEC_LINK
20181+ select GRKERNSEC_FIFO
20182+ select GRKERNSEC_RANDPID
20183+ select GRKERNSEC_EXECVE
20184+ select GRKERNSEC_DMESG
20185+ select GRKERNSEC_RANDNET
20186+ select GRKERNSEC_FORKFAIL
20187+ select GRKERNSEC_TIME
20188+ select GRKERNSEC_SIGNAL
20189+ select GRKERNSEC_CHROOT
20190+ select GRKERNSEC_CHROOT_UNIX
20191+ select GRKERNSEC_CHROOT_MOUNT
20192+ select GRKERNSEC_CHROOT_PIVOT
20193+ select GRKERNSEC_CHROOT_DOUBLE
20194+ select GRKERNSEC_CHROOT_CHDIR
20195+ select GRKERNSEC_CHROOT_MKNOD
20196+ select GRKERNSEC_PROC
20197+ select GRKERNSEC_PROC_USERGROUP
20198+ select GRKERNSEC_MODSTOP if (MODULES)
20199+ select PAX_RANDUSTACK
20200+ select PAX_ASLR
20201+ select PAX_RANDMMAP
20202+
20203+ help
20204+ If you say Y here, several features in addition to those included
20205+ in the low additional security level will be enabled. These
20206+ features provide even more security to your system, though in rare
20207+ cases they may be incompatible with very old or poorly written
20208+ software. If you enable this option, make sure that your auth
20209+ service (identd) is running as gid 1001. With this option,
20210+ the following features (in addition to those provided in the
20211+ low additional security level) will be enabled:
20212+
20213+ - Randomized TCP source ports
20214+ - Failed fork logging
20215+ - Time change logging
20216+ - Signal logging
20217+ - Deny mounts in chroot
20218+ - Deny double chrooting
20219+ - Deny sysctl writes in chroot
20220+ - Deny mknod in chroot
20221+ - Deny access to abstract AF_UNIX sockets out of chroot
20222+ - Deny pivot_root in chroot
20223+ - Denied writes of /dev/kmem, /dev/mem, and /dev/port
20224+ - /proc restrictions with special GID set to 10 (usually wheel)
20225+ - Address Space Layout Randomization (ASLR)
20226+
20227+config GRKERNSEC_HIGH
20228+ bool "High"
20229+ select GRKERNSEC_LINK
20230+ select GRKERNSEC_FIFO
20231+ select GRKERNSEC_RANDPID
20232+ select GRKERNSEC_EXECVE
20233+ select GRKERNSEC_DMESG
20234+ select GRKERNSEC_FORKFAIL
20235+ select GRKERNSEC_TIME
20236+ select GRKERNSEC_SIGNAL
20237+ select GRKERNSEC_CHROOT_SHMAT
20238+ select GRKERNSEC_CHROOT_UNIX
20239+ select GRKERNSEC_CHROOT_MOUNT
20240+ select GRKERNSEC_CHROOT_FCHDIR
20241+ select GRKERNSEC_CHROOT_PIVOT
20242+ select GRKERNSEC_CHROOT_DOUBLE
20243+ select GRKERNSEC_CHROOT_CHDIR
20244+ select GRKERNSEC_CHROOT_MKNOD
20245+ select GRKERNSEC_CHROOT_CAPS
20246+ select GRKERNSEC_CHROOT_SYSCTL
20247+ select GRKERNSEC_CHROOT_FINDTASK
20248+ select GRKERNSEC_PROC
20249+ select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
20250+ select GRKERNSEC_HIDESYM
20251+ select GRKERNSEC_BRUTE
20252+ select GRKERNSEC_SHM if (SYSVIPC)
20253+ select GRKERNSEC_PROC_USERGROUP
20254+ select GRKERNSEC_KMEM
20255+ select GRKERNSEC_RESLOG
20256+ select GRKERNSEC_RANDNET
20257+ select GRKERNSEC_PROC_ADD
20258+ select GRKERNSEC_CHROOT_CHMOD
20259+ select GRKERNSEC_CHROOT_NICE
20260+ select GRKERNSEC_AUDIT_MOUNT
20261+ select GRKERNSEC_MODSTOP if (MODULES)
20262+ select PAX
20263+ select PAX_RANDUSTACK
20264+ select PAX_ASLR
20265+ select PAX_RANDMMAP
20266+ select PAX_NOEXEC
20267+ select PAX_MPROTECT
20268+ select PAX_EI_PAX
20269+ select PAX_PT_PAX_FLAGS
20270+ select PAX_HAVE_ACL_FLAGS
20271+ select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
20272+ select PAX_RANDKSTACK if (X86_TSC && !X86_64)
20273+ select PAX_SEGMEXEC if (X86 && !X86_64)
20274+ select PAX_PAGEEXEC if (!X86)
20275+ select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
20276+ select PAX_DLRESOLVE if (SPARC32 || SPARC64)
20277+ select PAX_SYSCALL if (PPC32)
20278+ select PAX_EMUTRAMP if (PARISC)
20279+ select PAX_EMUSIGRT if (PARISC)
20280+ select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
20281+ help
20282+ If you say Y here, many of the features of grsecurity will be
20283+ enabled, which will protect you against many kinds of attacks
20284+ against your system. The heightened security comes at a cost
20285+ of an increased chance of incompatibilities with rare software
20286+ on your machine. Since this security level enables PaX, you should
20287+ view <http://pax.grsecurity.net> and read about the PaX
20288+ project. While you are there, download chpax and run it on
20289+ binaries that cause problems with PaX. Also remember that
20290+ since the /proc restrictions are enabled, you must run your
20291+ identd as gid 1001. This security level enables the following
20292+ features in addition to those listed in the low and medium
20293+ security levels:
20294+
20295+ - Additional /proc restrictions
20296+ - Chmod restrictions in chroot
20297+ - No signals, ptrace, or viewing of processes outside of chroot
20298+ - Capability restrictions in chroot
20299+ - Deny fchdir out of chroot
20300+ - Priority restrictions in chroot
20301+ - Segmentation-based implementation of PaX
20302+ - Mprotect restrictions
20303+ - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
20304+ - Kernel stack randomization
20305+ - Mount/unmount/remount logging
20306+ - Kernel symbol hiding
20307+ - Destroy unused shared memory
20308+ - Prevention of memory exhaustion-based exploits
20309+config GRKERNSEC_CUSTOM
20310+ bool "Custom"
20311+ help
20312+ If you say Y here, you will be able to configure every grsecurity
20313+ option, which allows you to enable many more features that aren't
20314+ covered in the basic security levels. These additional features
20315+ include TPE, socket restrictions, and the sysctl system for
20316+ grsecurity. It is advised that you read through the help for
20317+ each option to determine its usefulness in your situation.
20318+
20319+endchoice
20320+
20321+menu "Address Space Protection"
20322+depends on GRKERNSEC
20323+
20324+config GRKERNSEC_KMEM
20325+ bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
20326+ help
20327+ If you say Y here, /dev/kmem and /dev/mem won't be allowed to
20328+ be written to via mmap or otherwise to modify the running kernel.
20329+ /dev/port will also not be allowed to be opened. If you have module
20330+ support disabled, enabling this will close up four ways that are
20331+ currently used to insert malicious code into the running kernel.
20332+ Even with all these features enabled, we still highly recommend that
20333+ you use the RBAC system, as it is still possible for an attacker to
20334+ modify the running kernel through privileged I/O granted by ioperm/iopl.
20335+ If you are not using XFree86, you may be able to stop this additional
20336+ case by enabling the 'Disable privileged I/O' option. Though nothing
20337+ legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
20338+ but only to video memory, which is the only writing we allow in this
20339+ case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
20340+ not be allowed to mprotect it with PROT_WRITE later.
20341+ It is highly recommended that you say Y here if you meet all the
20342+ conditions above.
20343+
20344+config GRKERNSEC_IO
20345+ bool "Disable privileged I/O"
20346+ depends on X86
20347+ select RTC
20348+ help
20349+ If you say Y here, all ioperm and iopl calls will return an error.
20350+ Ioperm and iopl can be used to modify the running kernel.
20351+ Unfortunately, some programs need this access to operate properly,
20352+ the most notable of which are XFree86 and hwclock. hwclock can be
20353+ remedied by having RTC support in the kernel, so CONFIG_RTC is
20354+ enabled if this option is enabled, to ensure that hwclock operates
20355+ correctly. XFree86 still will not operate correctly with this option
20356+ enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86
20357+ and you still want to protect your kernel against modification,
20358+ use the RBAC system.
20359+
20360+config GRKERNSEC_PROC_MEMMAP
20361+ bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
20362+ depends on PAX_NOEXEC || PAX_ASLR
20363+ help
20364+ If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
20365+ give no information about the addresses of its mappings if
20366+ PaX features that rely on random addresses are enabled on the task.
20367+ If you use PaX it is greatly recommended that you say Y here as it
20368+ closes up a hole that makes the full ASLR useless for suid
20369+ binaries.
20370+
20371+config GRKERNSEC_BRUTE
20372+ bool "Deter exploit bruteforcing"
20373+ help
20374+ If you say Y here, attempts to bruteforce exploits against forking
20375+ daemons such as apache or sshd will be deterred. When a child of a
20376+ forking daemon is killed by PaX or crashes due to an illegal
20377+ instruction, the parent process will be delayed 30 seconds upon every
20378+ subsequent fork until the administrator is able to assess the
20379+ situation and restart the daemon. It is recommended that you also
20380+ enable signal logging in the auditing section so that logs are
20381+ generated when a process performs an illegal instruction.
20382+
20383+config GRKERNSEC_MODSTOP
20384+ bool "Runtime module disabling"
20385+ depends on MODULES
20386+ help
20387+ If you say Y here, you will be able to disable the ability to (un)load
20388+ modules at runtime. This feature is useful if you need the ability
20389+ to load kernel modules at boot time, but do not want to allow an
20390+ attacker to load a rootkit kernel module into the system, or to remove
20391+ a loaded kernel module important to system functioning. You should
20392+ enable the /dev/mem protection feature as well, since rootkits can be
20393+ inserted into the kernel via other methods than kernel modules. Since
20394+ an untrusted module could still be loaded by modifying init scripts and
20395+ rebooting the system, it is also recommended that you enable the RBAC
20396+ system. If you enable this option, a sysctl option with name
20397+ "disable_modules" will be created. Setting this option to "1" disables
20398+ module loading. After this option is set, no further writes to it are
20399+ allowed until the system is rebooted.
20400+
20401+config GRKERNSEC_HIDESYM
20402+ bool "Hide kernel symbols"
20403+ help
20404+ If you say Y here, getting information on loaded modules, and
20405+ displaying all kernel symbols through a syscall will be restricted
20406+ to users with CAP_SYS_MODULE. This option is only effective
20407+ provided the following conditions are met:
20408+ 1) The kernel using grsecurity is not precompiled by some distribution
20409+ 2) You are using the RBAC system and hiding other files such as your
20410+ kernel image and System.map
20411+ 3) You have the additional /proc restrictions enabled, which removes
20412+ /proc/kcore
20413+ If the above conditions are met, this option will aid to provide a
20414+ useful protection against local and remote kernel exploitation of
20415+ overflows and arbitrary read/write vulnerabilities.
20416+
20417+endmenu
20418+menu "Role Based Access Control Options"
20419+depends on GRKERNSEC
20420+
20421+config GRKERNSEC_ACL_HIDEKERN
20422+ bool "Hide kernel processes"
20423+ help
20424+ If you say Y here, all kernel threads will be hidden to all
20425+ processes but those whose subject has the "view hidden processes"
20426+ flag.
20427+
20428+config GRKERNSEC_ACL_MAXTRIES
20429+ int "Maximum tries before password lockout"
20430+ default 3
20431+ help
20432+ This option enforces the maximum number of times a user can attempt
20433+ to authorize themselves with the grsecurity RBAC system before being
20434+ denied the ability to attempt authorization again for a specified time.
20435+ The lower the number, the harder it will be to brute-force a password.
20436+
20437+config GRKERNSEC_ACL_TIMEOUT
20438+ int "Time to wait after max password tries, in seconds"
20439+ default 30
20440+ help
20441+ This option specifies the time the user must wait after attempting to
20442+ authorize to the RBAC system with the maximum number of invalid
20443+ passwords. The higher the number, the harder it will be to brute-force
20444+ a password.
20445+
20446+endmenu
20447+menu "Filesystem Protections"
20448+depends on GRKERNSEC
20449+
20450+config GRKERNSEC_PROC
20451+ bool "Proc restrictions"
20452+ help
20453+ If you say Y here, the permissions of the /proc filesystem
20454+ will be altered to enhance system security and privacy. You MUST
20455+ choose either a user only restriction or a user and group restriction.
20456+ Depending upon the option you choose, you can either restrict users to
20457+ see only the processes they themselves run, or choose a group that can
20458+ view all processes and files normally restricted to root if you choose
20459+ the "restrict to user only" option. NOTE: If you're running identd as
20460+ a non-root user, you will have to run it as the group you specify here.
20461+
20462+config GRKERNSEC_PROC_USER
20463+ bool "Restrict /proc to user only"
20464+ depends on GRKERNSEC_PROC
20465+ help
20466+ If you say Y here, non-root users will only be able to view their own
20467+ processes, and restricts them from viewing network-related information,
20468+ and viewing kernel symbol and module information.
20469+
20470+config GRKERNSEC_PROC_USERGROUP
20471+ bool "Allow special group"
20472+ depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
20473+ help
20474+ If you say Y here, you will be able to select a group that will be
20475+ able to view all processes, network-related information, and
20476+ kernel and symbol information. This option is useful if you want
20477+ to run identd as a non-root user.
20478+
20479+config GRKERNSEC_PROC_GID
20480+ int "GID for special group"
20481+ depends on GRKERNSEC_PROC_USERGROUP
20482+ default 1001
20483+
20484+config GRKERNSEC_PROC_ADD
20485+ bool "Additional restrictions"
20486+ depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
20487+ help
20488+ If you say Y here, additional restrictions will be placed on
20489+ /proc that keep normal users from viewing device information and
20490+ slabinfo information that could be useful for exploits.
20491+
20492+config GRKERNSEC_LINK
20493+ bool "Linking restrictions"
20494+ help
20495+ If you say Y here, /tmp race exploits will be prevented, since users
20496+ will no longer be able to follow symlinks owned by other users in
20497+ world-writable +t directories (i.e. /tmp), unless the owner of the
20498+ symlink is the owner of the directory. users will also not be
20499+ able to hardlink to files they do not own. If the sysctl option is
20500+ enabled, a sysctl option with name "linking_restrictions" is created.
20501+
20502+config GRKERNSEC_FIFO
20503+ bool "FIFO restrictions"
20504+ help
20505+ If you say Y here, users will not be able to write to FIFOs they don't
20506+ own in world-writable +t directories (i.e. /tmp), unless the owner of
20507+ the FIFO is the same owner of the directory it's held in. If the sysctl
20508+ option is enabled, a sysctl option with name "fifo_restrictions" is
20509+ created.
20510+
20511+config GRKERNSEC_CHROOT
20512+ bool "Chroot jail restrictions"
20513+ help
20514+ If you say Y here, you will be able to choose several options that will
20515+ make breaking out of a chrooted jail much more difficult. If you
20516+ encounter no software incompatibilities with the following options, it
20517+ is recommended that you enable each one.
20518+
20519+config GRKERNSEC_CHROOT_MOUNT
20520+ bool "Deny mounts"
20521+ depends on GRKERNSEC_CHROOT
20522+ help
20523+ If you say Y here, processes inside a chroot will not be able to
20524+ mount or remount filesystems. If the sysctl option is enabled, a
20525+ sysctl option with name "chroot_deny_mount" is created.
20526+
20527+config GRKERNSEC_CHROOT_DOUBLE
20528+ bool "Deny double-chroots"
20529+ depends on GRKERNSEC_CHROOT
20530+ help
20531+ If you say Y here, processes inside a chroot will not be able to chroot
20532+ again outside the chroot. This is a widely used method of breaking
20533+ out of a chroot jail and should not be allowed. If the sysctl
20534+ option is enabled, a sysctl option with name
20535+ "chroot_deny_chroot" is created.
20536+
20537+config GRKERNSEC_CHROOT_PIVOT
20538+ bool "Deny pivot_root in chroot"
20539+ depends on GRKERNSEC_CHROOT
20540+ help
20541+ If you say Y here, processes inside a chroot will not be able to use
20542+ a function called pivot_root() that was introduced in Linux 2.3.41. It
20543+ works similar to chroot in that it changes the root filesystem. This
20544+ function could be misused in a chrooted process to attempt to break out
20545+ of the chroot, and therefore should not be allowed. If the sysctl
20546+ option is enabled, a sysctl option with name "chroot_deny_pivot" is
20547+ created.
20548+
20549+config GRKERNSEC_CHROOT_CHDIR
20550+ bool "Enforce chdir(\"/\") on all chroots"
20551+ depends on GRKERNSEC_CHROOT
20552+ help
20553+ If you say Y here, the current working directory of all newly-chrooted
20554+ applications will be set to the the root directory of the chroot.
20555+ The man page on chroot(2) states:
20556+ Note that this call does not change the current working
20557+ directory, so that `.' can be outside the tree rooted at
20558+ `/'. In particular, the super-user can escape from a
20559+ `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
20560+
20561+ It is recommended that you say Y here, since it's not known to break
20562+ any software. If the sysctl option is enabled, a sysctl option with
20563+ name "chroot_enforce_chdir" is created.
20564+
20565+config GRKERNSEC_CHROOT_CHMOD
20566+ bool "Deny (f)chmod +s"
20567+ depends on GRKERNSEC_CHROOT
20568+ help
20569+ If you say Y here, processes inside a chroot will not be able to chmod
20570+ or fchmod files to make them have suid or sgid bits. This protects
20571+ against another published method of breaking a chroot. If the sysctl
20572+ option is enabled, a sysctl option with name "chroot_deny_chmod" is
20573+ created.
20574+
20575+config GRKERNSEC_CHROOT_FCHDIR
20576+ bool "Deny fchdir out of chroot"
20577+ depends on GRKERNSEC_CHROOT
20578+ help
20579+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
20580+ to a file descriptor of the chrooting process that points to a directory
20581+ outside the filesystem will be stopped. If the sysctl option
20582+ is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
20583+
20584+config GRKERNSEC_CHROOT_MKNOD
20585+ bool "Deny mknod"
20586+ depends on GRKERNSEC_CHROOT
20587+ help
20588+ If you say Y here, processes inside a chroot will not be allowed to
20589+ mknod. The problem with using mknod inside a chroot is that it
20590+ would allow an attacker to create a device entry that is the same
20591+ as one on the physical root of your system, which could range from
20592+ anything from the console device to a device for your harddrive (which
20593+ they could then use to wipe the drive or steal data). It is recommended
20594+ that you say Y here, unless you run into software incompatibilities.
20595+ If the sysctl option is enabled, a sysctl option with name
20596+ "chroot_deny_mknod" is created.
20597+
20598+config GRKERNSEC_CHROOT_SHMAT
20599+ bool "Deny shmat() out of chroot"
20600+ depends on GRKERNSEC_CHROOT
20601+ help
20602+ If you say Y here, processes inside a chroot will not be able to attach
20603+ to shared memory segments that were created outside of the chroot jail.
20604+ It is recommended that you say Y here. If the sysctl option is enabled,
20605+ a sysctl option with name "chroot_deny_shmat" is created.
20606+
20607+config GRKERNSEC_CHROOT_UNIX
20608+ bool "Deny access to abstract AF_UNIX sockets out of chroot"
20609+ depends on GRKERNSEC_CHROOT
20610+ help
20611+ If you say Y here, processes inside a chroot will not be able to
20612+ connect to abstract (meaning not belonging to a filesystem) Unix
20613+ domain sockets that were bound outside of a chroot. It is recommended
20614+ that you say Y here. If the sysctl option is enabled, a sysctl option
20615+ with name "chroot_deny_unix" is created.
20616+
20617+config GRKERNSEC_CHROOT_FINDTASK
20618+ bool "Protect outside processes"
20619+ depends on GRKERNSEC_CHROOT
20620+ help
20621+ If you say Y here, processes inside a chroot will not be able to
20622+ kill, send signals with fcntl, ptrace, capget, setpgid, getpgid,
20623+ getsid, or view any process outside of the chroot. If the sysctl
20624+ option is enabled, a sysctl option with name "chroot_findtask" is
20625+ created.
20626+
20627+config GRKERNSEC_CHROOT_NICE
20628+ bool "Restrict priority changes"
20629+ depends on GRKERNSEC_CHROOT
20630+ help
20631+ If you say Y here, processes inside a chroot will not be able to raise
20632+ the priority of processes in the chroot, or alter the priority of
20633+ processes outside the chroot. This provides more security than simply
20634+ removing CAP_SYS_NICE from the process' capability set. If the
20635+ sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
20636+ is created.
20637+
20638+config GRKERNSEC_CHROOT_SYSCTL
20639+ bool "Deny sysctl writes"
20640+ depends on GRKERNSEC_CHROOT
20641+ help
20642+ If you say Y here, an attacker in a chroot will not be able to
20643+ write to sysctl entries, either by sysctl(2) or through a /proc
20644+ interface. It is strongly recommended that you say Y here. If the
20645+ sysctl option is enabled, a sysctl option with name
20646+ "chroot_deny_sysctl" is created.
20647+
20648+config GRKERNSEC_CHROOT_CAPS
20649+ bool "Capability restrictions"
20650+ depends on GRKERNSEC_CHROOT
20651+ help
20652+ If you say Y here, the capabilities on all root processes within a
20653+ chroot jail will be lowered to stop module insertion, raw i/o,
20654+ system and net admin tasks, rebooting the system, modifying immutable
20655+ files, modifying IPC owned by another, and changing the system time.
20656+ This is left an option because it can break some apps. Disable this
20657+ if your chrooted apps are having problems performing those kinds of
20658+ tasks. If the sysctl option is enabled, a sysctl option with
20659+ name "chroot_caps" is created.
20660+
20661+endmenu
20662+menu "Kernel Auditing"
20663+depends on GRKERNSEC
20664+
20665+config GRKERNSEC_AUDIT_GROUP
20666+ bool "Single group for auditing"
20667+ help
20668+ If you say Y here, the exec, chdir, (un)mount, and ipc logging features
20669+ will only operate on a group you specify. This option is recommended
20670+ if you only want to watch certain users instead of having a large
20671+ amount of logs from the entire system. If the sysctl option is enabled,
20672+ a sysctl option with name "audit_group" is created.
20673+
20674+config GRKERNSEC_AUDIT_GID
20675+ int "GID for auditing"
20676+ depends on GRKERNSEC_AUDIT_GROUP
20677+ default 1007
20678+
20679+config GRKERNSEC_EXECLOG
20680+ bool "Exec logging"
20681+ help
20682+ If you say Y here, all execve() calls will be logged (since the
20683+ other exec*() calls are frontends to execve(), all execution
20684+ will be logged). Useful for shell-servers that like to keep track
20685+ of their users. If the sysctl option is enabled, a sysctl option with
20686+ name "exec_logging" is created.
20687+ WARNING: This option when enabled will produce a LOT of logs, especially
20688+ on an active system.
20689+
20690+config GRKERNSEC_RESLOG
20691+ bool "Resource logging"
20692+ help
20693+ If you say Y here, all attempts to overstep resource limits will
20694+ be logged with the resource name, the requested size, and the current
20695+ limit. It is highly recommended that you say Y here. If the sysctl
20696+ option is enabled, a sysctl option with name "resource_logging" is
20697+ created. If the RBAC system is enabled, the sysctl value is ignored.
20698+
20699+config GRKERNSEC_CHROOT_EXECLOG
20700+ bool "Log execs within chroot"
20701+ help
20702+ If you say Y here, all executions inside a chroot jail will be logged
20703+ to syslog. This can cause a large amount of logs if certain
20704+ applications (eg. djb's daemontools) are installed on the system, and
20705+ is therefore left as an option. If the sysctl option is enabled, a
20706+ sysctl option with name "chroot_execlog" is created.
20707+
20708+config GRKERNSEC_AUDIT_CHDIR
20709+ bool "Chdir logging"
20710+ help
20711+ If you say Y here, all chdir() calls will be logged. If the sysctl
20712+ option is enabled, a sysctl option with name "audit_chdir" is created.
20713+
20714+config GRKERNSEC_AUDIT_MOUNT
20715+ bool "(Un)Mount logging"
20716+ help
20717+ If you say Y here, all mounts and unmounts will be logged. If the
20718+ sysctl option is enabled, a sysctl option with name "audit_mount" is
20719+ created.
20720+
20721+config GRKERNSEC_AUDIT_IPC
20722+ bool "IPC logging"
20723+ help
20724+ If you say Y here, creation and removal of message queues, semaphores,
20725+ and shared memory will be logged. If the sysctl option is enabled, a
20726+ sysctl option with name "audit_ipc" is created.
20727+
20728+config GRKERNSEC_SIGNAL
20729+ bool "Signal logging"
20730+ help
20731+ If you say Y here, certain important signals will be logged, such as
20732+ SIGSEGV, which will as a result inform you of when a error in a program
20733+ occurred, which in some cases could mean a possible exploit attempt.
20734+ If the sysctl option is enabled, a sysctl option with name
20735+ "signal_logging" is created.
20736+
20737+config GRKERNSEC_FORKFAIL
20738+ bool "Fork failure logging"
20739+ help
20740+ If you say Y here, all failed fork() attempts will be logged.
20741+ This could suggest a fork bomb, or someone attempting to overstep
20742+ their process limit. If the sysctl option is enabled, a sysctl option
20743+ with name "forkfail_logging" is created.
20744+
20745+config GRKERNSEC_TIME
20746+ bool "Time change logging"
20747+ help
20748+ If you say Y here, any changes of the system clock will be logged.
20749+ If the sysctl option is enabled, a sysctl option with name
20750+ "timechange_logging" is created.
20751+
20752+config GRKERNSEC_PROC_IPADDR
20753+ bool "/proc/<pid>/ipaddr support"
20754+ help
20755+ If you say Y here, a new entry will be added to each /proc/<pid>
20756+ directory that contains the IP address of the person using the task.
20757+ The IP is carried across local TCP and AF_UNIX stream sockets.
20758+ This information can be useful for IDS/IPSes to perform remote response
20759+ to a local attack. The entry is readable by only the owner of the
20760+ process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
20761+ the RBAC system), and thus does not create privacy concerns.
20762+
20763+config GRKERNSEC_AUDIT_TEXTREL
20764+ bool 'ELF text relocations logging (READ HELP)'
20765+ depends on PAX_MPROTECT
20766+ help
20767+ If you say Y here, text relocations will be logged with the filename
20768+ of the offending library or binary. The purpose of the feature is
20769+ to help Linux distribution developers get rid of libraries and
20770+ binaries that need text relocations which hinder the future progress
20771+ of PaX. Only Linux distribution developers should say Y here, and
20772+ never on a production machine, as this option creates an information
20773+ leak that could aid an attacker in defeating the randomization of
20774+ a single memory region. If the sysctl option is enabled, a sysctl
20775+ option with name "audit_textrel" is created.
20776+
20777+endmenu
20778+
20779+menu "Executable Protections"
20780+depends on GRKERNSEC
20781+
20782+config GRKERNSEC_EXECVE
20783+ bool "Enforce RLIMIT_NPROC on execs"
20784+ help
20785+ If you say Y here, users with a resource limit on processes will
20786+ have the value checked during execve() calls. The current system
20787+ only checks the system limit during fork() calls. If the sysctl option
20788+ is enabled, a sysctl option with name "execve_limiting" is created.
20789+
20790+config GRKERNSEC_SHM
20791+ bool "Destroy unused shared memory"
20792+ depends on SYSVIPC
20793+ help
20794+ If you say Y here, shared memory will be destroyed when no one is
20795+ attached to it. Otherwise, resources involved with the shared
20796+ memory can be used up and not be associated with any process (as the
20797+ shared memory still exists, and the creating process has exited). If
20798+ the sysctl option is enabled, a sysctl option with name
20799+ "destroy_unused_shm" is created.
20800+
20801+config GRKERNSEC_DMESG
20802+ bool "Dmesg(8) restriction"
20803+ help
20804+ If you say Y here, non-root users will not be able to use dmesg(8)
20805+ to view up to the last 4kb of messages in the kernel's log buffer.
20806+ If the sysctl option is enabled, a sysctl option with name "dmesg" is
20807+ created.
20808+
20809+config GRKERNSEC_RANDPID
20810+ bool "Randomized PIDs"
20811+ help
20812+ If you say Y here, all PIDs created on the system will be
20813+ pseudo-randomly generated. This is extremely effective along
20814+ with the /proc restrictions to disallow an attacker from guessing
20815+ pids of daemons, etc. PIDs are also used in some cases as part
20816+ of a naming system for temporary files, so this option would keep
20817+ those filenames from being predicted as well. We also use code
20818+ to make sure that PID numbers aren't reused too soon. If the sysctl
20819+ option is enabled, a sysctl option with name "rand_pids" is created.
20820+
20821+config GRKERNSEC_TPE
20822+ bool "Trusted Path Execution (TPE)"
20823+ help
20824+ If you say Y here, you will be able to choose a gid to add to the
20825+ supplementary groups of users you want to mark as "untrusted."
20826+ These users will not be able to execute any files that are not in
20827+ root-owned directories writable only by root. If the sysctl option
20828+ is enabled, a sysctl option with name "tpe" is created.
20829+
20830+config GRKERNSEC_TPE_ALL
20831+ bool "Partially restrict non-root users"
20832+ depends on GRKERNSEC_TPE
20833+ help
20834+ If you say Y here, All non-root users other than the ones in the
20835+ group specified in the main TPE option will only be allowed to
20836+ execute files in directories they own that are not group or
20837+ world-writable, or in directories owned by root and writable only by
20838+ root. If the sysctl option is enabled, a sysctl option with name
20839+ "tpe_restrict_all" is created.
20840+
20841+config GRKERNSEC_TPE_INVERT
20842+ bool "Invert GID option"
20843+ depends on GRKERNSEC_TPE
20844+ help
20845+ If you say Y here, the group you specify in the TPE configuration will
20846+ decide what group TPE restrictions will be *disabled* for. This
20847+ option is useful if you want TPE restrictions to be applied to most
20848+ users on the system.
20849+
20850+config GRKERNSEC_TPE_GID
20851+ int "GID for untrusted users"
20852+ depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
20853+ default 1005
20854+ help
20855+ If you have selected the "Invert GID option" above, setting this
20856+ GID determines what group TPE restrictions will be *disabled* for.
20857+ If you have not selected the "Invert GID option" above, setting this
20858+ GID determines what group TPE restrictions will be *enabled* for.
20859+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
20860+ is created.
20861+
20862+config GRKERNSEC_TPE_GID
20863+ int "GID for trusted users"
20864+ depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
20865+ default 1005
20866+ help
20867+ If you have selected the "Invert GID option" above, setting this
20868+ GID determines what group TPE restrictions will be *disabled* for.
20869+ If you have not selected the "Invert GID option" above, setting this
20870+ GID determines what group TPE restrictions will be *enabled* for.
20871+ If the sysctl option is enabled, a sysctl option with name "tpe_gid"
20872+ is created.
20873+
20874+endmenu
20875+menu "Network Protections"
20876+depends on GRKERNSEC
20877+
20878+config GRKERNSEC_RANDNET
20879+ bool "Larger entropy pools"
20880+ help
20881+ If you say Y here, the entropy pools used for many features of Linux
20882+ and grsecurity will be doubled in size. Since several grsecurity
20883+ features use additional randomness, it is recommended that you say Y
20884+ here. Saying Y here has a similar effect as modifying
20885+ /proc/sys/kernel/random/poolsize.
20886+
20887+config GRKERNSEC_SOCKET
20888+ bool "Socket restrictions"
20889+ help
20890+ If you say Y here, you will be able to choose from several options.
20891+ If you assign a GID on your system and add it to the supplementary
20892+ groups of users you want to restrict socket access to, this patch
20893+ will perform up to three things, based on the option(s) you choose.
20894+
20895+config GRKERNSEC_SOCKET_ALL
20896+ bool "Deny any sockets to group"
20897+ depends on GRKERNSEC_SOCKET
20898+ help
20899+ If you say Y here, you will be able to choose a GID of whose users will
20900+ be unable to connect to other hosts from your machine or run server
20901+ applications from your machine. If the sysctl option is enabled, a
20902+ sysctl option with name "socket_all" is created.
20903+
20904+config GRKERNSEC_SOCKET_ALL_GID
20905+ int "GID to deny all sockets for"
20906+ depends on GRKERNSEC_SOCKET_ALL
20907+ default 1004
20908+ help
20909+ Here you can choose the GID to disable socket access for. Remember to
20910+ add the users you want socket access disabled for to the GID
20911+ specified here. If the sysctl option is enabled, a sysctl option
20912+ with name "socket_all_gid" is created.
20913+
20914+config GRKERNSEC_SOCKET_CLIENT
20915+ bool "Deny client sockets to group"
20916+ depends on GRKERNSEC_SOCKET
20917+ help
20918+ If you say Y here, you will be able to choose a GID of whose users will
20919+ be unable to connect to other hosts from your machine, but will be
20920+ able to run servers. If this option is enabled, all users in the group
20921+ you specify will have to use passive mode when initiating ftp transfers
20922+ from the shell on your machine. If the sysctl option is enabled, a
20923+ sysctl option with name "socket_client" is created.
20924+
20925+config GRKERNSEC_SOCKET_CLIENT_GID
20926+ int "GID to deny client sockets for"
20927+ depends on GRKERNSEC_SOCKET_CLIENT
20928+ default 1003
20929+ help
20930+ Here you can choose the GID to disable client socket access for.
20931+ Remember to add the users you want client socket access disabled for to
20932+ the GID specified here. If the sysctl option is enabled, a sysctl
20933+ option with name "socket_client_gid" is created.
20934+
20935+config GRKERNSEC_SOCKET_SERVER
20936+ bool "Deny server sockets to group"
20937+ depends on GRKERNSEC_SOCKET
20938+ help
20939+ If you say Y here, you will be able to choose a GID of whose users will
20940+ be unable to run server applications from your machine. If the sysctl
20941+ option is enabled, a sysctl option with name "socket_server" is created.
20942+
20943+config GRKERNSEC_SOCKET_SERVER_GID
20944+ int "GID to deny server sockets for"
20945+ depends on GRKERNSEC_SOCKET_SERVER
20946+ default 1002
20947+ help
20948+ Here you can choose the GID to disable server socket access for.
20949+ Remember to add the users you want server socket access disabled for to
20950+ the GID specified here. If the sysctl option is enabled, a sysctl
20951+ option with name "socket_server_gid" is created.
20952+
20953+endmenu
20954+menu "Sysctl support"
20955+depends on GRKERNSEC && SYSCTL
20956+
20957+config GRKERNSEC_SYSCTL
20958+ bool "Sysctl support"
20959+ help
20960+ If you say Y here, you will be able to change the options that
20961+ grsecurity runs with at bootup, without having to recompile your
20962+ kernel. You can echo values to files in /proc/sys/kernel/grsecurity
20963+ to enable (1) or disable (0) various features. All the sysctl entries
20964+ are mutable until the "grsec_lock" entry is set to a non-zero value.
20965+ All features enabled in the kernel configuration are disabled at boot
20966+ if you do not say Y to the "Turn on features by default" option.
20967+ All options should be set at startup, and the grsec_lock entry should
20968+ be set to a non-zero value after all the options are set.
20969+ *THIS IS EXTREMELY IMPORTANT*
20970+
20971+config GRKERNSEC_SYSCTL_ON
20972+ bool "Turn on features by default"
20973+ depends on GRKERNSEC_SYSCTL
20974+ help
20975+ If you say Y here, instead of having all features enabled in the
20976+ kernel configuration disabled at boot time, the features will be
20977+ enabled at boot time. It is recommended you say Y here unless
20978+ there is some reason you would want all sysctl-tunable features to
20979+ be disabled by default. As mentioned elsewhere, it is important
20980+ to enable the grsec_lock entry once you have finished modifying
20981+ the sysctl entries.
20982+
20983+endmenu
20984+menu "Logging Options"
20985+depends on GRKERNSEC
20986+
20987+config GRKERNSEC_FLOODTIME
20988+ int "Seconds in between log messages (minimum)"
20989+ default 10
20990+ help
20991+ This option allows you to enforce the number of seconds between
20992+ grsecurity log messages. The default should be suitable for most
20993+ people, however, if you choose to change it, choose a value small enough
20994+ to allow informative logs to be produced, but large enough to
20995+ prevent flooding.
20996+
20997+config GRKERNSEC_FLOODBURST
20998+ int "Number of messages in a burst (maximum)"
20999+ default 4
21000+ help
21001+ This option allows you to choose the maximum number of messages allowed
21002+ within the flood time interval you chose in a separate option. The
21003+ default should be suitable for most people, however if you find that
21004+ many of your logs are being interpreted as flooding, you may want to
21005+ raise this value.
21006+
21007+endmenu
21008+
21009+endmenu
21010diff -urNp linux-2.6.19.1/grsecurity/Makefile linux-2.6.19.1/grsecurity/Makefile
21011--- linux-2.6.19.1/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
21012+++ linux-2.6.19.1/grsecurity/Makefile 2006-12-03 15:16:32.000000000 -0500
21013@@ -0,0 +1,20 @@
21014+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
21015+# during 2001-2005 it has been completely redesigned by Brad Spengler
21016+# into an RBAC system
21017+#
21018+# All code in this directory and various hooks inserted throughout the kernel
21019+# are copyright Brad Spengler, and released under the GPL v2 or higher
21020+
21021+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
21022+ grsec_mount.o grsec_rand.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
21023+ grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
21024+
21025+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
21026+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
21027+ gracl_learn.o grsec_log.o
21028+obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
21029+
21030+ifndef CONFIG_GRKERNSEC
21031+obj-y += grsec_disabled.o
21032+endif
21033+
21034diff -urNp linux-2.6.19.1/include/acpi/acmacros.h linux-2.6.19.1/include/acpi/acmacros.h
21035--- linux-2.6.19.1/include/acpi/acmacros.h 2006-11-29 16:57:37.000000000 -0500
21036+++ linux-2.6.19.1/include/acpi/acmacros.h 2006-12-03 15:16:16.000000000 -0500
21037@@ -672,7 +672,7 @@
21038 #define ACPI_DUMP_PATHNAME(a,b,c,d)
21039 #define ACPI_DUMP_RESOURCE_LIST(a)
21040 #define ACPI_DUMP_BUFFER(a,b)
21041-#define ACPI_DEBUG_PRINT(pl)
21042+#define ACPI_DEBUG_PRINT(pl) do {} while (0)
21043 #define ACPI_DEBUG_PRINT_RAW(pl)
21044
21045 #define return_VOID return
21046diff -urNp linux-2.6.19.1/include/asm-alpha/a.out.h linux-2.6.19.1/include/asm-alpha/a.out.h
21047--- linux-2.6.19.1/include/asm-alpha/a.out.h 2006-11-29 16:57:37.000000000 -0500
21048+++ linux-2.6.19.1/include/asm-alpha/a.out.h 2006-12-03 15:16:16.000000000 -0500
21049@@ -98,7 +98,7 @@ struct exec
21050 set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
21051 ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
21052
21053-#define STACK_TOP \
21054+#define __STACK_TOP \
21055 (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
21056
21057 #endif
21058diff -urNp linux-2.6.19.1/include/asm-alpha/elf.h linux-2.6.19.1/include/asm-alpha/elf.h
21059--- linux-2.6.19.1/include/asm-alpha/elf.h 2006-11-29 16:57:37.000000000 -0500
21060+++ linux-2.6.19.1/include/asm-alpha/elf.h 2006-12-03 15:16:16.000000000 -0500
21061@@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
21062
21063 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x1000000)
21064
21065+#ifdef CONFIG_PAX_ASLR
21066+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
21067+
21068+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
21069+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
21070+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
21071+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
21072+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
21073+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
21074+#endif
21075+
21076 /* $0 is set by ld.so to a pointer to a function which might be
21077 registered using atexit. This provides a mean for the dynamic
21078 linker to call DT_FINI functions for shared libraries that have
21079diff -urNp linux-2.6.19.1/include/asm-alpha/kmap_types.h linux-2.6.19.1/include/asm-alpha/kmap_types.h
21080--- linux-2.6.19.1/include/asm-alpha/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21081+++ linux-2.6.19.1/include/asm-alpha/kmap_types.h 2006-12-03 15:16:16.000000000 -0500
21082@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
21083 D(10) KM_IRQ1,
21084 D(11) KM_SOFTIRQ0,
21085 D(12) KM_SOFTIRQ1,
21086-D(13) KM_TYPE_NR
21087+D(13) KM_CLEARPAGE,
21088+D(14) KM_TYPE_NR
21089 };
21090
21091 #undef D
21092diff -urNp linux-2.6.19.1/include/asm-alpha/page.h linux-2.6.19.1/include/asm-alpha/page.h
21093--- linux-2.6.19.1/include/asm-alpha/page.h 2006-11-29 16:57:37.000000000 -0500
21094+++ linux-2.6.19.1/include/asm-alpha/page.h 2006-12-03 15:16:16.000000000 -0500
21095@@ -93,6 +93,15 @@ typedef unsigned long pgprot_t;
21096 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
21097 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21098
21099+#ifdef CONFIG_PAX_PAGEEXEC
21100+#ifdef CONFIG_PAX_MPROTECT
21101+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21102+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21103+#else
21104+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
21105+#endif
21106+#endif
21107+
21108 #include <asm-generic/memory_model.h>
21109 #include <asm-generic/page.h>
21110
21111diff -urNp linux-2.6.19.1/include/asm-alpha/pgtable.h linux-2.6.19.1/include/asm-alpha/pgtable.h
21112--- linux-2.6.19.1/include/asm-alpha/pgtable.h 2006-11-29 16:57:37.000000000 -0500
21113+++ linux-2.6.19.1/include/asm-alpha/pgtable.h 2006-12-03 15:16:16.000000000 -0500
21114@@ -101,6 +101,17 @@ struct vm_area_struct;
21115 #define PAGE_SHARED __pgprot(_PAGE_VALID | __ACCESS_BITS)
21116 #define PAGE_COPY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
21117 #define PAGE_READONLY __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
21118+
21119+#ifdef CONFIG_PAX_PAGEEXEC
21120+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
21121+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
21122+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
21123+#else
21124+# define PAGE_SHARED_NOEXEC PAGE_SHARED
21125+# define PAGE_COPY_NOEXEC PAGE_COPY
21126+# define PAGE_READONLY_NOEXEC PAGE_READONLY
21127+#endif
21128+
21129 #define PAGE_KERNEL __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
21130
21131 #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
21132diff -urNp linux-2.6.19.1/include/asm-arm/a.out.h linux-2.6.19.1/include/asm-arm/a.out.h
21133--- linux-2.6.19.1/include/asm-arm/a.out.h 2006-11-29 16:57:37.000000000 -0500
21134+++ linux-2.6.19.1/include/asm-arm/a.out.h 2006-12-03 15:16:16.000000000 -0500
21135@@ -28,7 +28,7 @@ struct exec
21136 #define M_ARM 103
21137
21138 #ifdef __KERNEL__
21139-#define STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
21140+#define __STACK_TOP ((current->personality == PER_LINUX_32BIT) ? \
21141 TASK_SIZE : TASK_SIZE_26)
21142 #endif
21143
21144diff -urNp linux-2.6.19.1/include/asm-arm/elf.h linux-2.6.19.1/include/asm-arm/elf.h
21145--- linux-2.6.19.1/include/asm-arm/elf.h 2006-11-29 16:57:37.000000000 -0500
21146+++ linux-2.6.19.1/include/asm-arm/elf.h 2006-12-03 15:16:17.000000000 -0500
21147@@ -57,6 +57,17 @@ typedef struct user_fp elf_fpregset_t;
21148
21149 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
21150
21151+#ifdef CONFIG_PAX_ASLR
21152+#define PAX_ELF_ET_DYN_BASE(tsk) 0x00008000UL
21153+
21154+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
21155+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
21156+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
21157+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
21158+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
21159+#define PAX_DELTA_STACK_LEN(tsk) ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
21160+#endif
21161+
21162 /* When the program starts, a1 contains a pointer to a function to be
21163 registered with atexit, as per the SVR4 ABI. A value of 0 means we
21164 have no such handler. */
21165diff -urNp linux-2.6.19.1/include/asm-arm/kmap_types.h linux-2.6.19.1/include/asm-arm/kmap_types.h
21166--- linux-2.6.19.1/include/asm-arm/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21167+++ linux-2.6.19.1/include/asm-arm/kmap_types.h 2006-12-03 15:16:17.000000000 -0500
21168@@ -18,6 +18,7 @@ enum km_type {
21169 KM_IRQ1,
21170 KM_SOFTIRQ0,
21171 KM_SOFTIRQ1,
21172+ KM_CLEARPAGE,
21173 KM_TYPE_NR
21174 };
21175
21176diff -urNp linux-2.6.19.1/include/asm-arm26/kmap_types.h linux-2.6.19.1/include/asm-arm26/kmap_types.h
21177--- linux-2.6.19.1/include/asm-arm26/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21178+++ linux-2.6.19.1/include/asm-arm26/kmap_types.h 2006-12-03 15:16:17.000000000 -0500
21179@@ -6,7 +6,8 @@
21180 */
21181 enum km_type {
21182 KM_IRQ0,
21183- KM_USER1
21184+ KM_USER1,
21185+ KM_CLEARPAGE
21186 };
21187
21188 #endif
21189diff -urNp linux-2.6.19.1/include/asm-cris/kmap_types.h linux-2.6.19.1/include/asm-cris/kmap_types.h
21190--- linux-2.6.19.1/include/asm-cris/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21191+++ linux-2.6.19.1/include/asm-cris/kmap_types.h 2006-12-03 15:16:19.000000000 -0500
21192@@ -19,6 +19,7 @@ enum km_type {
21193 KM_IRQ1,
21194 KM_SOFTIRQ0,
21195 KM_SOFTIRQ1,
21196+ KM_CLEARPAGE,
21197 KM_TYPE_NR
21198 };
21199
21200diff -urNp linux-2.6.19.1/include/asm-frv/kmap_types.h linux-2.6.19.1/include/asm-frv/kmap_types.h
21201--- linux-2.6.19.1/include/asm-frv/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21202+++ linux-2.6.19.1/include/asm-frv/kmap_types.h 2006-12-03 15:16:19.000000000 -0500
21203@@ -23,6 +23,7 @@ enum km_type {
21204 KM_IRQ1,
21205 KM_SOFTIRQ0,
21206 KM_SOFTIRQ1,
21207+ KM_CLEARPAGE,
21208 KM_TYPE_NR
21209 };
21210
21211diff -urNp linux-2.6.19.1/include/asm-h8300/kmap_types.h linux-2.6.19.1/include/asm-h8300/kmap_types.h
21212--- linux-2.6.19.1/include/asm-h8300/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21213+++ linux-2.6.19.1/include/asm-h8300/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
21214@@ -15,6 +15,7 @@ enum km_type {
21215 KM_IRQ1,
21216 KM_SOFTIRQ0,
21217 KM_SOFTIRQ1,
21218+ KM_CLEARPAGE,
21219 KM_TYPE_NR
21220 };
21221
21222diff -urNp linux-2.6.19.1/include/asm-i386/alternative.h linux-2.6.19.1/include/asm-i386/alternative.h
21223--- linux-2.6.19.1/include/asm-i386/alternative.h 2006-11-29 16:57:37.000000000 -0500
21224+++ linux-2.6.19.1/include/asm-i386/alternative.h 2006-12-03 15:16:20.000000000 -0500
21225@@ -57,7 +57,7 @@ static inline void alternatives_smp_swit
21226 " .byte 662b-661b\n" /* sourcelen */ \
21227 " .byte 664f-663f\n" /* replacementlen */ \
21228 ".previous\n" \
21229- ".section .altinstr_replacement,\"ax\"\n" \
21230+ ".section .altinstr_replacement,\"a\"\n" \
21231 "663:\n\t" newinstr "\n664:\n" /* replacement */\
21232 ".previous" :: "i" (feature) : "memory")
21233
21234@@ -81,7 +81,7 @@ static inline void alternatives_smp_swit
21235 " .byte 662b-661b\n" /* sourcelen */ \
21236 " .byte 664f-663f\n" /* replacementlen */ \
21237 ".previous\n" \
21238- ".section .altinstr_replacement,\"ax\"\n" \
21239+ ".section .altinstr_replacement,\"a\"\n" \
21240 "663:\n\t" newinstr "\n664:\n" /* replacement */\
21241 ".previous" :: "i" (feature), ##input)
21242
21243diff -urNp linux-2.6.19.1/include/asm-i386/a.out.h linux-2.6.19.1/include/asm-i386/a.out.h
21244--- linux-2.6.19.1/include/asm-i386/a.out.h 2006-11-29 16:57:37.000000000 -0500
21245+++ linux-2.6.19.1/include/asm-i386/a.out.h 2006-12-03 15:16:20.000000000 -0500
21246@@ -19,7 +19,11 @@ struct exec
21247
21248 #ifdef __KERNEL__
21249
21250-#define STACK_TOP TASK_SIZE
21251+#ifdef CONFIG_PAX_SEGMEXEC
21252+#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
21253+#else
21254+#define __STACK_TOP TASK_SIZE
21255+#endif
21256
21257 #endif
21258
21259diff -urNp linux-2.6.19.1/include/asm-i386/apic.h linux-2.6.19.1/include/asm-i386/apic.h
21260--- linux-2.6.19.1/include/asm-i386/apic.h 2006-11-29 16:57:37.000000000 -0500
21261+++ linux-2.6.19.1/include/asm-i386/apic.h 2006-12-03 15:16:20.000000000 -0500
21262@@ -7,7 +7,7 @@
21263 #include <asm/processor.h>
21264 #include <asm/system.h>
21265
21266-#define Dprintk(x...)
21267+#define Dprintk(x...) do {} while (0)
21268
21269 /*
21270 * Debugging macros
21271diff -urNp linux-2.6.19.1/include/asm-i386/bug.h linux-2.6.19.1/include/asm-i386/bug.h
21272--- linux-2.6.19.1/include/asm-i386/bug.h 2006-11-29 16:57:37.000000000 -0500
21273+++ linux-2.6.19.1/include/asm-i386/bug.h 2006-12-03 15:16:20.000000000 -0500
21274@@ -11,10 +11,9 @@
21275 #ifdef CONFIG_BUG
21276 #define HAVE_ARCH_BUG
21277 #ifdef CONFIG_DEBUG_BUGVERBOSE
21278-#define BUG() \
21279- __asm__ __volatile__( "ud2\n" \
21280- "\t.word %c0\n" \
21281- "\t.long %c1\n" \
21282+#define BUG() \
21283+ __asm__ __volatile__( "ud2\n\t" \
21284+ "ljmp %0, %1\n\t" \
21285 : : "i" (__LINE__), "i" (__FILE__))
21286 #else
21287 #define BUG() __asm__ __volatile__("ud2\n")
21288diff -urNp linux-2.6.19.1/include/asm-i386/checksum.h linux-2.6.19.1/include/asm-i386/checksum.h
21289--- linux-2.6.19.1/include/asm-i386/checksum.h 2006-11-29 16:57:37.000000000 -0500
21290+++ linux-2.6.19.1/include/asm-i386/checksum.h 2006-12-03 15:16:20.000000000 -0500
21291@@ -30,6 +30,12 @@ asmlinkage unsigned int csum_partial(con
21292 asmlinkage unsigned int csum_partial_copy_generic(const unsigned char *src, unsigned char *dst,
21293 int len, int sum, int *src_err_ptr, int *dst_err_ptr);
21294
21295+asmlinkage unsigned int csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
21296+ int len, int sum, int *src_err_ptr, int *dst_err_ptr);
21297+
21298+asmlinkage unsigned int csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
21299+ int len, int sum, int *src_err_ptr, int *dst_err_ptr);
21300+
21301 /*
21302 * Note: when you get a NULL pointer exception here this means someone
21303 * passed in an incorrect kernel address to one of these functions.
21304@@ -49,7 +55,7 @@ unsigned int csum_partial_copy_from_user
21305 int len, int sum, int *err_ptr)
21306 {
21307 might_sleep();
21308- return csum_partial_copy_generic((__force unsigned char *)src, dst,
21309+ return csum_partial_copy_generic_from_user((__force unsigned char *)src, dst,
21310 len, sum, err_ptr, NULL);
21311 }
21312
21313@@ -183,7 +189,7 @@ static __inline__ unsigned int csum_and_
21314 {
21315 might_sleep();
21316 if (access_ok(VERIFY_WRITE, dst, len))
21317- return csum_partial_copy_generic(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
21318+ return csum_partial_copy_generic_to_user(src, (__force unsigned char *)dst, len, sum, NULL, err_ptr);
21319
21320 if (len)
21321 *err_ptr = -EFAULT;
21322diff -urNp linux-2.6.19.1/include/asm-i386/desc.h linux-2.6.19.1/include/asm-i386/desc.h
21323--- linux-2.6.19.1/include/asm-i386/desc.h 2006-11-29 16:57:37.000000000 -0500
21324+++ linux-2.6.19.1/include/asm-i386/desc.h 2006-12-03 15:16:20.000000000 -0500
21325@@ -10,11 +10,13 @@
21326
21327 #include <linux/preempt.h>
21328 #include <linux/smp.h>
21329-#include <linux/percpu.h>
21330+#include <linux/sched.h>
21331
21332 #include <asm/mmu.h>
21333+#include <asm/pgtable.h>
21334+#include <asm/tlbflush.h>
21335
21336-extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
21337+extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
21338
21339 DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);
21340
21341@@ -24,20 +26,33 @@ struct Xgt_desc_struct {
21342 unsigned short pad;
21343 } __attribute__ ((packed));
21344
21345-extern struct Xgt_desc_struct idt_descr;
21346-DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
21347-
21348+extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
21349
21350 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
21351 {
21352- return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
21353+ return cpu_gdt_table[cpu];
21354 }
21355
21356+#define pax_open_kernel(cr0) \
21357+do { \
21358+ typecheck(unsigned long,cr0); \
21359+ preempt_disable(); \
21360+ cr0 = read_cr0(); \
21361+ write_cr0(cr0 & ~0x10000UL); \
21362+} while(0)
21363+
21364+#define pax_close_kernel(cr0) \
21365+do { \
21366+ typecheck(unsigned long,cr0); \
21367+ write_cr0(cr0); \
21368+ preempt_enable_no_resched(); \
21369+} while(0)
21370+
21371 /*
21372 * This is the ldt that every process will get unless we need
21373 * something other than this.
21374 */
21375-extern struct desc_struct default_ldt[];
21376+extern const struct desc_struct default_ldt[];
21377 extern struct desc_struct idt_table[];
21378 extern void set_intr_gate(unsigned int irq, void * addr);
21379
21380@@ -91,8 +106,20 @@ static inline void load_TLS(struct threa
21381 static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b)
21382 {
21383 __u32 *lp = (__u32 *)((char *)dt + entry*8);
21384+
21385+#ifdef CONFIG_PAX_KERNEXEC
21386+ unsigned long cr0;
21387+
21388+ pax_open_kernel(cr0);
21389+#endif
21390+
21391 *lp = entry_a;
21392 *(lp+1) = entry_b;
21393+
21394+#ifdef CONFIG_PAX_KERNEXEC
21395+ pax_close_kernel(cr0);
21396+#endif
21397+
21398 }
21399
21400 #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
21401@@ -115,7 +142,7 @@ static inline void __set_tss_desc(unsign
21402 write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b);
21403 }
21404
21405-static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries)
21406+static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int entries)
21407 {
21408 __u32 a, b;
21409 pack_descriptor(&a, &b, (unsigned long)addr,
21410@@ -139,7 +166,7 @@ static inline void set_ldt_desc(unsigned
21411 ((info)->seg_32bit << 22) | \
21412 ((info)->limit_in_pages << 23) | \
21413 ((info)->useable << 20) | \
21414- 0x7000)
21415+ 0x7100)
21416
21417 #define LDT_empty(info) (\
21418 (info)->base_addr == 0 && \
21419@@ -165,7 +192,7 @@ static inline void clear_LDT(void)
21420 */
21421 static inline void load_LDT_nolock(mm_context_t *pc, int cpu)
21422 {
21423- void *segments = pc->ldt;
21424+ const void *segments = pc->ldt;
21425 int count = pc->size;
21426
21427 if (likely(!count)) {
21428@@ -184,15 +211,25 @@ static inline void load_LDT(mm_context_t
21429 put_cpu();
21430 }
21431
21432-static inline unsigned long get_desc_base(unsigned long *desc)
21433+static inline unsigned long get_desc_base(struct desc_struct *desc)
21434 {
21435 unsigned long base;
21436- base = ((desc[0] >> 16) & 0x0000ffff) |
21437- ((desc[1] << 16) & 0x00ff0000) |
21438- (desc[1] & 0xff000000);
21439+ base = ((desc->a >> 16) & 0x0000ffff) |
21440+ ((desc->b << 16) & 0x00ff0000) |
21441+ (desc->b & 0xff000000);
21442 return base;
21443 }
21444
21445+static inline void set_user_cs(struct mm_struct *mm, int cpu)
21446+{
21447+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21448+ __u32 a, b;
21449+
21450+ pack_descriptor(&a, &b, mm->context.user_cs_base, mm->context.user_cs_limit - 1, 0xFB, 0xC);
21451+ write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
21452+#endif
21453+}
21454+
21455 #endif /* !__ASSEMBLY__ */
21456
21457 #endif
21458diff -urNp linux-2.6.19.1/include/asm-i386/elf.h linux-2.6.19.1/include/asm-i386/elf.h
21459--- linux-2.6.19.1/include/asm-i386/elf.h 2006-11-29 16:57:37.000000000 -0500
21460+++ linux-2.6.19.1/include/asm-i386/elf.h 2006-12-03 15:16:20.000000000 -0500
21461@@ -75,7 +75,22 @@ typedef struct user_fxsr_struct elf_fpxr
21462 the loader. We need to make sure that it is out of the way of the program
21463 that it will "exec", and that there is sufficient room for the brk. */
21464
21465+#ifdef CONFIG_PAX_SEGMEXEC
b6fa5d20 21466+#define ELF_ET_DYN_BASE ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : (TASK_UNMAPPED_BASE) * 2)
c3e8c1b5 21467+#else
5c9295bc 21468 #define ELF_ET_DYN_BASE ((TASK_UNMAPPED_BASE) * 2)
c3e8c1b5 21469+#endif
21470+
21471+#ifdef CONFIG_PAX_ASLR
21472+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000000UL
21473+
21474+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
21475+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
21476+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
21477+#define PAX_DELTA_EXEC_LEN(tsk) 15
21478+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
21479+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
21480+#endif
21481
21482 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
21483 now struct_user_regs, they are different) */
21484@@ -133,7 +148,7 @@ extern int dump_task_extended_fpu (struc
21485 #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
21486
21487 #define VDSO_HIGH_BASE (__fix_to_virt(FIX_VDSO))
21488-#define VDSO_BASE ((unsigned long)current->mm->context.vdso)
21489+#define VDSO_BASE (current->mm->context.vdso)
21490
21491 #ifdef CONFIG_COMPAT_VDSO
21492 # define VDSO_COMPAT_BASE VDSO_HIGH_BASE
21493diff -urNp linux-2.6.19.1/include/asm-i386/i387.h linux-2.6.19.1/include/asm-i386/i387.h
21494--- linux-2.6.19.1/include/asm-i386/i387.h 2006-11-29 16:57:37.000000000 -0500
21495+++ linux-2.6.19.1/include/asm-i386/i387.h 2006-12-03 15:16:20.000000000 -0500
21496@@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
21497 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
21498
21499 /* We need a safe address that is cheap to find and that is already
21500- in L1 during context switch. The best choices are unfortunately
21501- different for UP and SMP */
21502-#ifdef CONFIG_SMP
21503-#define safe_address (__per_cpu_offset[0])
21504-#else
21505-#define safe_address (kstat_cpu(0).cpustat.user)
21506-#endif
21507+ in L1 during context switch. */
21508+#define safe_address (init_tss[smp_processor_id()].esp0)
21509
21510 /*
21511 * These must be called with preempt disabled
21512diff -urNp linux-2.6.19.1/include/asm-i386/kmap_types.h linux-2.6.19.1/include/asm-i386/kmap_types.h
21513--- linux-2.6.19.1/include/asm-i386/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
21514+++ linux-2.6.19.1/include/asm-i386/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
21515@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
21516 D(10) KM_IRQ1,
21517 D(11) KM_SOFTIRQ0,
21518 D(12) KM_SOFTIRQ1,
21519-D(13) KM_TYPE_NR
21520+D(13) KM_CLEARPAGE,
21521+D(14) KM_TYPE_NR
21522 };
21523
21524 #undef D
21525diff -urNp linux-2.6.19.1/include/asm-i386/mach-default/apm.h linux-2.6.19.1/include/asm-i386/mach-default/apm.h
21526--- linux-2.6.19.1/include/asm-i386/mach-default/apm.h 2006-11-29 16:57:37.000000000 -0500
21527+++ linux-2.6.19.1/include/asm-i386/mach-default/apm.h 2006-12-03 15:16:20.000000000 -0500
21528@@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
21529 __asm__ __volatile__(APM_DO_ZERO_SEGS
21530 "pushl %%edi\n\t"
21531 "pushl %%ebp\n\t"
21532- "lcall *%%cs:apm_bios_entry\n\t"
21533+ "lcall *%%ss:apm_bios_entry\n\t"
21534 "setc %%al\n\t"
21535 "popl %%ebp\n\t"
21536 "popl %%edi\n\t"
21537@@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
21538 __asm__ __volatile__(APM_DO_ZERO_SEGS
21539 "pushl %%edi\n\t"
21540 "pushl %%ebp\n\t"
21541- "lcall *%%cs:apm_bios_entry\n\t"
21542+ "lcall *%%ss:apm_bios_entry\n\t"
21543 "setc %%bl\n\t"
21544 "popl %%ebp\n\t"
21545 "popl %%edi\n\t"
21546diff -urNp linux-2.6.19.1/include/asm-i386/mach-default/do_timer.h linux-2.6.19.1/include/asm-i386/mach-default/do_timer.h
21547--- linux-2.6.19.1/include/asm-i386/mach-default/do_timer.h 2006-11-29 16:57:37.000000000 -0500
21548+++ linux-2.6.19.1/include/asm-i386/mach-default/do_timer.h 2006-12-03 15:16:20.000000000 -0500
21549@@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
21550 {
21551 do_timer(1);
21552 #ifndef CONFIG_SMP
21553- update_process_times(user_mode_vm(get_irq_regs()));
21554+ update_process_times(user_mode(get_irq_regs()));
21555 #endif
21556 /*
21557 * In the SMP case we use the local APIC timer interrupt to do the
21558diff -urNp linux-2.6.19.1/include/asm-i386/mach-voyager/do_timer.h linux-2.6.19.1/include/asm-i386/mach-voyager/do_timer.h
21559--- linux-2.6.19.1/include/asm-i386/mach-voyager/do_timer.h 2006-11-29 16:57:37.000000000 -0500
21560+++ linux-2.6.19.1/include/asm-i386/mach-voyager/do_timer.h 2006-12-03 15:16:20.000000000 -0500
21561@@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
21562 {
21563 do_timer(1);
21564 #ifndef CONFIG_SMP
21565- update_process_times(user_mode_vm(irq_regs));
21566+ update_process_times(user_mode(irq_regs));
21567 #endif
21568
21569 voyager_timer_interrupt();
21570diff -urNp linux-2.6.19.1/include/asm-i386/mman.h linux-2.6.19.1/include/asm-i386/mman.h
21571--- linux-2.6.19.1/include/asm-i386/mman.h 2006-11-29 16:57:37.000000000 -0500
21572+++ linux-2.6.19.1/include/asm-i386/mman.h 2006-12-03 15:16:20.000000000 -0500
21573@@ -11,6 +11,10 @@
21574 #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */
21575 #define MAP_NONBLOCK 0x10000 /* do not block on IO */
21576
21577+#ifdef CONFIG_PAX_SEGMEXEC
21578+#define MAP_MIRROR 0x20000
21579+#endif
21580+
21581 #define MCL_CURRENT 1 /* lock all current mappings */
21582 #define MCL_FUTURE 2 /* lock all future mappings */
21583
21584diff -urNp linux-2.6.19.1/include/asm-i386/mmu_context.h linux-2.6.19.1/include/asm-i386/mmu_context.h
21585--- linux-2.6.19.1/include/asm-i386/mmu_context.h 2006-11-29 16:57:37.000000000 -0500
21586+++ linux-2.6.19.1/include/asm-i386/mmu_context.h 2006-12-03 15:16:20.000000000 -0500
21587@@ -45,6 +45,17 @@ static inline void switch_mm(struct mm_s
21588 */
21589 if (unlikely(prev->context.ldt != next->context.ldt))
21590 load_LDT_nolock(&next->context, cpu);
21591+
21592+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
21593+ cpu_clear(cpu, prev->context.cpu_user_cs_mask);
21594+ cpu_set(cpu, next->context.cpu_user_cs_mask);
21595+#endif
21596+
21597+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21598+ if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
21599+ prev->context.user_cs_limit != next->context.user_cs_limit))
21600+#endif
21601+ set_user_cs(next, cpu);
21602 }
21603 #ifdef CONFIG_SMP
21604 else {
21605@@ -57,6 +68,12 @@ static inline void switch_mm(struct mm_s
21606 */
21607 load_cr3(next->pgd);
21608 load_LDT_nolock(&next->context, cpu);
21609+
21610+#ifdef CONFIG_PAX_PAGEEXEC
21611+ cpu_set(cpu, next->context.cpu_user_cs_mask);
21612+#endif
21613+
21614+ set_user_cs(next, cpu);
21615 }
21616 }
21617 #endif
21618diff -urNp linux-2.6.19.1/include/asm-i386/mmu.h linux-2.6.19.1/include/asm-i386/mmu.h
21619--- linux-2.6.19.1/include/asm-i386/mmu.h 2006-11-29 16:57:37.000000000 -0500
21620+++ linux-2.6.19.1/include/asm-i386/mmu.h 2006-12-03 15:16:20.000000000 -0500
21621@@ -11,8 +11,19 @@
21622 typedef struct {
21623 int size;
21624 struct semaphore sem;
21625- void *ldt;
21626- void *vdso;
21627+ struct desc_struct *ldt;
21628+ unsigned long vdso;
21629+
21630+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21631+ unsigned long user_cs_base;
21632+ unsigned long user_cs_limit;
21633+
21634+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
21635+ cpumask_t cpu_user_cs_mask;
21636+#endif
21637+
21638+#endif
21639+
21640 } mm_context_t;
21641
21642 #endif
21643diff -urNp linux-2.6.19.1/include/asm-i386/module.h linux-2.6.19.1/include/asm-i386/module.h
21644--- linux-2.6.19.1/include/asm-i386/module.h 2006-11-29 16:57:37.000000000 -0500
21645+++ linux-2.6.19.1/include/asm-i386/module.h 2006-12-03 15:16:20.000000000 -0500
21646@@ -72,6 +72,12 @@ struct mod_arch_specific
21647 #define MODULE_STACKSIZE ""
21648 #endif
21649
21650-#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE
21651+#ifdef CONFIG_GRKERNSEC
21652+#define MODULE_GRSEC "GRSECURITY "
21653+#else
21654+#define MODULE_GRSEC ""
21655+#endif
21656+
21657+#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_REGPARM MODULE_STACKSIZE MODULE_GRSEC
21658
21659 #endif /* _ASM_I386_MODULE_H */
21660diff -urNp linux-2.6.19.1/include/asm-i386/page.h linux-2.6.19.1/include/asm-i386/page.h
21661--- linux-2.6.19.1/include/asm-i386/page.h 2006-11-29 16:57:37.000000000 -0500
21662+++ linux-2.6.19.1/include/asm-i386/page.h 2006-12-03 15:16:20.000000000 -0500
21663@@ -51,13 +51,14 @@ typedef struct { unsigned long long pgpr
21664 #define pmd_val(x) ((x).pmd)
21665 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
21666 #define __pmd(x) ((pmd_t) { (x) } )
21667+#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
21668 #define HPAGE_SHIFT 21
21669 #else
21670 typedef struct { unsigned long pte_low; } pte_t;
21671 typedef struct { unsigned long pgd; } pgd_t;
21672 typedef struct { unsigned long pgprot; } pgprot_t;
21673-#define boot_pte_t pte_t /* or would you rather have a typedef */
21674 #define pte_val(x) ((x).pte_low)
21675+#define __pte(x) ((pte_t) { (x) } )
21676 #define HPAGE_SHIFT 22
21677 #endif
21678 #define PTE_MASK PAGE_MASK
21679@@ -72,7 +73,6 @@ typedef struct { unsigned long pgprot; }
21680 #define pgd_val(x) ((x).pgd)
21681 #define pgprot_val(x) ((x).pgprot)
21682
21683-#define __pte(x) ((pte_t) { (x) } )
21684 #define __pgd(x) ((pgd_t) { (x) } )
21685 #define __pgprot(x) ((pgprot_t) { (x) } )
21686
21687@@ -119,6 +119,15 @@ extern int page_is_ram(unsigned long pag
21688 #endif
21689 #define __KERNEL_START (__PAGE_OFFSET + __PHYSICAL_START)
21690
21691+#ifdef CONFIG_PAX_KERNEXEC
21692+#define __KERNEL_TEXT_OFFSET (__PAGE_OFFSET + ((__PHYSICAL_START + ~(4*1024*1024)) & (4*1024*1024)))
21693+#ifndef __ASSEMBLY__
21694+extern unsigned char MODULES_VADDR[];
21695+extern unsigned char MODULES_END[];
21696+#endif
21697+#else
21698+#define __KERNEL_TEXT_OFFSET (0)
21699+#endif
21700
21701 #define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
21702 #define VMALLOC_RESERVE ((unsigned long)__VMALLOC_RESERVE)
21703@@ -138,6 +147,19 @@ extern int page_is_ram(unsigned long pag
21704 ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
21705 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
21706
21707+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
21708+#ifdef CONFIG_PAX_MPROTECT
21709+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
21710+ ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
21711+#else
21712+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
21713+#endif
21714+#endif
21715+
21716+#ifdef CONFIG_PAX_PAGEEXEC
21717+#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
21718+#endif
21719+
21720 #include <asm-generic/memory_model.h>
21721 #include <asm-generic/page.h>
21722
21723diff -urNp linux-2.6.19.1/include/asm-i386/pgalloc.h linux-2.6.19.1/include/asm-i386/pgalloc.h
21724--- linux-2.6.19.1/include/asm-i386/pgalloc.h 2006-11-29 16:57:37.000000000 -0500
21725+++ linux-2.6.19.1/include/asm-i386/pgalloc.h 2006-12-03 15:16:20.000000000 -0500
21726@@ -2,11 +2,17 @@
21727 #define _I386_PGALLOC_H
21728
21729 #include <asm/fixmap.h>
21730+#include <asm/desc.h>
21731 #include <linux/threads.h>
21732 #include <linux/mm.h> /* for struct page */
21733
21734+#ifdef CONFIG_COMPAT_VDSO
21735 #define pmd_populate_kernel(mm, pmd, pte) \
21736 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
21737+#else
21738+#define pmd_populate_kernel(mm, pmd, pte) \
21739+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
21740+#endif
21741
21742 #define pmd_populate(mm, pmd, pte) \
21743 set_pmd(pmd, __pmd(_PAGE_TABLE + \
21744diff -urNp linux-2.6.19.1/include/asm-i386/pgtable.h linux-2.6.19.1/include/asm-i386/pgtable.h
21745--- linux-2.6.19.1/include/asm-i386/pgtable.h 2006-11-29 16:57:37.000000000 -0500
21746+++ linux-2.6.19.1/include/asm-i386/pgtable.h 2006-12-03 15:16:20.000000000 -0500
21747@@ -33,7 +33,6 @@ struct vm_area_struct;
21748 */
21749 #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
21750 extern unsigned long empty_zero_page[1024];
21751-extern pgd_t swapper_pg_dir[1024];
21752 extern kmem_cache_t *pgd_cache;
21753 extern kmem_cache_t *pmd_cache;
21754 extern spinlock_t pgd_lock;
21755@@ -58,6 +57,11 @@ void paging_init(void);
21756 # include <asm/pgtable-2level-defs.h>
21757 #endif
21758
21759+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
21760+#ifdef CONFIG_X86_PAE
21761+extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
21762+#endif
21763+
21764 #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
21765 #define PGDIR_MASK (~(PGDIR_SIZE-1))
21766
21767@@ -67,9 +71,11 @@ void paging_init(void);
21768 #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
21769 #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
21770
21771+#ifndef CONFIG_X86_PAE
21772 #define TWOLEVEL_PGDIR_SHIFT 22
21773 #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
21774 #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
21775+#endif
21776
21777 /* Just any arbitrary offset to the start of the vmalloc VM area: the
21778 * current 8MB value just means that there will be a 8MB "hole" after the
21779@@ -140,17 +146,26 @@ void paging_init(void);
21780
21781 #define PAGE_SHARED_EXEC \
21782 __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
21783-#define PAGE_COPY_NOEXEC \
21784- __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21785 #define PAGE_COPY_EXEC \
21786 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
21787-#define PAGE_COPY \
21788- PAGE_COPY_NOEXEC
21789 #define PAGE_READONLY \
21790 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21791 #define PAGE_READONLY_EXEC \
21792 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
21793
21794+#ifdef CONFIG_PAX_PAGEEXEC
21795+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
21796+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
21797+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
21798+#else
21799+# define PAGE_SHARED_NOEXEC PAGE_SHARED
21800+# define PAGE_COPY_NOEXEC \
21801+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
21802+# define PAGE_READONLY_NOEXEC PAGE_READONLY
21803+#endif
21804+
21805+#define PAGE_COPY \
21806+ PAGE_COPY_NOEXEC
21807 #define _PAGE_KERNEL \
21808 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
21809 #define _PAGE_KERNEL_EXEC \
21810@@ -175,18 +190,18 @@ extern unsigned long long __PAGE_KERNEL,
21811 * This is the closest we can get..
21812 */
21813 #define __P000 PAGE_NONE
21814-#define __P001 PAGE_READONLY
21815-#define __P010 PAGE_COPY
21816-#define __P011 PAGE_COPY
21817+#define __P001 PAGE_READONLY_NOEXEC
21818+#define __P010 PAGE_COPY_NOEXEC
21819+#define __P011 PAGE_COPY_NOEXEC
21820 #define __P100 PAGE_READONLY_EXEC
21821 #define __P101 PAGE_READONLY_EXEC
21822 #define __P110 PAGE_COPY_EXEC
21823 #define __P111 PAGE_COPY_EXEC
21824
21825 #define __S000 PAGE_NONE
21826-#define __S001 PAGE_READONLY
21827-#define __S010 PAGE_SHARED
21828-#define __S011 PAGE_SHARED
21829+#define __S001 PAGE_READONLY_NOEXEC
21830+#define __S010 PAGE_SHARED_NOEXEC
21831+#define __S011 PAGE_SHARED_NOEXEC
21832 #define __S100 PAGE_READONLY_EXEC
21833 #define __S101 PAGE_READONLY_EXEC
21834 #define __S110 PAGE_SHARED_EXEC
21835@@ -487,6 +502,9 @@ do { \
21836 #define update_mmu_cache(vma,address,pte) do { } while (0)
21837 #endif /* !__ASSEMBLY__ */
21838
21839+#define HAVE_ARCH_UNMAPPED_AREA
21840+#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
21841+
21842 #ifdef CONFIG_FLATMEM
21843 #define kern_addr_valid(addr) (1)
21844 #endif /* CONFIG_FLATMEM */
21845diff -urNp linux-2.6.19.1/include/asm-i386/processor.h linux-2.6.19.1/include/asm-i386/processor.h
21846--- linux-2.6.19.1/include/asm-i386/processor.h 2006-11-29 16:57:37.000000000 -0500
21847+++ linux-2.6.19.1/include/asm-i386/processor.h 2006-12-03 15:16:20.000000000 -0500
21848@@ -18,7 +18,6 @@
21849 #include <asm/system.h>
21850 #include <linux/cache.h>
21851 #include <linux/threads.h>
21852-#include <asm/percpu.h>
21853 #include <linux/cpumask.h>
21854
21855 /* flag for disabling the tsc */
21856@@ -97,8 +96,6 @@ struct cpuinfo_x86 {
21857
21858 extern struct cpuinfo_x86 boot_cpu_data;
21859 extern struct cpuinfo_x86 new_cpu_data;
21860-extern struct tss_struct doublefault_tss;
21861-DECLARE_PER_CPU(struct tss_struct, init_tss);
21862
21863 #ifdef CONFIG_SMP
21864 extern struct cpuinfo_x86 cpu_data[];
21865@@ -323,10 +320,19 @@ extern int bootloader_type;
21866 */
21867 #define TASK_SIZE (PAGE_OFFSET)
21868
21869+#ifdef CONFIG_PAX_SEGMEXEC
21870+#define SEGMEXEC_TASK_SIZE ((PAGE_OFFSET) / 2)
21871+#endif
21872+
21873 /* This decides where the kernel will search for a free chunk of vm
21874 * space during mmap's.
21875 */
21876+
21877+#ifdef CONFIG_PAX_SEGMEXEC
21878+#define TASK_UNMAPPED_BASE (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
21879+#else
21880 #define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
21881+#endif
21882
21883 #define HAVE_ARCH_PICK_MMAP_LAYOUT
21884
21885@@ -442,6 +448,9 @@ struct tss_struct {
21886
21887 #define ARCH_MIN_TASKALIGN 16
21888
21889+extern struct tss_struct doublefault_tss;
21890+extern struct tss_struct init_tss[NR_CPUS];
21891+
21892 struct thread_struct {
21893 /* cached TLS descriptors. */
21894 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
21895@@ -470,6 +479,7 @@ struct thread_struct {
21896 };
21897
21898 #define INIT_THREAD { \
21899+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
21900 .vm86_info = NULL, \
21901 .sysenter_cs = __KERNEL_CS, \
21902 .io_bitmap_ptr = NULL, \
21903@@ -482,7 +492,7 @@ struct thread_struct {
21904 * be within the limit.
21905 */
21906 #define INIT_TSS { \
21907- .esp0 = sizeof(init_stack) + (long)&init_stack, \
21908+ .esp0 = sizeof(init_stack) + (long)&init_stack - 8, \
21909 .ss0 = __KERNEL_DS, \
21910 .ss1 = __KERNEL_CS, \
21911 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET, \
21912@@ -558,11 +568,7 @@ void show_trace(struct task_struct *task
21913 unsigned long get_wchan(struct task_struct *p);
21914
21915 #define THREAD_SIZE_LONGS (THREAD_SIZE/sizeof(unsigned long))
21916-#define KSTK_TOP(info) \
21917-({ \
21918- unsigned long *__ptr = (unsigned long *)(info); \
21919- (unsigned long)(&__ptr[THREAD_SIZE_LONGS]); \
21920-})
21921+#define KSTK_TOP(info) ((info)->task.thread.esp0)
21922
21923 /*
21924 * The below -8 is to reserve 8 bytes on top of the ring0 stack.
21925@@ -577,7 +583,7 @@ unsigned long get_wchan(struct task_stru
21926 #define task_pt_regs(task) \
21927 ({ \
21928 struct pt_regs *__regs__; \
21929- __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
21930+ __regs__ = (struct pt_regs *)((task)->thread.esp0); \
21931 __regs__ - 1; \
21932 })
21933
21934diff -urNp linux-2.6.19.1/include/asm-i386/ptrace.h linux-2.6.19.1/include/asm-i386/ptrace.h
21935--- linux-2.6.19.1/include/asm-i386/ptrace.h 2006-11-29 16:57:37.000000000 -0500
21936+++ linux-2.6.19.1/include/asm-i386/ptrace.h 2006-12-03 15:16:20.000000000 -0500
21937@@ -33,17 +33,18 @@ struct task_struct;
21938 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
21939
21940 /*
21941- * user_mode_vm(regs) determines whether a register set came from user mode.
21942+ * user_mode(regs) determines whether a register set came from user mode.
21943 * This is true if V8086 mode was enabled OR if the register set was from
21944 * protected mode with RPL-3 CS value. This tricky test checks that with
21945 * one comparison. Many places in the kernel can bypass this full check
21946- * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
21947+ * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
21948+ * be used.
21949 */
21950-static inline int user_mode(struct pt_regs *regs)
21951+static inline int user_mode_novm(struct pt_regs *regs)
21952 {
21953 return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
21954 }
21955-static inline int user_mode_vm(struct pt_regs *regs)
21956+static inline int user_mode(struct pt_regs *regs)
21957 {
21958 return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
21959 }
21960diff -urNp linux-2.6.19.1/include/asm-i386/segment.h linux-2.6.19.1/include/asm-i386/segment.h
21961--- linux-2.6.19.1/include/asm-i386/segment.h 2006-11-29 16:57:37.000000000 -0500
21962+++ linux-2.6.19.1/include/asm-i386/segment.h 2006-12-03 15:16:20.000000000 -0500
21963@@ -84,9 +84,9 @@
21964 #define GDT_SIZE (GDT_ENTRIES * 8)
21965
21966 /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
21967-#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
21968+#define SEGMENT_IS_FLAT_CODE(x) (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
21969 /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
21970-#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
21971+#define SEGMENT_IS_PNP_CODE(x) (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
21972
21973 /* Simple and small GDT entries for booting only */
21974
21975diff -urNp linux-2.6.19.1/include/asm-i386/system.h linux-2.6.19.1/include/asm-i386/system.h
21976--- linux-2.6.19.1/include/asm-i386/system.h 2006-11-29 16:57:37.000000000 -0500
21977+++ linux-2.6.19.1/include/asm-i386/system.h 2006-12-03 15:16:20.000000000 -0500
21978@@ -4,6 +4,7 @@
21979 #include <linux/kernel.h>
21980 #include <asm/segment.h>
21981 #include <asm/cpufeature.h>
21982+#include <asm/page.h>
21983 #include <linux/bitops.h> /* for LOCK_PREFIX */
21984
21985 #ifdef __KERNEL__
21986@@ -155,7 +156,7 @@ static inline unsigned long get_limit(un
21987 unsigned long __limit;
21988 __asm__("lsll %1,%0"
21989 :"=r" (__limit):"r" (segment));
21990- return __limit+1;
21991+ return __limit;
21992 }
21993
21994 #define nop() __asm__ __volatile__ ("nop")
21995@@ -516,7 +517,7 @@ static inline void sched_cacheflush(void
21996 wbinvd();
21997 }
21998
21999-extern unsigned long arch_align_stack(unsigned long sp);
22000+#define arch_align_stack(x) (x)
22001 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
22002
22003 void default_idle(void);
22004diff -urNp linux-2.6.19.1/include/asm-i386/uaccess.h linux-2.6.19.1/include/asm-i386/uaccess.h
22005--- linux-2.6.19.1/include/asm-i386/uaccess.h 2006-11-29 16:57:37.000000000 -0500
22006+++ linux-2.6.19.1/include/asm-i386/uaccess.h 2006-12-03 15:16:20.000000000 -0500
22007@@ -9,6 +9,8 @@
22008 #include <linux/prefetch.h>
22009 #include <linux/string.h>
22010 #include <asm/page.h>
22011+#include <asm/segment.h>
22012+#include <asm/desc.h>
22013
22014 #define VERIFY_READ 0
22015 #define VERIFY_WRITE 1
22016@@ -29,7 +31,8 @@
22017
22018 #define get_ds() (KERNEL_DS)
22019 #define get_fs() (current_thread_info()->addr_limit)
22020-#define set_fs(x) (current_thread_info()->addr_limit = (x))
22021+void __set_fs(mm_segment_t x, int cpu);
22022+void set_fs(mm_segment_t x);
22023
22024 #define segment_eq(a,b) ((a).seg == (b).seg)
22025
22026@@ -280,9 +283,12 @@ extern void __put_user_8(void);
22027
22028 #define __put_user_u64(x, addr, err) \
22029 __asm__ __volatile__( \
22030- "1: movl %%eax,0(%2)\n" \
22031- "2: movl %%edx,4(%2)\n" \
22032+ " movw %w5,%%ds\n" \
22033+ "1: movl %%eax,%%ds:0(%2)\n" \
22034+ "2: movl %%edx,%%ds:4(%2)\n" \
22035 "3:\n" \
22036+ " pushl %%ss\n" \
22037+ " popl %%ds\n" \
22038 ".section .fixup,\"ax\"\n" \
22039 "4: movl %3,%0\n" \
22040 " jmp 3b\n" \
22041@@ -293,7 +299,8 @@ extern void __put_user_8(void);
22042 " .long 2b,4b\n" \
22043 ".previous" \
22044 : "=r"(err) \
22045- : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
22046+ : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err), \
22047+ "r"(__USER_DS))
22048
22049 #ifdef CONFIG_X86_WP_WORKS_OK
22050
22051@@ -332,8 +339,11 @@ struct __large_struct { unsigned long bu
22052 */
22053 #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret) \
22054 __asm__ __volatile__( \
22055- "1: mov"itype" %"rtype"1,%2\n" \
22056+ " movw %w5,%%ds\n" \
22057+ "1: mov"itype" %"rtype"1,%%ds:%2\n" \
22058 "2:\n" \
22059+ " pushl %%ss\n" \
22060+ " popl %%ds\n" \
22061 ".section .fixup,\"ax\"\n" \
22062 "3: movl %3,%0\n" \
22063 " jmp 2b\n" \
22064@@ -343,7 +353,8 @@ struct __large_struct { unsigned long bu
22065 " .long 1b,3b\n" \
22066 ".previous" \
22067 : "=r"(err) \
22068- : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
22069+ : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err), \
22070+ "r"(__USER_DS))
22071
22072
22073 #define __get_user_nocheck(x,ptr,size) \
22074@@ -371,8 +382,11 @@ do { \
22075
22076 #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret) \
22077 __asm__ __volatile__( \
22078- "1: mov"itype" %2,%"rtype"1\n" \
22079+ " movw %w5,%%ds\n" \
22080+ "1: mov"itype" %%ds:%2,%"rtype"1\n" \
22081 "2:\n" \
22082+ " pushl %%ss\n" \
22083+ " popl %%ds\n" \
22084 ".section .fixup,\"ax\"\n" \
22085 "3: movl %3,%0\n" \
22086 " xor"itype" %"rtype"1,%"rtype"1\n" \
22087@@ -383,7 +397,7 @@ do { \
22088 " .long 1b,3b\n" \
22089 ".previous" \
22090 : "=r"(err), ltype (x) \
22091- : "m"(__m(addr)), "i"(errret), "0"(err))
22092+ : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
22093
22094
22095 unsigned long __must_check __copy_to_user_ll(void __user *to,
22096diff -urNp linux-2.6.19.1/include/asm-i386/unwind.h linux-2.6.19.1/include/asm-i386/unwind.h
22097--- linux-2.6.19.1/include/asm-i386/unwind.h 2006-11-29 16:57:37.000000000 -0500
22098+++ linux-2.6.19.1/include/asm-i386/unwind.h 2006-12-03 15:16:20.000000000 -0500
22099@@ -52,7 +52,7 @@ struct unwind_frame_info
22100 static inline void arch_unw_init_frame_info(struct unwind_frame_info *info,
22101 /*const*/ struct pt_regs *regs)
22102 {
22103- if (user_mode_vm(regs))
22104+ if (user_mode(regs))
22105 info->regs = *regs;
22106 else {
22107 memcpy(&info->regs, regs, offsetof(struct pt_regs, esp));
22108@@ -69,8 +69,8 @@ static inline void arch_unw_init_blocked
22109 __get_user(info->regs.ebp, (long *)info->task->thread.esp);
22110 info->regs.esp = info->task->thread.esp;
22111 info->regs.xss = __KERNEL_DS;
22112- info->regs.xds = __USER_DS;
22113- info->regs.xes = __USER_DS;
22114+ info->regs.xds = __KERNEL_DS;
22115+ info->regs.xes = __KERNEL_DS;
22116 }
22117
22118 extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *,
22119@@ -82,9 +82,9 @@ static inline int arch_unw_user_mode(con
22120 {
22121 #if 0 /* This can only work when selector register and EFLAGS saves/restores
22122 are properly annotated (and tracked in UNW_REGISTER_INFO). */
22123- return user_mode_vm(&info->regs);
22124+ return user_mode(&info->regs);
22125 #else
22126- return info->regs.eip < PAGE_OFFSET
22127+ return (info->regs.eip < PAGE_OFFSET && (info->regs.xcs & 0xFFFF) != __KERNEL_CS)
22128 || (info->regs.eip >= __fix_to_virt(FIX_VDSO)
22129 && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE)
22130 || info->regs.esp < PAGE_OFFSET;
22131diff -urNp linux-2.6.19.1/include/asm-ia64/elf.h linux-2.6.19.1/include/asm-ia64/elf.h
22132--- linux-2.6.19.1/include/asm-ia64/elf.h 2006-11-29 16:57:37.000000000 -0500
22133+++ linux-2.6.19.1/include/asm-ia64/elf.h 2006-12-03 15:16:20.000000000 -0500
22134@@ -162,6 +162,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
22135 typedef struct ia64_fpreg elf_fpreg_t;
22136 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
22137
22138+#ifdef CONFIG_PAX_ASLR
22139+#define PAX_ELF_ET_DYN_BASE(tsk) ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
22140+
22141+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22142+#define PAX_DELTA_MMAP_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
22143+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22144+#define PAX_DELTA_EXEC_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
22145+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22146+#define PAX_DELTA_STACK_LEN(tsk) ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
22147+#endif
22148
22149
22150 struct pt_regs; /* forward declaration... */
22151diff -urNp linux-2.6.19.1/include/asm-ia64/kmap_types.h linux-2.6.19.1/include/asm-ia64/kmap_types.h
22152--- linux-2.6.19.1/include/asm-ia64/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22153+++ linux-2.6.19.1/include/asm-ia64/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
22154@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
22155 D(10) KM_IRQ1,
22156 D(11) KM_SOFTIRQ0,
22157 D(12) KM_SOFTIRQ1,
22158-D(13) KM_TYPE_NR
22159+D(13) KM_CLEARPAGE,
22160+D(14) KM_TYPE_NR
22161 };
22162
22163 #undef D
22164diff -urNp linux-2.6.19.1/include/asm-ia64/page.h linux-2.6.19.1/include/asm-ia64/page.h
22165--- linux-2.6.19.1/include/asm-ia64/page.h 2006-11-29 16:57:37.000000000 -0500
22166+++ linux-2.6.19.1/include/asm-ia64/page.h 2006-12-03 15:16:20.000000000 -0500
22167@@ -227,5 +227,14 @@ get_order (unsigned long size)
22168 (((current->personality & READ_IMPLIES_EXEC) != 0) \
22169 ? VM_EXEC : 0))
22170
22171+#ifdef CONFIG_PAX_PAGEEXEC
22172+#ifdef CONFIG_PAX_MPROTECT
22173+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22174+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22175+#else
22176+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22177+#endif
22178+#endif
22179+
22180 # endif /* __KERNEL__ */
22181 #endif /* _ASM_IA64_PAGE_H */
22182diff -urNp linux-2.6.19.1/include/asm-ia64/pgtable.h linux-2.6.19.1/include/asm-ia64/pgtable.h
22183--- linux-2.6.19.1/include/asm-ia64/pgtable.h 2006-11-29 16:57:37.000000000 -0500
22184+++ linux-2.6.19.1/include/asm-ia64/pgtable.h 2006-12-03 15:16:20.000000000 -0500
22185@@ -143,6 +143,17 @@
22186 #define PAGE_READONLY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22187 #define PAGE_COPY __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22188 #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
22189+
22190+#ifdef CONFIG_PAX_PAGEEXEC
22191+# define PAGE_SHARED_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
22192+# define PAGE_READONLY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22193+# define PAGE_COPY_NOEXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
22194+#else
22195+# define PAGE_SHARED_NOEXEC PAGE_SHARED
22196+# define PAGE_READONLY_NOEXEC PAGE_READONLY
22197+# define PAGE_COPY_NOEXEC PAGE_COPY
22198+#endif
22199+
22200 #define PAGE_GATE __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
22201 #define PAGE_KERNEL __pgprot(__DIRTY_BITS | _PAGE_PL_0 | _PAGE_AR_RWX)
22202 #define PAGE_KERNELRX __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
22203diff -urNp linux-2.6.19.1/include/asm-ia64/processor.h linux-2.6.19.1/include/asm-ia64/processor.h
22204--- linux-2.6.19.1/include/asm-ia64/processor.h 2006-11-29 16:57:37.000000000 -0500
22205+++ linux-2.6.19.1/include/asm-ia64/processor.h 2006-12-03 15:16:20.000000000 -0500
22206@@ -274,7 +274,7 @@ struct thread_struct {
22207 .on_ustack = 0, \
22208 .ksp = 0, \
22209 .map_base = DEFAULT_MAP_BASE, \
22210- .rbs_bot = STACK_TOP - DEFAULT_USER_STACK_SIZE, \
22211+ .rbs_bot = __STACK_TOP - DEFAULT_USER_STACK_SIZE, \
22212 .task_size = DEFAULT_TASK_SIZE, \
22213 .last_fph_cpu = -1, \
22214 INIT_THREAD_IA32 \
22215diff -urNp linux-2.6.19.1/include/asm-ia64/ustack.h linux-2.6.19.1/include/asm-ia64/ustack.h
22216--- linux-2.6.19.1/include/asm-ia64/ustack.h 2006-11-29 16:57:37.000000000 -0500
22217+++ linux-2.6.19.1/include/asm-ia64/ustack.h 2006-12-03 15:16:20.000000000 -0500
22218@@ -10,10 +10,10 @@
22219
22220 /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
22221 #define MAX_USER_STACK_SIZE (RGN_MAP_LIMIT/2)
22222-#define STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
22223+#define __STACK_TOP (0x6000000000000000UL + RGN_MAP_LIMIT)
22224 #endif
22225
22226-/* Make a default stack size of 2GiB */
22227+/* Make a default stack size of 2GB */
22228 #define DEFAULT_USER_STACK_SIZE (1UL << 31)
22229
22230 #endif /* _ASM_IA64_USTACK_H */
22231diff -urNp linux-2.6.19.1/include/asm-m32r/kmap_types.h linux-2.6.19.1/include/asm-m32r/kmap_types.h
22232--- linux-2.6.19.1/include/asm-m32r/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22233+++ linux-2.6.19.1/include/asm-m32r/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
22234@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
22235 D(10) KM_IRQ1,
22236 D(11) KM_SOFTIRQ0,
22237 D(12) KM_SOFTIRQ1,
22238-D(13) KM_TYPE_NR
22239+D(13) KM_CLEARPAGE,
22240+D(14) KM_TYPE_NR
22241 };
22242
22243 #undef D
22244diff -urNp linux-2.6.19.1/include/asm-m68k/kmap_types.h linux-2.6.19.1/include/asm-m68k/kmap_types.h
22245--- linux-2.6.19.1/include/asm-m68k/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22246+++ linux-2.6.19.1/include/asm-m68k/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
22247@@ -15,6 +15,7 @@ enum km_type {
22248 KM_IRQ1,
22249 KM_SOFTIRQ0,
22250 KM_SOFTIRQ1,
22251+ KM_CLEARPAGE,
22252 KM_TYPE_NR
22253 };
22254
22255diff -urNp linux-2.6.19.1/include/asm-m68knommu/kmap_types.h linux-2.6.19.1/include/asm-m68knommu/kmap_types.h
22256--- linux-2.6.19.1/include/asm-m68knommu/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22257+++ linux-2.6.19.1/include/asm-m68knommu/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
22258@@ -15,6 +15,7 @@ enum km_type {
22259 KM_IRQ1,
22260 KM_SOFTIRQ0,
22261 KM_SOFTIRQ1,
22262+ KM_CLEARPAGE,
22263 KM_TYPE_NR
22264 };
22265
22266diff -urNp linux-2.6.19.1/include/asm-mips/a.out.h linux-2.6.19.1/include/asm-mips/a.out.h
22267--- linux-2.6.19.1/include/asm-mips/a.out.h 2006-11-29 16:57:37.000000000 -0500
22268+++ linux-2.6.19.1/include/asm-mips/a.out.h 2006-12-03 15:16:20.000000000 -0500
22269@@ -35,10 +35,10 @@ struct exec
22270 #ifdef __KERNEL__
22271
22272 #ifdef CONFIG_32BIT
22273-#define STACK_TOP TASK_SIZE
22274+#define __STACK_TOP TASK_SIZE
22275 #endif
22276 #ifdef CONFIG_64BIT
22277-#define STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
22278+#define __STACK_TOP (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
22279 #endif
22280
22281 #endif
22282diff -urNp linux-2.6.19.1/include/asm-mips/elf.h linux-2.6.19.1/include/asm-mips/elf.h
22283--- linux-2.6.19.1/include/asm-mips/elf.h 2006-11-29 16:57:37.000000000 -0500
22284+++ linux-2.6.19.1/include/asm-mips/elf.h 2006-12-03 15:16:20.000000000 -0500
22285@@ -371,4 +371,15 @@ extern int dump_task_fpu(struct task_str
22286 #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
22287 #endif
22288
22289+#ifdef CONFIG_PAX_ASLR
22290+#define PAX_ELF_ET_DYN_BASE(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
22291+
22292+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22293+#define PAX_DELTA_MMAP_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
22294+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22295+#define PAX_DELTA_EXEC_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
22296+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22297+#define PAX_DELTA_STACK_LEN(tsk) (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
22298+#endif
22299+
22300 #endif /* _ASM_ELF_H */
22301diff -urNp linux-2.6.19.1/include/asm-mips/kmap_types.h linux-2.6.19.1/include/asm-mips/kmap_types.h
22302--- linux-2.6.19.1/include/asm-mips/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22303+++ linux-2.6.19.1/include/asm-mips/kmap_types.h 2006-12-03 15:16:20.000000000 -0500
22304@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
22305 D(10) KM_IRQ1,
22306 D(11) KM_SOFTIRQ0,
22307 D(12) KM_SOFTIRQ1,
22308-D(13) KM_TYPE_NR
22309+D(13) KM_CLEARPAGE,
22310+D(14) KM_TYPE_NR
22311 };
22312
22313 #undef D
22314diff -urNp linux-2.6.19.1/include/asm-mips/page.h linux-2.6.19.1/include/asm-mips/page.h
22315--- linux-2.6.19.1/include/asm-mips/page.h 2006-11-29 16:57:37.000000000 -0500
22316+++ linux-2.6.19.1/include/asm-mips/page.h 2006-12-03 15:16:20.000000000 -0500
22317@@ -77,7 +77,7 @@ static inline void copy_user_page(void *
22318 #ifdef CONFIG_CPU_MIPS32
22319 typedef struct { unsigned long pte_low, pte_high; } pte_t;
22320 #define pte_val(x) ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
22321- #define __pte(x) ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
22322+ #define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
22323 #else
22324 typedef struct { unsigned long long pte; } pte_t;
22325 #define pte_val(x) ((x).pte)
22326@@ -166,6 +166,15 @@ typedef struct { unsigned long pgprot; }
22327 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
22328 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22329
22330+#ifdef CONFIG_PAX_PAGEEXEC
22331+#ifdef CONFIG_PAX_MPROTECT
22332+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22333+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22334+#else
22335+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22336+#endif
22337+#endif
22338+
22339 #define UNCAC_ADDR(addr) ((addr) - PAGE_OFFSET + UNCAC_BASE)
22340 #define CAC_ADDR(addr) ((addr) - UNCAC_BASE + PAGE_OFFSET)
22341
22342diff -urNp linux-2.6.19.1/include/asm-parisc/a.out.h linux-2.6.19.1/include/asm-parisc/a.out.h
22343--- linux-2.6.19.1/include/asm-parisc/a.out.h 2006-11-29 16:57:37.000000000 -0500
22344+++ linux-2.6.19.1/include/asm-parisc/a.out.h 2006-12-03 15:16:21.000000000 -0500
22345@@ -22,7 +22,7 @@ struct exec
22346 /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
22347 * prumpf */
22348
22349-#define STACK_TOP TASK_SIZE
22350+#define __STACK_TOP TASK_SIZE
22351
22352 #endif
22353
22354diff -urNp linux-2.6.19.1/include/asm-parisc/elf.h linux-2.6.19.1/include/asm-parisc/elf.h
22355--- linux-2.6.19.1/include/asm-parisc/elf.h 2006-11-29 16:57:37.000000000 -0500
22356+++ linux-2.6.19.1/include/asm-parisc/elf.h 2006-12-03 15:16:21.000000000 -0500
22357@@ -337,6 +337,17 @@ struct pt_regs; /* forward declaration..
22358
22359 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE + 0x01000000)
22360
22361+#ifdef CONFIG_PAX_ASLR
22362+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
22363+
22364+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22365+#define PAX_DELTA_MMAP_LEN(tsk) 16
22366+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22367+#define PAX_DELTA_EXEC_LEN(tsk) 16
22368+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22369+#define PAX_DELTA_STACK_LEN(tsk) 16
22370+#endif
22371+
22372 /* This yields a mask that user programs can use to figure out what
22373 instruction set this CPU supports. This could be done in user space,
22374 but it's not easy, and we've already done it here. */
22375diff -urNp linux-2.6.19.1/include/asm-parisc/kmap_types.h linux-2.6.19.1/include/asm-parisc/kmap_types.h
22376--- linux-2.6.19.1/include/asm-parisc/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22377+++ linux-2.6.19.1/include/asm-parisc/kmap_types.h 2006-12-03 15:16:21.000000000 -0500
22378@@ -22,7 +22,8 @@ D(9) KM_IRQ0,
22379 D(10) KM_IRQ1,
22380 D(11) KM_SOFTIRQ0,
22381 D(12) KM_SOFTIRQ1,
22382-D(13) KM_TYPE_NR
22383+D(13) KM_CLEARPAGE,
22384+D(14) KM_TYPE_NR
22385 };
22386
22387 #undef D
22388diff -urNp linux-2.6.19.1/include/asm-parisc/page.h linux-2.6.19.1/include/asm-parisc/page.h
22389--- linux-2.6.19.1/include/asm-parisc/page.h 2006-11-29 16:57:37.000000000 -0500
22390+++ linux-2.6.19.1/include/asm-parisc/page.h 2006-12-03 15:16:21.000000000 -0500
22391@@ -166,6 +166,15 @@ extern int npmem_ranges;
22392 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
22393 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22394
22395+#ifdef CONFIG_PAX_PAGEEXEC
22396+#ifdef CONFIG_PAX_MPROTECT
22397+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22398+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22399+#else
22400+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22401+#endif
22402+#endif
22403+
22404 #include <asm-generic/memory_model.h>
22405 #include <asm-generic/page.h>
22406
22407diff -urNp linux-2.6.19.1/include/asm-parisc/pgtable.h linux-2.6.19.1/include/asm-parisc/pgtable.h
22408--- linux-2.6.19.1/include/asm-parisc/pgtable.h 2006-11-29 16:57:37.000000000 -0500
22409+++ linux-2.6.19.1/include/asm-parisc/pgtable.h 2006-12-03 15:16:21.000000000 -0500
22410@@ -219,6 +219,17 @@ extern void *vmalloc_start;
22411 #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
22412 #define PAGE_COPY PAGE_EXECREAD
22413 #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
22414+
22415+#ifdef CONFIG_PAX_PAGEEXEC
22416+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
22417+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
22418+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
22419+#else
22420+# define PAGE_SHARED_NOEXEC PAGE_SHARED
22421+# define PAGE_COPY_NOEXEC PAGE_COPY
22422+# define PAGE_READONLY_NOEXEC PAGE_READONLY
22423+#endif
22424+
22425 #define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
22426 #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
22427 #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
22428diff -urNp linux-2.6.19.1/include/asm-powerpc/a.out.h linux-2.6.19.1/include/asm-powerpc/a.out.h
22429--- linux-2.6.19.1/include/asm-powerpc/a.out.h 2006-11-29 16:57:37.000000000 -0500
22430+++ linux-2.6.19.1/include/asm-powerpc/a.out.h 2006-12-03 15:16:21.000000000 -0500
22431@@ -23,12 +23,12 @@ struct exec
22432 #define STACK_TOP_USER64 TASK_SIZE_USER64
22433 #define STACK_TOP_USER32 TASK_SIZE_USER32
22434
22435-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22436+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22437 STACK_TOP_USER32 : STACK_TOP_USER64)
22438
22439 #else /* __powerpc64__ */
22440
22441-#define STACK_TOP TASK_SIZE
22442+#define __STACK_TOP TASK_SIZE
22443
22444 #endif /* __powerpc64__ */
22445 #endif /* __KERNEL__ */
22446diff -urNp linux-2.6.19.1/include/asm-powerpc/elf.h linux-2.6.19.1/include/asm-powerpc/elf.h
22447--- linux-2.6.19.1/include/asm-powerpc/elf.h 2006-11-29 16:57:37.000000000 -0500
22448+++ linux-2.6.19.1/include/asm-powerpc/elf.h 2006-12-03 15:16:21.000000000 -0500
22449@@ -161,6 +161,26 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
22450 typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
22451 #endif
22452
22453+#ifdef CONFIG_PAX_ASLR
22454+#define PAX_ELF_ET_DYN_BASE(tsk) (0x10000000UL)
22455+
22456+#ifdef __powerpc64__
22457+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22458+#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
22459+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22460+#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
22461+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22462+#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 16 : 28)
22463+#else
22464+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22465+#define PAX_DELTA_MMAP_LEN(tsk) 15
22466+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22467+#define PAX_DELTA_EXEC_LEN(tsk) 15
22468+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22469+#define PAX_DELTA_STACK_LEN(tsk) 15
22470+#endif
22471+#endif
22472+
22473 #ifdef __KERNEL__
22474 /*
22475 * This is used to ensure we don't load something for the wrong architecture.
22476diff -urNp linux-2.6.19.1/include/asm-powerpc/kmap_types.h linux-2.6.19.1/include/asm-powerpc/kmap_types.h
22477--- linux-2.6.19.1/include/asm-powerpc/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22478+++ linux-2.6.19.1/include/asm-powerpc/kmap_types.h 2006-12-03 15:16:21.000000000 -0500
22479@@ -26,6 +26,7 @@ enum km_type {
22480 KM_SOFTIRQ1,
22481 KM_PPC_SYNC_PAGE,
22482 KM_PPC_SYNC_ICACHE,
22483+ KM_CLEARPAGE,
22484 KM_TYPE_NR
22485 };
22486
22487diff -urNp linux-2.6.19.1/include/asm-powerpc/page_64.h linux-2.6.19.1/include/asm-powerpc/page_64.h
22488--- linux-2.6.19.1/include/asm-powerpc/page_64.h 2006-11-29 16:57:37.000000000 -0500
22489+++ linux-2.6.19.1/include/asm-powerpc/page_64.h 2006-12-03 15:16:21.000000000 -0500
22490@@ -160,15 +160,18 @@ extern unsigned int HPAGE_SHIFT;
22491 * stack by default, so in the absense of a PT_GNU_STACK program header
22492 * we turn execute permission off.
22493 */
22494-#define VM_STACK_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
22495- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22496+#define VM_STACK_DEFAULT_FLAGS32 \
22497+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22498+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22499
22500 #define VM_STACK_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
22501 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22502
22503+#ifndef CONFIG_PAX_PAGEEXEC
22504 #define VM_STACK_DEFAULT_FLAGS \
22505 (test_thread_flag(TIF_32BIT) ? \
22506 VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
22507+#endif
22508
22509 #include <asm-generic/page.h>
22510
22511diff -urNp linux-2.6.19.1/include/asm-powerpc/page.h linux-2.6.19.1/include/asm-powerpc/page.h
22512--- linux-2.6.19.1/include/asm-powerpc/page.h 2006-11-29 16:57:37.000000000 -0500
22513+++ linux-2.6.19.1/include/asm-powerpc/page.h 2006-12-03 15:16:21.000000000 -0500
22514@@ -71,8 +71,9 @@
22515 * and needs to be executable. This means the whole heap ends
22516 * up being executable.
22517 */
22518-#define VM_DATA_DEFAULT_FLAGS32 (VM_READ | VM_WRITE | VM_EXEC | \
22519- VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22520+#define VM_DATA_DEFAULT_FLAGS32 \
22521+ (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22522+ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22523
22524 #define VM_DATA_DEFAULT_FLAGS64 (VM_READ | VM_WRITE | \
22525 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22526@@ -83,6 +84,15 @@
22527 #include <asm/page_32.h>
22528 #endif
22529
22530+#ifdef CONFIG_PAX_PAGEEXEC
22531+#ifdef CONFIG_PAX_MPROTECT
22532+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22533+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22534+#else
22535+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22536+#endif
22537+#endif
22538+
22539 /* align addr on a size boundary - adjust address up/down if needed */
22540 #define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1)))
22541 #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
22542diff -urNp linux-2.6.19.1/include/asm-ppc/mmu_context.h linux-2.6.19.1/include/asm-ppc/mmu_context.h
22543--- linux-2.6.19.1/include/asm-ppc/mmu_context.h 2006-11-29 16:57:37.000000000 -0500
22544+++ linux-2.6.19.1/include/asm-ppc/mmu_context.h 2006-12-03 15:16:21.000000000 -0500
22545@@ -144,7 +144,8 @@ static inline void get_mmu_context(struc
22546 static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
22547 {
22548 mm->context.id = NO_CONTEXT;
22549- mm->context.vdso_base = 0;
22550+ if (t == current)
22551+ mm->context.vdso_base = ~0UL;
22552 return 0;
22553 }
22554
22555diff -urNp linux-2.6.19.1/include/asm-ppc/page.h linux-2.6.19.1/include/asm-ppc/page.h
22556--- linux-2.6.19.1/include/asm-ppc/page.h 2006-11-29 16:57:37.000000000 -0500
22557+++ linux-2.6.19.1/include/asm-ppc/page.h 2006-12-03 15:16:21.000000000 -0500
22558@@ -173,6 +173,15 @@ extern __inline__ int get_order(unsigned
22559 /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
22560 #define __HAVE_ARCH_GATE_AREA 1
22561
22562+#ifdef CONFIG_PAX_PAGEEXEC
22563+#ifdef CONFIG_PAX_MPROTECT
22564+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22565+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22566+#else
22567+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22568+#endif
22569+#endif
22570+
22571 #include <asm-generic/memory_model.h>
22572 #endif /* __KERNEL__ */
22573 #endif /* _PPC_PAGE_H */
22574diff -urNp linux-2.6.19.1/include/asm-ppc/pgtable.h linux-2.6.19.1/include/asm-ppc/pgtable.h
22575--- linux-2.6.19.1/include/asm-ppc/pgtable.h 2006-11-29 16:57:37.000000000 -0500
22576+++ linux-2.6.19.1/include/asm-ppc/pgtable.h 2006-12-03 15:16:21.000000000 -0500
22577@@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
22578
22579 #define PAGE_NONE __pgprot(_PAGE_BASE)
22580 #define PAGE_READONLY __pgprot(_PAGE_BASE | _PAGE_USER)
22581-#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
22582+#define PAGE_READONLY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
22583 #define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
22584-#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
22585+#define PAGE_SHARED_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
22586 #define PAGE_COPY __pgprot(_PAGE_BASE | _PAGE_USER)
22587-#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
22588+#define PAGE_COPY_X __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
22589+
22590+#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
22591+# define PAGE_SHARED_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
22592+# define PAGE_COPY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
22593+# define PAGE_READONLY_NOEXEC __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
22594+#else
22595+# define PAGE_SHARED_NOEXEC PAGE_SHARED
22596+# define PAGE_COPY_NOEXEC PAGE_COPY
22597+# define PAGE_READONLY_NOEXEC PAGE_READONLY
22598+#endif
22599
22600 #define PAGE_KERNEL __pgprot(_PAGE_RAM)
22601 #define PAGE_KERNEL_NOCACHE __pgprot(_PAGE_IO)
22602@@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
22603 * This is the closest we can get..
22604 */
22605 #define __P000 PAGE_NONE
22606-#define __P001 PAGE_READONLY_X
22607-#define __P010 PAGE_COPY
22608-#define __P011 PAGE_COPY_X
22609-#define __P100 PAGE_READONLY
22610+#define __P001 PAGE_READONLY_NOEXEC
22611+#define __P010 PAGE_COPY_NOEXEC
22612+#define __P011 PAGE_COPY_NOEXEC
22613+#define __P100 PAGE_READONLY_X
22614 #define __P101 PAGE_READONLY_X
22615-#define __P110 PAGE_COPY
22616+#define __P110 PAGE_COPY_X
22617 #define __P111 PAGE_COPY_X
22618
22619 #define __S000 PAGE_NONE
22620-#define __S001 PAGE_READONLY_X
22621-#define __S010 PAGE_SHARED
22622-#define __S011 PAGE_SHARED_X
22623-#define __S100 PAGE_READONLY
22624+#define __S001 PAGE_READONLY_NOEXEC
22625+#define __S010 PAGE_SHARED_NOEXEC
22626+#define __S011 PAGE_SHARED_NOEXEC
22627+#define __S100 PAGE_READONLY_X
22628 #define __S101 PAGE_READONLY_X
22629-#define __S110 PAGE_SHARED
22630+#define __S110 PAGE_SHARED_X
22631 #define __S111 PAGE_SHARED_X
22632
22633 #ifndef __ASSEMBLY__
22634diff -urNp linux-2.6.19.1/include/asm-s390/kmap_types.h linux-2.6.19.1/include/asm-s390/kmap_types.h
22635--- linux-2.6.19.1/include/asm-s390/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22636+++ linux-2.6.19.1/include/asm-s390/kmap_types.h 2006-12-03 15:16:21.000000000 -0500
22637@@ -16,6 +16,7 @@ enum km_type {
22638 KM_IRQ1,
22639 KM_SOFTIRQ0,
22640 KM_SOFTIRQ1,
22641+ KM_CLEARPAGE,
22642 KM_TYPE_NR
22643 };
22644
22645diff -urNp linux-2.6.19.1/include/asm-sh/kmap_types.h linux-2.6.19.1/include/asm-sh/kmap_types.h
22646--- linux-2.6.19.1/include/asm-sh/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22647+++ linux-2.6.19.1/include/asm-sh/kmap_types.h 2006-12-03 15:16:21.000000000 -0500
22648@@ -24,7 +24,8 @@ D(9) KM_IRQ0,
22649 D(10) KM_IRQ1,
22650 D(11) KM_SOFTIRQ0,
22651 D(12) KM_SOFTIRQ1,
22652-D(13) KM_TYPE_NR
22653+D(13) KM_CLEARPAGE,
22654+D(14) KM_TYPE_NR
22655 };
22656
22657 #undef D
22658diff -urNp linux-2.6.19.1/include/asm-sparc/a.out.h linux-2.6.19.1/include/asm-sparc/a.out.h
22659--- linux-2.6.19.1/include/asm-sparc/a.out.h 2006-11-29 16:57:37.000000000 -0500
22660+++ linux-2.6.19.1/include/asm-sparc/a.out.h 2006-12-03 15:16:21.000000000 -0500
22661@@ -91,7 +91,7 @@ struct relocation_info /* used when head
22662
22663 #include <asm/page.h>
22664
22665-#define STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
22666+#define __STACK_TOP (PAGE_OFFSET - PAGE_SIZE)
22667
22668 #endif /* __KERNEL__ */
22669
22670diff -urNp linux-2.6.19.1/include/asm-sparc/elf.h linux-2.6.19.1/include/asm-sparc/elf.h
22671--- linux-2.6.19.1/include/asm-sparc/elf.h 2006-11-29 16:57:37.000000000 -0500
22672+++ linux-2.6.19.1/include/asm-sparc/elf.h 2006-12-03 15:16:21.000000000 -0500
22673@@ -143,6 +143,17 @@ do { unsigned long *dest = &(__elf_regs[
22674
22675 #define ELF_ET_DYN_BASE (TASK_UNMAPPED_BASE)
22676
22677+#ifdef CONFIG_PAX_ASLR
22678+#define PAX_ELF_ET_DYN_BASE(tsk) 0x10000UL
22679+
22680+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22681+#define PAX_DELTA_MMAP_LEN(tsk) 16
22682+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22683+#define PAX_DELTA_EXEC_LEN(tsk) 16
22684+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22685+#define PAX_DELTA_STACK_LEN(tsk) 16
22686+#endif
22687+
22688 /* This yields a mask that user programs can use to figure out what
22689 instruction set this cpu supports. This can NOT be done in userspace
22690 on Sparc. */
22691diff -urNp linux-2.6.19.1/include/asm-sparc/kmap_types.h linux-2.6.19.1/include/asm-sparc/kmap_types.h
22692--- linux-2.6.19.1/include/asm-sparc/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22693+++ linux-2.6.19.1/include/asm-sparc/kmap_types.h 2006-12-03 15:16:21.000000000 -0500
22694@@ -15,6 +15,7 @@ enum km_type {
22695 KM_IRQ1,
22696 KM_SOFTIRQ0,
22697 KM_SOFTIRQ1,
22698+ KM_CLEARPAGE,
22699 KM_TYPE_NR
22700 };
22701
22702diff -urNp linux-2.6.19.1/include/asm-sparc/page.h linux-2.6.19.1/include/asm-sparc/page.h
22703--- linux-2.6.19.1/include/asm-sparc/page.h 2006-11-29 16:57:37.000000000 -0500
22704+++ linux-2.6.19.1/include/asm-sparc/page.h 2006-12-03 15:16:21.000000000 -0500
22705@@ -160,6 +160,15 @@ extern unsigned long pfn_base;
22706 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
22707 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22708
22709+#ifdef CONFIG_PAX_PAGEEXEC
22710+#ifdef CONFIG_PAX_MPROTECT
22711+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22712+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22713+#else
22714+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22715+#endif
22716+#endif
22717+
22718 #include <asm-generic/memory_model.h>
22719 #include <asm-generic/page.h>
22720
22721diff -urNp linux-2.6.19.1/include/asm-sparc/pgtable.h linux-2.6.19.1/include/asm-sparc/pgtable.h
22722--- linux-2.6.19.1/include/asm-sparc/pgtable.h 2006-11-29 16:57:37.000000000 -0500
22723+++ linux-2.6.19.1/include/asm-sparc/pgtable.h 2006-12-03 15:16:21.000000000 -0500
22724@@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
22725 BTFIXUPDEF_INT(page_shared)
22726 BTFIXUPDEF_INT(page_copy)
22727 BTFIXUPDEF_INT(page_readonly)
22728+
22729+#ifdef CONFIG_PAX_PAGEEXEC
22730+BTFIXUPDEF_INT(page_shared_noexec)
22731+BTFIXUPDEF_INT(page_copy_noexec)
22732+BTFIXUPDEF_INT(page_readonly_noexec)
22733+#endif
22734+
22735 BTFIXUPDEF_INT(page_kernel)
22736
22737 #define PMD_SHIFT SUN4C_PMD_SHIFT
22738@@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
22739 #define PAGE_COPY __pgprot(BTFIXUP_INT(page_copy))
22740 #define PAGE_READONLY __pgprot(BTFIXUP_INT(page_readonly))
22741
22742+#ifdef CONFIG_PAX_PAGEEXEC
22743+# define PAGE_SHARED_NOEXEC __pgprot(BTFIXUP_INT(page_shared_noexec))
22744+# define PAGE_COPY_NOEXEC __pgprot(BTFIXUP_INT(page_copy_noexec))
22745+# define PAGE_READONLY_NOEXEC __pgprot(BTFIXUP_INT(page_readonly_noexec))
22746+#else
22747+# define PAGE_SHARED_NOEXEC PAGE_SHARED
22748+# define PAGE_COPY_NOEXEC PAGE_COPY
22749+# define PAGE_READONLY_NOEXEC PAGE_READONLY
22750+#endif
22751+
22752 extern unsigned long page_kernel;
22753
22754 #ifdef MODULE
22755diff -urNp linux-2.6.19.1/include/asm-sparc/pgtsrmmu.h linux-2.6.19.1/include/asm-sparc/pgtsrmmu.h
22756--- linux-2.6.19.1/include/asm-sparc/pgtsrmmu.h 2006-11-29 16:57:37.000000000 -0500
22757+++ linux-2.6.19.1/include/asm-sparc/pgtsrmmu.h 2006-12-03 15:16:21.000000000 -0500
22758@@ -115,6 +115,16 @@
22759 SRMMU_EXEC | SRMMU_REF)
22760 #define SRMMU_PAGE_RDONLY __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22761 SRMMU_EXEC | SRMMU_REF)
22762+
22763+#ifdef CONFIG_PAX_PAGEEXEC
22764+#define SRMMU_PAGE_SHARED_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22765+ SRMMU_WRITE | SRMMU_REF)
22766+#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22767+ SRMMU_REF)
22768+#define SRMMU_PAGE_RDONLY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | \
22769+ SRMMU_REF)
22770+#endif
22771+
22772 #define SRMMU_PAGE_KERNEL __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
22773 SRMMU_DIRTY | SRMMU_REF)
22774
22775diff -urNp linux-2.6.19.1/include/asm-sparc/uaccess.h linux-2.6.19.1/include/asm-sparc/uaccess.h
22776--- linux-2.6.19.1/include/asm-sparc/uaccess.h 2006-11-29 16:57:37.000000000 -0500
22777+++ linux-2.6.19.1/include/asm-sparc/uaccess.h 2006-12-03 15:16:21.000000000 -0500
22778@@ -41,7 +41,7 @@
22779 * No one can read/write anything from userland in the kernel space by setting
22780 * large size and address near to PAGE_OFFSET - a fault will break his intentions.
22781 */
22782-#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
22783+#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
22784 #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
22785 #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
22786 #define access_ok(type, addr, size) \
22787diff -urNp linux-2.6.19.1/include/asm-sparc64/a.out.h linux-2.6.19.1/include/asm-sparc64/a.out.h
22788--- linux-2.6.19.1/include/asm-sparc64/a.out.h 2006-11-29 16:57:37.000000000 -0500
22789+++ linux-2.6.19.1/include/asm-sparc64/a.out.h 2006-12-03 15:16:21.000000000 -0500
22790@@ -98,7 +98,7 @@ struct relocation_info /* used when head
22791 #define STACK_TOP32 ((1UL << 32UL) - PAGE_SIZE)
22792 #define STACK_TOP64 (0x0000080000000000UL - (1UL << 32UL))
22793
22794-#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22795+#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
22796 STACK_TOP32 : STACK_TOP64)
22797
22798 #endif
22799diff -urNp linux-2.6.19.1/include/asm-sparc64/elf.h linux-2.6.19.1/include/asm-sparc64/elf.h
22800--- linux-2.6.19.1/include/asm-sparc64/elf.h 2006-11-29 16:57:37.000000000 -0500
22801+++ linux-2.6.19.1/include/asm-sparc64/elf.h 2006-12-03 15:16:21.000000000 -0500
22802@@ -142,6 +142,16 @@ typedef struct {
22803 #define ELF_ET_DYN_BASE 0x0000010000000000UL
22804 #endif
22805
22806+#ifdef CONFIG_PAX_ASLR
22807+#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
22808+
22809+#define PAX_DELTA_MMAP_LSB(tsk) (PAGE_SHIFT + 1)
22810+#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
22811+#define PAX_DELTA_EXEC_LSB(tsk) (PAGE_SHIFT + 1)
22812+#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 14 : 28 )
22813+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22814+#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_32BIT) ? 15 : 29 )
22815+#endif
22816
22817 /* This yields a mask that user programs can use to figure out what
22818 instruction set this cpu supports. */
22819diff -urNp linux-2.6.19.1/include/asm-sparc64/kmap_types.h linux-2.6.19.1/include/asm-sparc64/kmap_types.h
22820--- linux-2.6.19.1/include/asm-sparc64/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22821+++ linux-2.6.19.1/include/asm-sparc64/kmap_types.h 2006-12-03 15:16:21.000000000 -0500
22822@@ -19,6 +19,7 @@ enum km_type {
22823 KM_IRQ1,
22824 KM_SOFTIRQ0,
22825 KM_SOFTIRQ1,
22826+ KM_CLEARPAGE,
22827 KM_TYPE_NR
22828 };
22829
22830diff -urNp linux-2.6.19.1/include/asm-sparc64/page.h linux-2.6.19.1/include/asm-sparc64/page.h
22831--- linux-2.6.19.1/include/asm-sparc64/page.h 2006-11-29 16:57:37.000000000 -0500
22832+++ linux-2.6.19.1/include/asm-sparc64/page.h 2006-12-03 15:16:21.000000000 -0500
22833@@ -141,6 +141,15 @@ typedef unsigned long pgprot_t;
22834 #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
22835 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22836
22837+#ifdef CONFIG_PAX_PAGEEXEC
22838+#ifdef CONFIG_PAX_MPROTECT
22839+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22840+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22841+#else
22842+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22843+#endif
22844+#endif
22845+
22846 #include <asm-generic/page.h>
22847
22848 #endif /* __KERNEL__ */
22849diff -urNp linux-2.6.19.1/include/asm-v850/kmap_types.h linux-2.6.19.1/include/asm-v850/kmap_types.h
22850--- linux-2.6.19.1/include/asm-v850/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22851+++ linux-2.6.19.1/include/asm-v850/kmap_types.h 2006-12-03 15:16:22.000000000 -0500
22852@@ -13,6 +13,7 @@ enum km_type {
22853 KM_PTE1,
22854 KM_IRQ0,
22855 KM_IRQ1,
22856+ KM_CLEARPAGE,
22857 KM_TYPE_NR
22858 };
22859
22860diff -urNp linux-2.6.19.1/include/asm-x86_64/a.out.h linux-2.6.19.1/include/asm-x86_64/a.out.h
22861--- linux-2.6.19.1/include/asm-x86_64/a.out.h 2006-11-29 16:57:37.000000000 -0500
22862+++ linux-2.6.19.1/include/asm-x86_64/a.out.h 2006-12-03 15:16:22.000000000 -0500
22863@@ -21,7 +21,7 @@ struct exec
22864
22865 #ifdef __KERNEL__
22866 #include <linux/thread_info.h>
22867-#define STACK_TOP TASK_SIZE
22868+#define __STACK_TOP TASK_SIZE
22869 #endif
22870
22871 #endif /* __A_OUT_GNU_H__ */
22872diff -urNp linux-2.6.19.1/include/asm-x86_64/elf.h linux-2.6.19.1/include/asm-x86_64/elf.h
22873--- linux-2.6.19.1/include/asm-x86_64/elf.h 2006-11-29 16:57:37.000000000 -0500
22874+++ linux-2.6.19.1/include/asm-x86_64/elf.h 2006-12-03 15:16:22.000000000 -0500
22875@@ -93,6 +93,17 @@ typedef struct user_i387_struct elf_fpre
22876
22877 #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
22878
22879+#ifdef CONFIG_PAX_ASLR
22880+#define PAX_ELF_ET_DYN_BASE(tsk) (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
22881+
22882+#define PAX_DELTA_MMAP_LSB(tsk) PAGE_SHIFT
22883+#define PAX_DELTA_MMAP_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
22884+#define PAX_DELTA_EXEC_LSB(tsk) PAGE_SHIFT
22885+#define PAX_DELTA_EXEC_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
22886+#define PAX_DELTA_STACK_LSB(tsk) PAGE_SHIFT
22887+#define PAX_DELTA_STACK_LEN(tsk) (test_thread_flag(TIF_IA32) ? 16 : 32)
22888+#endif
22889+
22890 /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
22891 now struct_user_regs, they are different). Assumes current is the process
22892 getting dumped. */
22893diff -urNp linux-2.6.19.1/include/asm-x86_64/ia32.h linux-2.6.19.1/include/asm-x86_64/ia32.h
22894--- linux-2.6.19.1/include/asm-x86_64/ia32.h 2006-11-29 16:57:37.000000000 -0500
22895+++ linux-2.6.19.1/include/asm-x86_64/ia32.h 2006-12-03 15:16:22.000000000 -0500
22896@@ -156,7 +156,13 @@ struct ustat32 {
22897 char f_fpack[6];
22898 };
22899
22900-#define IA32_STACK_TOP IA32_PAGE_OFFSET
22901+#ifdef CONFIG_PAX_RANDUSTACK
22902+#define IA32_DELTA_STACK (current->mm->delta_stack)
22903+#else
22904+#define IA32_DELTA_STACK 0UL
22905+#endif
22906+
22907+#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
22908
22909 #ifdef __KERNEL__
22910 struct user_desc;
22911diff -urNp linux-2.6.19.1/include/asm-x86_64/kmap_types.h linux-2.6.19.1/include/asm-x86_64/kmap_types.h
22912--- linux-2.6.19.1/include/asm-x86_64/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
22913+++ linux-2.6.19.1/include/asm-x86_64/kmap_types.h 2006-12-03 15:16:22.000000000 -0500
22914@@ -13,6 +13,7 @@ enum km_type {
22915 KM_IRQ1,
22916 KM_SOFTIRQ0,
22917 KM_SOFTIRQ1,
22918+ KM_CLEARPAGE,
22919 KM_TYPE_NR
22920 };
22921
22922diff -urNp linux-2.6.19.1/include/asm-x86_64/page.h linux-2.6.19.1/include/asm-x86_64/page.h
22923--- linux-2.6.19.1/include/asm-x86_64/page.h 2006-11-29 16:57:37.000000000 -0500
22924+++ linux-2.6.19.1/include/asm-x86_64/page.h 2006-12-03 15:16:22.000000000 -0500
22925@@ -88,6 +88,8 @@ typedef struct { unsigned long pgprot; }
22926 #define __PAGE_OFFSET 0xffff810000000000
22927 #endif /* !__ASSEMBLY__ */
22928
22929+#define __KERNEL_TEXT_OFFSET (0)
22930+
22931 /* to align the pointer to the (next) page boundary */
22932 #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
22933
22934@@ -133,6 +135,15 @@ typedef struct { unsigned long pgprot; }
22935 (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
22936 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
22937
22938+#ifdef CONFIG_PAX_PAGEEXEC
22939+#ifdef CONFIG_PAX_MPROTECT
22940+#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
22941+ ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22942+#else
22943+#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
22944+#endif
22945+#endif
22946+
22947 #define __HAVE_ARCH_GATE_AREA 1
22948
22949 #include <asm-generic/memory_model.h>
22950diff -urNp linux-2.6.19.1/include/asm-x86_64/pgalloc.h linux-2.6.19.1/include/asm-x86_64/pgalloc.h
22951--- linux-2.6.19.1/include/asm-x86_64/pgalloc.h 2006-11-29 16:57:37.000000000 -0500
22952+++ linux-2.6.19.1/include/asm-x86_64/pgalloc.h 2006-12-03 15:16:22.000000000 -0500
22953@@ -7,7 +7,7 @@
22954 #include <linux/mm.h>
22955
22956 #define pmd_populate_kernel(mm, pmd, pte) \
22957- set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
22958+ set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
22959 #define pud_populate(mm, pud, pmd) \
22960 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
22961 #define pgd_populate(mm, pgd, pud) \
22962diff -urNp linux-2.6.19.1/include/asm-x86_64/pgtable.h linux-2.6.19.1/include/asm-x86_64/pgtable.h
22963--- linux-2.6.19.1/include/asm-x86_64/pgtable.h 2006-11-29 16:57:37.000000000 -0500
22964+++ linux-2.6.19.1/include/asm-x86_64/pgtable.h 2006-12-03 15:16:22.000000000 -0500
22965@@ -174,6 +174,10 @@ static inline pte_t ptep_get_and_clear_f
22966 #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
22967 #define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
22968 #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
22969+
22970+#define PAGE_READONLY_NOEXEC PAGE_READONLY
22971+#define PAGE_SHARED_NOEXEC PAGE_SHARED
22972+
22973 #define __PAGE_KERNEL \
22974 (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
22975 #define __PAGE_KERNEL_EXEC \
22976@@ -262,7 +266,15 @@ static inline pte_t pfn_pte(unsigned lon
22977 #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
22978 static inline int pte_user(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
22979 static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; }
22980-static inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_NX); }
22981+
22982+static inline int pte_exec(pte_t pte)
22983+{
22984+ if (__supported_pte_mask & _PAGE_NX)
22985+ return pte_val(pte) & _PAGE_NX;
22986+ else
22987+ return pte_val(pte) & _PAGE_USER;
22988+}
22989+
22990 static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
22991 static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
22992 static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; }
22993@@ -270,12 +282,30 @@ static inline int pte_file(pte_t pte) {
22994 static inline int pte_huge(pte_t pte) { return pte_val(pte) & _PAGE_PSE; }
22995
22996 static inline pte_t pte_rdprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
22997-static inline pte_t pte_exprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
22998+
22999+static inline pte_t pte_exprotect(pte_t pte)
23000+{
23001+ if (__supported_pte_mask & _PAGE_NX)
23002+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
23003+ else
23004+ set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
23005+ return pte;
23006+}
23007+
23008 static inline pte_t pte_mkclean(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
23009 static inline pte_t pte_mkold(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
23010 static inline pte_t pte_wrprotect(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
23011 static inline pte_t pte_mkread(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
23012-static inline pte_t pte_mkexec(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; }
23013+
23014+extern inline pte_t pte_mkexec(pte_t pte)
23015+{
23016+ if (__supported_pte_mask & _PAGE_NX)
23017+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
23018+ else
23019+ set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
23020+ return pte;
23021+}
23022+
23023 static inline pte_t pte_mkdirty(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
23024 static inline pte_t pte_mkyoung(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
23025 static inline pte_t pte_mkwrite(pte_t pte) { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
23026diff -urNp linux-2.6.19.1/include/asm-x86_64/system.h linux-2.6.19.1/include/asm-x86_64/system.h
23027--- linux-2.6.19.1/include/asm-x86_64/system.h 2006-11-29 16:57:37.000000000 -0500
23028+++ linux-2.6.19.1/include/asm-x86_64/system.h 2006-12-03 15:16:22.000000000 -0500
23029@@ -248,7 +248,7 @@ static inline unsigned long __cmpxchg(vo
23030
23031 void cpu_idle_wait(void);
23032
23033-extern unsigned long arch_align_stack(unsigned long sp);
23034+#define arch_align_stack(x) (x)
23035 extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
23036
23037 #endif
23038diff -urNp linux-2.6.19.1/include/asm-xtensa/kmap_types.h linux-2.6.19.1/include/asm-xtensa/kmap_types.h
23039--- linux-2.6.19.1/include/asm-xtensa/kmap_types.h 2006-11-29 16:57:37.000000000 -0500
23040+++ linux-2.6.19.1/include/asm-xtensa/kmap_types.h 2006-12-03 15:16:22.000000000 -0500
23041@@ -25,6 +25,7 @@ enum km_type {
23042 KM_IRQ1,
23043 KM_SOFTIRQ0,
23044 KM_SOFTIRQ1,
23045+ KM_CLEARPAGE,
23046 KM_TYPE_NR
23047 };
23048
23049diff -urNp linux-2.6.19.1/include/linux/a.out.h linux-2.6.19.1/include/linux/a.out.h
23050--- linux-2.6.19.1/include/linux/a.out.h 2006-11-29 16:57:37.000000000 -0500
23051+++ linux-2.6.19.1/include/linux/a.out.h 2006-12-03 15:16:22.000000000 -0500
23052@@ -7,6 +7,16 @@
23053
23054 #include <asm/a.out.h>
23055
23056+#ifdef CONFIG_PAX_RANDUSTACK
23057+#define __DELTA_STACK (current->mm->delta_stack)
23058+#else
23059+#define __DELTA_STACK 0UL
23060+#endif
23061+
23062+#ifndef STACK_TOP
23063+#define STACK_TOP (__STACK_TOP - __DELTA_STACK)
23064+#endif
23065+
23066 #endif /* __STRUCT_EXEC_OVERRIDE__ */
23067
23068 /* these go in the N_MACHTYPE field */
23069@@ -37,6 +47,14 @@ enum machine_type {
23070 M_MIPS2 = 152 /* MIPS R6000/R4000 binary */
23071 };
23072
23073+/* Constants for the N_FLAGS field */
23074+#define F_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
23075+#define F_PAX_EMUTRAMP 2 /* Emulate trampolines */
23076+#define F_PAX_MPROTECT 4 /* Restrict mprotect() */
23077+#define F_PAX_RANDMMAP 8 /* Randomize mmap() base */
23078+/*#define F_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
23079+#define F_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
23080+
23081 #if !defined (N_MAGIC)
23082 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
23083 #endif
23084diff -urNp linux-2.6.19.1/include/linux/binfmts.h linux-2.6.19.1/include/linux/binfmts.h
23085--- linux-2.6.19.1/include/linux/binfmts.h 2006-11-29 16:57:37.000000000 -0500
23086+++ linux-2.6.19.1/include/linux/binfmts.h 2006-12-03 15:16:22.000000000 -0500
23087@@ -7,10 +7,10 @@ struct pt_regs;
23088
23089 /*
23090 * MAX_ARG_PAGES defines the number of pages allocated for arguments
23091- * and envelope for the new program. 32 should suffice, this gives
23092- * a maximum env+arg of 128kB w/4KB pages!
23093+ * and envelope for the new program. 33 should suffice, this gives
23094+ * a maximum env+arg of 132kB w/4KB pages!
23095 */
23096-#define MAX_ARG_PAGES 32
23097+#define MAX_ARG_PAGES 33
23098
23099 /* sizeof(linux_binprm->buf) */
23100 #define BINPRM_BUF_SIZE 128
23101@@ -38,6 +38,7 @@ struct linux_binprm{
23102 unsigned interp_flags;
23103 unsigned interp_data;
23104 unsigned long loader, exec;
23105+ int misc;
23106 };
23107
23108 #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
23109@@ -87,5 +88,8 @@ extern void compute_creds(struct linux_b
23110 extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
23111 extern int set_binfmt(struct linux_binfmt *new);
23112
23113+void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
23114+void pax_report_insns(void *pc, void *sp);
23115+
23116 #endif /* __KERNEL__ */
23117 #endif /* _LINUX_BINFMTS_H */
23118diff -urNp linux-2.6.19.1/include/linux/capability.h linux-2.6.19.1/include/linux/capability.h
23119--- linux-2.6.19.1/include/linux/capability.h 2006-11-29 16:57:37.000000000 -0500
23120+++ linux-2.6.19.1/include/linux/capability.h 2006-12-03 15:16:22.000000000 -0500
23121@@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
23122 #define cap_is_fs_cap(c) (CAP_TO_MASK(c) & CAP_FS_MASK)
23123
23124 int capable(int cap);
23125+int capable_nolog(int cap);
23126 int __capable(struct task_struct *t, int cap);
23127
23128 #endif /* __KERNEL__ */
23129diff -urNp linux-2.6.19.1/include/linux/elf.h linux-2.6.19.1/include/linux/elf.h
23130--- linux-2.6.19.1/include/linux/elf.h 2006-11-29 16:57:37.000000000 -0500
23131+++ linux-2.6.19.1/include/linux/elf.h 2006-12-03 15:16:24.000000000 -0500
23132@@ -6,6 +6,10 @@
23133 #include <linux/elf-em.h>
23134 #include <asm/elf.h>
23135
23136+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23137+#undef elf_read_implies_exec
23138+#endif
23139+
23140 #ifndef elf_read_implies_exec
23141 /* Executables for which elf_read_implies_exec() returns TRUE will
23142 have the READ_IMPLIES_EXEC personality flag set automatically.
23143@@ -47,6 +51,16 @@ typedef __s64 Elf64_Sxword;
23144
23145 #define PT_GNU_STACK (PT_LOOS + 0x474e551)
23146
23147+#define PT_PAX_FLAGS (PT_LOOS + 0x5041580)
23148+
23149+/* Constants for the e_flags field */
23150+#define EF_PAX_PAGEEXEC 1 /* Paging based non-executable pages */
23151+#define EF_PAX_EMUTRAMP 2 /* Emulate trampolines */
23152+#define EF_PAX_MPROTECT 4 /* Restrict mprotect() */
23153+#define EF_PAX_RANDMMAP 8 /* Randomize mmap() base */
23154+/*#define EF_PAX_RANDEXEC 16*/ /* Randomize ET_EXEC base */
23155+#define EF_PAX_SEGMEXEC 32 /* Segmentation based non-executable pages */
23156+
23157 /* These constants define the different elf file types */
23158 #define ET_NONE 0
23159 #define ET_REL 1
23160@@ -81,6 +95,8 @@ typedef __s64 Elf64_Sxword;
23161 #define DT_DEBUG 21
23162 #define DT_TEXTREL 22
23163 #define DT_JMPREL 23
23164+#define DT_FLAGS 30
23165+ #define DF_TEXTREL 0x00000004
23166 #define DT_LOPROC 0x70000000
23167 #define DT_HIPROC 0x7fffffff
23168
23169@@ -210,6 +226,19 @@ typedef struct elf64_hdr {
23170 #define PF_W 0x2
23171 #define PF_X 0x1
23172
23173+#define PF_PAGEEXEC (1U << 4) /* Enable PAGEEXEC */
23174+#define PF_NOPAGEEXEC (1U << 5) /* Disable PAGEEXEC */
23175+#define PF_SEGMEXEC (1U << 6) /* Enable SEGMEXEC */
23176+#define PF_NOSEGMEXEC (1U << 7) /* Disable SEGMEXEC */
23177+#define PF_MPROTECT (1U << 8) /* Enable MPROTECT */
23178+#define PF_NOMPROTECT (1U << 9) /* Disable MPROTECT */
23179+/*#define PF_RANDEXEC (1U << 10)*/ /* Enable RANDEXEC */
23180+/*#define PF_NORANDEXEC (1U << 11)*/ /* Disable RANDEXEC */
23181+#define PF_EMUTRAMP (1U << 12) /* Enable EMUTRAMP */
23182+#define PF_NOEMUTRAMP (1U << 13) /* Disable EMUTRAMP */
23183+#define PF_RANDMMAP (1U << 14) /* Enable RANDMMAP */
23184+#define PF_NORANDMMAP (1U << 15) /* Disable RANDMMAP */
23185+
23186 typedef struct elf32_phdr{
23187 Elf32_Word p_type;
23188 Elf32_Off p_offset;
23189@@ -302,6 +331,8 @@ typedef struct elf64_shdr {
23190 #define EI_OSABI 7
23191 #define EI_PAD 8
23192
23193+#define EI_PAX 14
23194+
23195 #define ELFMAG0 0x7f /* EI_MAG */
23196 #define ELFMAG1 'E'
23197 #define ELFMAG2 'L'
23198@@ -358,6 +389,7 @@ extern Elf32_Dyn _DYNAMIC [];
23199 #define elfhdr elf32_hdr
23200 #define elf_phdr elf32_phdr
23201 #define elf_note elf32_note
23202+#define elf_dyn Elf32_Dyn
23203
23204 #else
23205
23206@@ -365,6 +397,7 @@ extern Elf64_Dyn _DYNAMIC [];
23207 #define elfhdr elf64_hdr
23208 #define elf_phdr elf64_phdr
23209 #define elf_note elf64_note
23210+#define elf_dyn Elf64_Dyn
23211
23212 #endif
23213
23214diff -urNp linux-2.6.19.1/include/linux/ext4_fs_extents.h linux-2.6.19.1/include/linux/ext4_fs_extents.h
23215--- linux-2.6.19.1/include/linux/ext4_fs_extents.h 2006-11-29 16:57:37.000000000 -0500
23216+++ linux-2.6.19.1/include/linux/ext4_fs_extents.h 2006-12-03 15:16:24.000000000 -0500
23217@@ -50,7 +50,7 @@
23218 #ifdef EXT_DEBUG
23219 #define ext_debug(a...) printk(a)
23220 #else
23221-#define ext_debug(a...)
23222+#define ext_debug(a...) do {} while (0)
23223 #endif
23224
23225 /*
23226diff -urNp linux-2.6.19.1/include/linux/gracl.h linux-2.6.19.1/include/linux/gracl.h
23227--- linux-2.6.19.1/include/linux/gracl.h 1969-12-31 19:00:00.000000000 -0500
23228+++ linux-2.6.19.1/include/linux/gracl.h 2006-12-03 15:16:25.000000000 -0500
23229@@ -0,0 +1,316 @@
23230+#ifndef GR_ACL_H
23231+#define GR_ACL_H
23232+
23233+#include <linux/grdefs.h>
23234+#include <linux/resource.h>
23235+#include <linux/dcache.h>
23236+#include <asm/resource.h>
23237+
23238+/* Major status information */
23239+
23240+#define GR_VERSION "grsecurity 2.1.9"
23241+#define GRSECURITY_VERSION 0x219
23242+
23243+enum {
23244+
23245+ SHUTDOWN = 0,
23246+ ENABLE = 1,
23247+ SPROLE = 2,
23248+ RELOAD = 3,
23249+ SEGVMOD = 4,
23250+ STATUS = 5,
23251+ UNSPROLE = 6,
23252+ PASSSET = 7,
23253+ SPROLEPAM = 8
23254+};
23255+
23256+/* Password setup definitions
23257+ * kernel/grhash.c */
23258+enum {
23259+ GR_PW_LEN = 128,
23260+ GR_SALT_LEN = 16,
23261+ GR_SHA_LEN = 32,
23262+};
23263+
23264+enum {
23265+ GR_SPROLE_LEN = 64,
23266+};
23267+
23268+#define GR_NLIMITS (RLIMIT_LOCKS + 2)
23269+
23270+/* Begin Data Structures */
23271+
23272+struct sprole_pw {
23273+ unsigned char *rolename;
23274+ unsigned char salt[GR_SALT_LEN];
23275+ unsigned char sum[GR_SHA_LEN]; /* 256-bit SHA hash of the password */
23276+};
23277+
23278+struct name_entry {
23279+ __u32 key;
23280+ ino_t inode;
23281+ dev_t device;
23282+ char *name;
23283+ __u16 len;
23284+ struct name_entry *prev;
23285+ struct name_entry *next;
23286+};
23287+
23288+struct inodev_entry {
23289+ struct name_entry *nentry;
23290+ struct inodev_entry *prev;
23291+ struct inodev_entry *next;
23292+};
23293+
23294+struct acl_role_db {
23295+ struct acl_role_label **r_hash;
23296+ __u32 r_size;
23297+};
23298+
23299+struct inodev_db {
23300+ struct inodev_entry **i_hash;
23301+ __u32 i_size;
23302+};
23303+
23304+struct name_db {
23305+ struct name_entry **n_hash;
23306+ __u32 n_size;
23307+};
23308+
23309+struct crash_uid {
23310+ uid_t uid;
23311+ unsigned long expires;
23312+};
23313+
23314+struct gr_hash_struct {
23315+ void **table;
23316+ void **nametable;
23317+ void *first;
23318+ __u32 table_size;
23319+ __u32 used_size;
23320+ int type;
23321+};
23322+
23323+/* Userspace Grsecurity ACL data structures */
23324+
23325+struct acl_subject_label {
23326+ char *filename;
23327+ ino_t inode;
23328+ dev_t device;
23329+ __u32 mode;
23330+ __u32 cap_mask;
23331+ __u32 cap_lower;
23332+
23333+ struct rlimit res[GR_NLIMITS];
23334+ __u16 resmask;
23335+
23336+ __u8 user_trans_type;
23337+ __u8 group_trans_type;
23338+ uid_t *user_transitions;
23339+ gid_t *group_transitions;
23340+ __u16 user_trans_num;
23341+ __u16 group_trans_num;
23342+
23343+ __u32 ip_proto[8];
23344+ __u32 ip_type;
23345+ struct acl_ip_label **ips;
23346+ __u32 ip_num;
23347+
23348+ __u32 crashes;
23349+ unsigned long expires;
23350+
23351+ struct acl_subject_label *parent_subject;
23352+ struct gr_hash_struct *hash;
23353+ struct acl_subject_label *prev;
23354+ struct acl_subject_label *next;
23355+
23356+ struct acl_object_label **obj_hash;
23357+ __u32 obj_hash_size;
23358+ __u16 pax_flags;
23359+};
23360+
23361+struct role_allowed_ip {
23362+ __u32 addr;
23363+ __u32 netmask;
23364+
23365+ struct role_allowed_ip *prev;
23366+ struct role_allowed_ip *next;
23367+};
23368+
23369+struct role_transition {
23370+ char *rolename;
23371+
23372+ struct role_transition *prev;
23373+ struct role_transition *next;
23374+};
23375+
23376+struct acl_role_label {
23377+ char *rolename;
23378+ uid_t uidgid;
23379+ __u16 roletype;
23380+
23381+ __u16 auth_attempts;
23382+ unsigned long expires;
23383+
23384+ struct acl_subject_label *root_label;
23385+ struct gr_hash_struct *hash;
23386+
23387+ struct acl_role_label *prev;
23388+ struct acl_role_label *next;
23389+
23390+ struct role_transition *transitions;
23391+ struct role_allowed_ip *allowed_ips;
23392+ uid_t *domain_children;
23393+ __u16 domain_child_num;
23394+
23395+ struct acl_subject_label **subj_hash;
23396+ __u32 subj_hash_size;
23397+};
23398+
23399+struct user_acl_role_db {
23400+ struct acl_role_label **r_table;
23401+ __u32 num_pointers; /* Number of allocations to track */
23402+ __u32 num_roles; /* Number of roles */
23403+ __u32 num_domain_children; /* Number of domain children */
23404+ __u32 num_subjects; /* Number of subjects */
23405+ __u32 num_objects; /* Number of objects */
23406+};
23407+
23408+struct acl_object_label {
23409+ char *filename;
23410+ ino_t inode;
23411+ dev_t device;
23412+ __u32 mode;
23413+
23414+ struct acl_subject_label *nested;
23415+ struct acl_object_label *globbed;
23416+
23417+ /* next two structures not used */
23418+
23419+ struct acl_object_label *prev;
23420+ struct acl_object_label *next;
23421+};
23422+
23423+struct acl_ip_label {
23424+ char *iface;
23425+ __u32 addr;
23426+ __u32 netmask;
23427+ __u16 low, high;
23428+ __u8 mode;
23429+ __u32 type;
23430+ __u32 proto[8];
23431+
23432+ /* next two structures not used */
23433+
23434+ struct acl_ip_label *prev;
23435+ struct acl_ip_label *next;
23436+};
23437+
23438+struct gr_arg {
23439+ struct user_acl_role_db role_db;
23440+ unsigned char pw[GR_PW_LEN];
23441+ unsigned char salt[GR_SALT_LEN];
23442+ unsigned char sum[GR_SHA_LEN];
23443+ unsigned char sp_role[GR_SPROLE_LEN];
23444+ struct sprole_pw *sprole_pws;
23445+ dev_t segv_device;
23446+ ino_t segv_inode;
23447+ uid_t segv_uid;
23448+ __u16 num_sprole_pws;
23449+ __u16 mode;
23450+};
23451+
23452+struct gr_arg_wrapper {
23453+ struct gr_arg *arg;
23454+ __u32 version;
23455+ __u32 size;
23456+};
23457+
23458+struct subject_map {
23459+ struct acl_subject_label *user;
23460+ struct acl_subject_label *kernel;
23461+ struct subject_map *prev;
23462+ struct subject_map *next;
23463+};
23464+
23465+struct acl_subj_map_db {
23466+ struct subject_map **s_hash;
23467+ __u32 s_size;
23468+};
23469+
23470+/* End Data Structures Section */
23471+
23472+/* Hash functions generated by empirical testing by Brad Spengler
23473+ Makes good use of the low bits of the inode. Generally 0-1 times
23474+ in loop for successful match. 0-3 for unsuccessful match.
23475+ Shift/add algorithm with modulus of table size and an XOR*/
23476+
23477+static __inline__ unsigned int
23478+rhash(const uid_t uid, const __u16 type, const unsigned int sz)
23479+{
23480+ return (((uid << type) + (uid ^ type)) % sz);
23481+}
23482+
23483+ static __inline__ unsigned int
23484+shash(const struct acl_subject_label *userp, const unsigned int sz)
23485+{
23486+ return ((const unsigned long)userp % sz);
23487+}
23488+
23489+static __inline__ unsigned int
23490+fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
23491+{
23492+ return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
23493+}
23494+
23495+static __inline__ unsigned int
23496+nhash(const char *name, const __u16 len, const unsigned int sz)
23497+{
23498+ return full_name_hash(name, len) % sz;
23499+}
23500+
23501+#define FOR_EACH_ROLE_START(role,iter) \
23502+ role = NULL; \
23503+ iter = 0; \
23504+ while (iter < acl_role_set.r_size) { \
23505+ if (role == NULL) \
23506+ role = acl_role_set.r_hash[iter]; \
23507+ if (role == NULL) { \
23508+ iter++; \
23509+ continue; \
23510+ }
23511+
23512+#define FOR_EACH_ROLE_END(role,iter) \
23513+ role = role->next; \
23514+ if (role == NULL) \
23515+ iter++; \
23516+ }
23517+
23518+#define FOR_EACH_SUBJECT_START(role,subj,iter) \
23519+ subj = NULL; \
23520+ iter = 0; \
23521+ while (iter < role->subj_hash_size) { \
23522+ if (subj == NULL) \
23523+ subj = role->subj_hash[iter]; \
23524+ if (subj == NULL) { \
23525+ iter++; \
23526+ continue; \
23527+ }
23528+
23529+#define FOR_EACH_SUBJECT_END(subj,iter) \
23530+ subj = subj->next; \
23531+ if (subj == NULL) \
23532+ iter++; \
23533+ }
23534+
23535+
23536+#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
23537+ subj = role->hash->first; \
23538+ while (subj != NULL) {
23539+
23540+#define FOR_EACH_NESTED_SUBJECT_END(subj) \
23541+ subj = subj->next; \
23542+ }
23543+
23544+#endif
23545+
23546diff -urNp linux-2.6.19.1/include/linux/gralloc.h linux-2.6.19.1/include/linux/gralloc.h
23547--- linux-2.6.19.1/include/linux/gralloc.h 1969-12-31 19:00:00.000000000 -0500
23548+++ linux-2.6.19.1/include/linux/gralloc.h 2006-12-03 15:16:25.000000000 -0500
23549@@ -0,0 +1,8 @@
23550+#ifndef __GRALLOC_H
23551+#define __GRALLOC_H
23552+
23553+void acl_free_all(void);
23554+int acl_alloc_stack_init(unsigned long size);
23555+void *acl_alloc(unsigned long len);
23556+
23557+#endif
23558diff -urNp linux-2.6.19.1/include/linux/grdefs.h linux-2.6.19.1/include/linux/grdefs.h
23559--- linux-2.6.19.1/include/linux/grdefs.h 1969-12-31 19:00:00.000000000 -0500
23560+++ linux-2.6.19.1/include/linux/grdefs.h 2006-12-03 15:16:25.000000000 -0500
23561@@ -0,0 +1,131 @@
23562+#ifndef GRDEFS_H
23563+#define GRDEFS_H
23564+
23565+/* Begin grsecurity status declarations */
23566+
23567+enum {
23568+ GR_READY = 0x01,
23569+ GR_STATUS_INIT = 0x00 // disabled state
23570+};
23571+
23572+/* Begin ACL declarations */
23573+
23574+/* Role flags */
23575+
23576+enum {
23577+ GR_ROLE_USER = 0x0001,
23578+ GR_ROLE_GROUP = 0x0002,
23579+ GR_ROLE_DEFAULT = 0x0004,
23580+ GR_ROLE_SPECIAL = 0x0008,
23581+ GR_ROLE_AUTH = 0x0010,
23582+ GR_ROLE_NOPW = 0x0020,
23583+ GR_ROLE_GOD = 0x0040,
23584+ GR_ROLE_LEARN = 0x0080,
23585+ GR_ROLE_TPE = 0x0100,
23586+ GR_ROLE_DOMAIN = 0x0200,
23587+ GR_ROLE_PAM = 0x0400
23588+};
23589+
23590+/* ACL Subject and Object mode flags */
23591+enum {
23592+ GR_DELETED = 0x80000000
23593+};
23594+
23595+/* ACL Object-only mode flags */
23596+enum {
23597+ GR_READ = 0x00000001,
23598+ GR_APPEND = 0x00000002,
23599+ GR_WRITE = 0x00000004,
23600+ GR_EXEC = 0x00000008,
23601+ GR_FIND = 0x00000010,
23602+ GR_INHERIT = 0x00000020,
23603+ GR_SETID = 0x00000040,
23604+ GR_CREATE = 0x00000080,
23605+ GR_DELETE = 0x00000100,
23606+ GR_LINK = 0x00000200,
23607+ GR_AUDIT_READ = 0x00000400,
23608+ GR_AUDIT_APPEND = 0x00000800,
23609+ GR_AUDIT_WRITE = 0x00001000,
23610+ GR_AUDIT_EXEC = 0x00002000,
23611+ GR_AUDIT_FIND = 0x00004000,
23612+ GR_AUDIT_INHERIT= 0x00008000,
23613+ GR_AUDIT_SETID = 0x00010000,
23614+ GR_AUDIT_CREATE = 0x00020000,
23615+ GR_AUDIT_DELETE = 0x00040000,
23616+ GR_AUDIT_LINK = 0x00080000,
23617+ GR_PTRACERD = 0x00100000,
23618+ GR_NOPTRACE = 0x00200000,
23619+ GR_SUPPRESS = 0x00400000,
23620+ GR_NOLEARN = 0x00800000
23621+};
23622+
23623+#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
23624+ GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
23625+ GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
23626+
23627+/* ACL subject-only mode flags */
23628+enum {
23629+ GR_KILL = 0x00000001,
23630+ GR_VIEW = 0x00000002,
23631+ GR_PROTECTED = 0x00000004,
23632+ GR_LEARN = 0x00000008,
23633+ GR_OVERRIDE = 0x00000010,
23634+ /* just a placeholder, this mode is only used in userspace */
23635+ GR_DUMMY = 0x00000020,
23636+ GR_PROTSHM = 0x00000040,
23637+ GR_KILLPROC = 0x00000080,
23638+ GR_KILLIPPROC = 0x00000100,
23639+ /* just a placeholder, this mode is only used in userspace */
23640+ GR_NOTROJAN = 0x00000200,
23641+ GR_PROTPROCFD = 0x00000400,
23642+ GR_PROCACCT = 0x00000800,
23643+ GR_RELAXPTRACE = 0x00001000,
23644+ GR_NESTED = 0x00002000,
23645+ GR_INHERITLEARN = 0x00004000,
23646+ GR_PROCFIND = 0x00008000,
23647+ GR_POVERRIDE = 0x00010000,
23648+ GR_KERNELAUTH = 0x00020000,
23649+};
23650+
23651+enum {
23652+ GR_PAX_ENABLE_SEGMEXEC = 0x0001,
23653+ GR_PAX_ENABLE_PAGEEXEC = 0x0002,
23654+ GR_PAX_ENABLE_MPROTECT = 0x0004,
23655+ GR_PAX_ENABLE_RANDMMAP = 0x0008,
23656+ GR_PAX_ENABLE_EMUTRAMP = 0x0010,
23657+ GR_PAX_DISABLE_SEGMEXEC = 0x8001,
23658+ GR_PAX_DISABLE_PAGEEXEC = 0x8002,
23659+ GR_PAX_DISABLE_MPROTECT = 0x8004,
23660+ GR_PAX_DISABLE_RANDMMAP = 0x8008,
23661+ GR_PAX_DISABLE_EMUTRAMP = 0x8010,
23662+};
23663+
23664+enum {
23665+ GR_ID_USER = 0x01,
23666+ GR_ID_GROUP = 0x02,
23667+};
23668+
23669+enum {
23670+ GR_ID_ALLOW = 0x01,
23671+ GR_ID_DENY = 0x02,
23672+};
23673+
23674+#define GR_CRASH_RES 11
23675+#define GR_UIDTABLE_MAX 500
23676+
23677+/* begin resource learning section */
23678+enum {
23679+ GR_RLIM_CPU_BUMP = 60,
23680+ GR_RLIM_FSIZE_BUMP = 50000,
23681+ GR_RLIM_DATA_BUMP = 10000,
23682+ GR_RLIM_STACK_BUMP = 1000,
23683+ GR_RLIM_CORE_BUMP = 10000,
23684+ GR_RLIM_RSS_BUMP = 500000,
23685+ GR_RLIM_NPROC_BUMP = 1,
23686+ GR_RLIM_NOFILE_BUMP = 5,
23687+ GR_RLIM_MEMLOCK_BUMP = 50000,
23688+ GR_RLIM_AS_BUMP = 500000,
23689+ GR_RLIM_LOCKS_BUMP = 2
23690+};
23691+
23692+#endif
23693diff -urNp linux-2.6.19.1/include/linux/grinternal.h linux-2.6.19.1/include/linux/grinternal.h
23694--- linux-2.6.19.1/include/linux/grinternal.h 1969-12-31 19:00:00.000000000 -0500
23695+++ linux-2.6.19.1/include/linux/grinternal.h 2006-12-03 15:16:25.000000000 -0500
23696@@ -0,0 +1,211 @@
23697+#ifndef __GRINTERNAL_H
23698+#define __GRINTERNAL_H
23699+
23700+#ifdef CONFIG_GRKERNSEC
23701+
23702+#include <linux/fs.h>
23703+#include <linux/gracl.h>
23704+#include <linux/grdefs.h>
23705+#include <linux/grmsg.h>
23706+
23707+extern void gr_add_learn_entry(const char *fmt, ...);
23708+extern __u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
23709+ const struct vfsmount *mnt);
23710+extern __u32 gr_check_create(const struct dentry *new_dentry,
23711+ const struct dentry *parent,
23712+ const struct vfsmount *mnt, const __u32 mode);
23713+extern int gr_check_protected_task(const struct task_struct *task);
23714+extern __u32 to_gr_audit(const __u32 reqmode);
23715+extern int gr_set_acls(const int type);
23716+
23717+extern int gr_acl_is_enabled(void);
23718+extern char gr_roletype_to_char(void);
23719+
23720+extern void gr_handle_alertkill(struct task_struct *task);
23721+extern char *gr_to_filename(const struct dentry *dentry,
23722+ const struct vfsmount *mnt);
23723+extern char *gr_to_filename1(const struct dentry *dentry,
23724+ const struct vfsmount *mnt);
23725+extern char *gr_to_filename2(const struct dentry *dentry,
23726+ const struct vfsmount *mnt);
23727+extern char *gr_to_filename3(const struct dentry *dentry,
23728+ const struct vfsmount *mnt);
23729+
23730+extern int grsec_enable_link;
23731+extern int grsec_enable_fifo;
23732+extern int grsec_enable_execve;
23733+extern int grsec_enable_shm;
23734+extern int grsec_enable_execlog;
23735+extern int grsec_enable_signal;
23736+extern int grsec_enable_forkfail;
23737+extern int grsec_enable_time;
23738+extern int grsec_enable_chroot_shmat;
23739+extern int grsec_enable_chroot_findtask;
23740+extern int grsec_enable_chroot_mount;
23741+extern int grsec_enable_chroot_double;
23742+extern int grsec_enable_chroot_pivot;
23743+extern int grsec_enable_chroot_chdir;
23744+extern int grsec_enable_chroot_chmod;
23745+extern int grsec_enable_chroot_mknod;
23746+extern int grsec_enable_chroot_fchdir;
23747+extern int grsec_enable_chroot_nice;
23748+extern int grsec_enable_chroot_execlog;
23749+extern int grsec_enable_chroot_caps;
23750+extern int grsec_enable_chroot_sysctl;
23751+extern int grsec_enable_chroot_unix;
23752+extern int grsec_enable_tpe;
23753+extern int grsec_tpe_gid;
23754+extern int grsec_enable_tpe_all;
23755+extern int grsec_enable_sidcaps;
23756+extern int grsec_enable_randpid;
23757+extern int grsec_enable_socket_all;
23758+extern int grsec_socket_all_gid;
23759+extern int grsec_enable_socket_client;
23760+extern int grsec_socket_client_gid;
23761+extern int grsec_enable_socket_server;
23762+extern int grsec_socket_server_gid;
23763+extern int grsec_audit_gid;
23764+extern int grsec_enable_group;
23765+extern int grsec_enable_audit_ipc;
23766+extern int grsec_enable_audit_textrel;
23767+extern int grsec_enable_mount;
23768+extern int grsec_enable_chdir;
23769+extern int grsec_resource_logging;
23770+extern int grsec_lock;
23771+
23772+extern struct task_struct *child_reaper;
23773+
23774+extern spinlock_t grsec_alert_lock;
23775+extern unsigned long grsec_alert_wtime;
23776+extern unsigned long grsec_alert_fyet;
23777+
23778+extern spinlock_t grsec_audit_lock;
23779+
23780+extern rwlock_t grsec_exec_file_lock;
23781+
23782+#define gr_task_fullpath(tsk) (tsk->exec_file ? \
23783+ gr_to_filename2(tsk->exec_file->f_dentry, \
23784+ tsk->exec_file->f_vfsmnt) : "/")
23785+
23786+#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
23787+ gr_to_filename3(tsk->parent->exec_file->f_dentry, \
23788+ tsk->parent->exec_file->f_vfsmnt) : "/")
23789+
23790+#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
23791+ gr_to_filename(tsk->exec_file->f_dentry, \
23792+ tsk->exec_file->f_vfsmnt) : "/")
23793+
23794+#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
23795+ gr_to_filename1(tsk->parent->exec_file->f_dentry, \
23796+ tsk->parent->exec_file->f_vfsmnt) : "/")
23797+
23798+#define proc_is_chrooted(tsk_a) ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
23799+ ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
23800+ child_reaper->fs->root->d_inode->i_sb->s_dev) || \
23801+ (tsk_a->fs->root->d_inode->i_ino != \
23802+ child_reaper->fs->root->d_inode->i_ino)))
23803+
23804+#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
23805+ (tsk_a->fs->root->d_inode->i_sb->s_dev == \
23806+ tsk_b->fs->root->d_inode->i_sb->s_dev) && \
23807+ (tsk_a->fs->root->d_inode->i_ino == \
23808+ tsk_b->fs->root->d_inode->i_ino))
23809+
23810+#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
23811+ task->pid, task->uid, \
23812+ task->euid, task->gid, task->egid, \
23813+ gr_parent_task_fullpath(task), \
23814+ task->parent->comm, task->parent->pid, \
23815+ task->parent->uid, task->parent->euid, \
23816+ task->parent->gid, task->parent->egid
23817+
23818+#define GR_CHROOT_CAPS ( \
23819+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
23820+ CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
23821+ CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
23822+ CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
23823+ CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
23824+ CAP_TO_MASK(CAP_IPC_OWNER))
23825+
23826+#define security_learn(normal_msg,args...) \
23827+({ \
23828+ read_lock(&grsec_exec_file_lock); \
23829+ gr_add_learn_entry(normal_msg "\n", ## args); \
23830+ read_unlock(&grsec_exec_file_lock); \
23831+})
23832+
23833+enum {
23834+ GR_DO_AUDIT,
23835+ GR_DONT_AUDIT,
23836+ GR_DONT_AUDIT_GOOD
23837+};
23838+
23839+enum {
23840+ GR_TTYSNIFF,
23841+ GR_RBAC,
23842+ GR_RBAC_STR,
23843+ GR_STR_RBAC,
23844+ GR_RBAC_MODE2,
23845+ GR_RBAC_MODE3,
23846+ GR_FILENAME,
23847+ GR_NOARGS,
23848+ GR_ONE_INT,
23849+ GR_ONE_INT_TWO_STR,
23850+ GR_ONE_STR,
23851+ GR_STR_INT,
23852+ GR_TWO_INT,
23853+ GR_THREE_INT,
23854+ GR_FIVE_INT_TWO_STR,
23855+ GR_TWO_STR,
23856+ GR_THREE_STR,
23857+ GR_FOUR_STR,
23858+ GR_STR_FILENAME,
23859+ GR_FILENAME_STR,
23860+ GR_FILENAME_TWO_INT,
23861+ GR_FILENAME_TWO_INT_STR,
23862+ GR_TEXTREL,
23863+ GR_PTRACE,
23864+ GR_RESOURCE,
23865+ GR_CAP,
23866+ GR_SIG,
23867+ GR_CRASH1,
23868+ GR_CRASH2,
23869+ GR_PSACCT
23870+};
23871+
23872+#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
23873+#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
23874+#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
23875+#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
23876+#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
23877+#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)
23878+#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
23879+#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
23880+#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
23881+#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
23882+#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
23883+#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
23884+#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
23885+#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
23886+#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)
23887+#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
23888+#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
23889+#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
23890+#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
23891+#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
23892+#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
23893+#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)
23894+#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
23895+#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
23896+#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
23897+#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
23898+#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
23899+#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
23900+#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
23901+#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)
23902+
23903+extern void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
23904+
23905+#endif
23906+
23907+#endif
23908diff -urNp linux-2.6.19.1/include/linux/grmsg.h linux-2.6.19.1/include/linux/grmsg.h
23909--- linux-2.6.19.1/include/linux/grmsg.h 1969-12-31 19:00:00.000000000 -0500
23910+++ linux-2.6.19.1/include/linux/grmsg.h 2006-12-03 15:16:25.000000000 -0500
23911@@ -0,0 +1,108 @@
23912+#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"
23913+#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"
23914+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
23915+#define GR_STOPMOD_MSG "denied modification of module state by "
23916+#define GR_IOPERM_MSG "denied use of ioperm() by "
23917+#define GR_IOPL_MSG "denied use of iopl() by "
23918+#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
23919+#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
23920+#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
23921+#define GR_KMEM_MSG "denied write of /dev/kmem by "
23922+#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
23923+#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
23924+#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
23925+#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
23926+#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"
23927+#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"
23928+#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
23929+#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
23930+#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
23931+#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
23932+#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
23933+#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
23934+#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
23935+#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
23936+#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
23937+#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
23938+#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
23939+#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
23940+#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
23941+#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
23942+#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
23943+#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
23944+#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
23945+#define GR_NPROC_MSG "denied overstep of process limit by "
23946+#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
23947+#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
23948+#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
23949+#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
23950+#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
23951+#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
23952+#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
23953+#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
23954+#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
23955+#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
23956+#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
23957+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
23958+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
23959+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
23960+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
23961+#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
23962+#define GR_INITF_ACL_MSG "init_variables() failed %s by "
23963+#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"
23964+#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
23965+#define GR_SHUTS_ACL_MSG "shutdown auth success for "
23966+#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
23967+#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
23968+#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
23969+#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
23970+#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
23971+#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
23972+#define GR_ENABLEF_ACL_MSG "unable to load %s for "
23973+#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
23974+#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
23975+#define GR_RELOADF_ACL_MSG "failed reload of %s for "
23976+#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
23977+#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
23978+#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
23979+#define GR_SPROLEF_ACL_MSG "special role %s failure for "
23980+#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
23981+#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
23982+#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
23983+#define GR_INVMODE_ACL_MSG "invalid mode %d by "
23984+#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
23985+#define GR_FAILFORK_MSG "failed fork with errno %d by "
23986+#define GR_NICE_CHROOT_MSG "denied priority change by "
23987+#define GR_UNISIGLOG_MSG "signal %d sent to "
23988+#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
23989+#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
23990+#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
23991+#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
23992+#define GR_TIME_MSG "time set by "
23993+#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
23994+#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
23995+#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
23996+#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
23997+#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
23998+#define GR_BIND_MSG "denied bind() by "
23999+#define GR_CONNECT_MSG "denied connect() by "
24000+#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
24001+#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
24002+#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"
24003+#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
24004+#define GR_CAP_ACL_MSG "use of %s denied for "
24005+#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
24006+#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
24007+#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
24008+#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
24009+#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
24010+#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
24011+#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
24012+#define GR_MSGQ_AUDIT_MSG "message queue created by "
24013+#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
24014+#define GR_SEM_AUDIT_MSG "semaphore created by "
24015+#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
24016+#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
24017+#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
24018+#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
24019+#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
24020diff -urNp linux-2.6.19.1/include/linux/grsecurity.h linux-2.6.19.1/include/linux/grsecurity.h
24021--- linux-2.6.19.1/include/linux/grsecurity.h 1969-12-31 19:00:00.000000000 -0500
24022+++ linux-2.6.19.1/include/linux/grsecurity.h 2006-12-03 15:16:25.000000000 -0500
24023@@ -0,0 +1,196 @@
24024+#ifndef GR_SECURITY_H
24025+#define GR_SECURITY_H
24026+#include <linux/fs.h>
24027+#include <linux/binfmts.h>
24028+#include <linux/gracl.h>
24029+
24030+extern void gr_handle_brute_attach(struct task_struct *p);
24031+extern void gr_handle_brute_check(void);
24032+
24033+extern char gr_roletype_to_char(void);
24034+
24035+extern int gr_check_user_change(int real, int effective, int fs);
24036+extern int gr_check_group_change(int real, int effective, int fs);
24037+
24038+extern void gr_del_task_from_ip_table(struct task_struct *p);
24039+
24040+extern int gr_pid_is_chrooted(struct task_struct *p);
24041+extern int gr_handle_chroot_nice(void);
24042+extern int gr_handle_chroot_sysctl(const int op);
24043+extern int gr_handle_chroot_setpriority(struct task_struct *p,
24044+ const int niceval);
24045+extern int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
24046+extern int gr_handle_chroot_chroot(const struct dentry *dentry,
24047+ const struct vfsmount *mnt);
24048+extern void gr_handle_chroot_caps(struct task_struct *task);
24049+extern void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
24050+extern int gr_handle_chroot_chmod(const struct dentry *dentry,
24051+ const struct vfsmount *mnt, const int mode);
24052+extern int gr_handle_chroot_mknod(const struct dentry *dentry,
24053+ const struct vfsmount *mnt, const int mode);
24054+extern int gr_handle_chroot_mount(const struct dentry *dentry,
24055+ const struct vfsmount *mnt,
24056+ const char *dev_name);
24057+extern int gr_handle_chroot_pivot(void);
24058+extern int gr_handle_chroot_unix(const pid_t pid);
24059+
24060+extern int gr_handle_rawio(const struct inode *inode);
24061+extern int gr_handle_nproc(void);
24062+
24063+extern void gr_handle_ioperm(void);
24064+extern void gr_handle_iopl(void);
24065+
24066+extern int gr_tpe_allow(const struct file *file);
24067+
24068+extern int gr_random_pid(void);
24069+
24070+extern void gr_log_forkfail(const int retval);
24071+extern void gr_log_timechange(void);
24072+extern void gr_log_signal(const int sig, const struct task_struct *t);
24073+extern void gr_log_chdir(const struct dentry *dentry,
24074+ const struct vfsmount *mnt);
24075+extern void gr_log_chroot_exec(const struct dentry *dentry,
24076+ const struct vfsmount *mnt);
24077+extern void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
24078+extern void gr_log_remount(const char *devname, const int retval);
24079+extern void gr_log_unmount(const char *devname, const int retval);
24080+extern void gr_log_mount(const char *from, const char *to, const int retval);
24081+extern void gr_log_msgget(const int ret, const int msgflg);
24082+extern void gr_log_msgrm(const uid_t uid, const uid_t cuid);
24083+extern void gr_log_semget(const int err, const int semflg);
24084+extern void gr_log_semrm(const uid_t uid, const uid_t cuid);
24085+extern void gr_log_shmget(const int err, const int shmflg, const size_t size);
24086+extern void gr_log_shmrm(const uid_t uid, const uid_t cuid);
24087+extern void gr_log_textrel(struct vm_area_struct *vma);
24088+
24089+extern int gr_handle_follow_link(const struct inode *parent,
24090+ const struct inode *inode,
24091+ const struct dentry *dentry,
24092+ const struct vfsmount *mnt);
24093+extern int gr_handle_fifo(const struct dentry *dentry,
24094+ const struct vfsmount *mnt,
24095+ const struct dentry *dir, const int flag,
24096+ const int acc_mode);
24097+extern int gr_handle_hardlink(const struct dentry *dentry,
24098+ const struct vfsmount *mnt,
24099+ struct inode *inode,
24100+ const int mode, const char *to);
24101+
24102+extern int gr_task_is_capable(struct task_struct *task, const int cap);
24103+extern int gr_is_capable_nolog(const int cap);
24104+extern void gr_learn_resource(const struct task_struct *task, const int limit,
24105+ const unsigned long wanted, const int gt);
24106+extern void gr_copy_label(struct task_struct *tsk);
24107+extern void gr_handle_crash(struct task_struct *task, const int sig);
24108+extern int gr_handle_signal(const struct task_struct *p, const int sig);
24109+extern int gr_check_crash_uid(const uid_t uid);
24110+extern int gr_check_protected_task(const struct task_struct *task);
24111+extern int gr_acl_handle_mmap(const struct file *file,
24112+ const unsigned long prot);
24113+extern int gr_acl_handle_mprotect(const struct file *file,
24114+ const unsigned long prot);
24115+extern int gr_check_hidden_task(const struct task_struct *tsk);
24116+extern __u32 gr_acl_handle_truncate(const struct dentry *dentry,
24117+ const struct vfsmount *mnt);
24118+extern __u32 gr_acl_handle_utime(const struct dentry *dentry,
24119+ const struct vfsmount *mnt);
24120+extern __u32 gr_acl_handle_access(const struct dentry *dentry,
24121+ const struct vfsmount *mnt, const int fmode);
24122+extern __u32 gr_acl_handle_fchmod(const struct dentry *dentry,
24123+ const struct vfsmount *mnt, mode_t mode);
24124+extern __u32 gr_acl_handle_chmod(const struct dentry *dentry,
24125+ const struct vfsmount *mnt, mode_t mode);
24126+extern __u32 gr_acl_handle_chown(const struct dentry *dentry,
24127+ const struct vfsmount *mnt);
24128+extern int gr_handle_ptrace(struct task_struct *task, const long request);
24129+extern int gr_handle_proc_ptrace(struct task_struct *task);
24130+extern __u32 gr_acl_handle_execve(const struct dentry *dentry,
24131+ const struct vfsmount *mnt);
24132+extern int gr_check_crash_exec(const struct file *filp);
24133+extern int gr_acl_is_enabled(void);
24134+extern void gr_set_kernel_label(struct task_struct *task);
24135+extern void gr_set_role_label(struct task_struct *task, const uid_t uid,
24136+ const gid_t gid);
24137+extern int gr_set_proc_label(const struct dentry *dentry,
24138+ const struct vfsmount *mnt);
24139+extern __u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
24140+ const struct vfsmount *mnt);
24141+extern __u32 gr_acl_handle_open(const struct dentry *dentry,
24142+ const struct vfsmount *mnt, const int fmode);
24143+extern __u32 gr_acl_handle_creat(const struct dentry *dentry,
24144+ const struct dentry *p_dentry,
24145+ const struct vfsmount *p_mnt, const int fmode,
24146+ const int imode);
24147+extern void gr_handle_create(const struct dentry *dentry,
24148+ const struct vfsmount *mnt);
24149+extern __u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
24150+ const struct dentry *parent_dentry,
24151+ const struct vfsmount *parent_mnt,
24152+ const int mode);
24153+extern __u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
24154+ const struct dentry *parent_dentry,
24155+ const struct vfsmount *parent_mnt);
24156+extern __u32 gr_acl_handle_rmdir(const struct dentry *dentry,
24157+ const struct vfsmount *mnt);
24158+extern void gr_handle_delete(const ino_t ino, const dev_t dev);
24159+extern __u32 gr_acl_handle_unlink(const struct dentry *dentry,
24160+ const struct vfsmount *mnt);
24161+extern __u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
24162+ const struct dentry *parent_dentry,
24163+ const struct vfsmount *parent_mnt,
24164+ const char *from);
24165+extern __u32 gr_acl_handle_link(const struct dentry *new_dentry,
24166+ const struct dentry *parent_dentry,
24167+ const struct vfsmount *parent_mnt,
24168+ const struct dentry *old_dentry,
24169+ const struct vfsmount *old_mnt, const char *to);
24170+extern int gr_acl_handle_rename(struct dentry *new_dentry,
24171+ struct dentry *parent_dentry,
24172+ const struct vfsmount *parent_mnt,
24173+ struct dentry *old_dentry,
24174+ struct inode *old_parent_inode,
24175+ struct vfsmount *old_mnt, const char *newname);
24176+extern void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
24177+ struct dentry *old_dentry,
24178+ struct dentry *new_dentry,
24179+ struct vfsmount *mnt, const __u8 replace);
24180+extern __u32 gr_check_link(const struct dentry *new_dentry,
24181+ const struct dentry *parent_dentry,
24182+ const struct vfsmount *parent_mnt,
24183+ const struct dentry *old_dentry,
24184+ const struct vfsmount *old_mnt);
24185+extern int gr_acl_handle_filldir(const struct file *file, const char *name,
24186+ const unsigned int namelen, const ino_t ino);
24187+
24188+extern __u32 gr_acl_handle_unix(const struct dentry *dentry,
24189+ const struct vfsmount *mnt);
24190+extern void gr_acl_handle_exit(void);
24191+extern void gr_acl_handle_psacct(struct task_struct *task, const long code);
24192+extern int gr_acl_handle_procpidmem(const struct task_struct *task);
24193+extern __u32 gr_cap_rtnetlink(void);
24194+
24195+#ifdef CONFIG_SYSVIPC
24196+extern void gr_shm_exit(struct task_struct *task);
24197+#else
24198+static inline void gr_shm_exit(struct task_struct *task)
24199+{
24200+ return;
24201+}
24202+#endif
24203+
24204+#ifdef CONFIG_GRKERNSEC
24205+extern void gr_handle_mem_write(void);
24206+extern void gr_handle_kmem_write(void);
24207+extern void gr_handle_open_port(void);
24208+extern int gr_handle_mem_mmap(const unsigned long offset,
24209+ struct vm_area_struct *vma);
24210+
24211+extern unsigned long pax_get_random_long(void);
24212+#define get_random_long() pax_get_random_long()
24213+
24214+extern int grsec_enable_dmesg;
24215+extern int grsec_enable_randsrc;
24216+extern int grsec_enable_shm;
24217+#endif
24218+
24219+#endif
24220diff -urNp linux-2.6.19.1/include/linux/highmem.h linux-2.6.19.1/include/linux/highmem.h
24221--- linux-2.6.19.1/include/linux/highmem.h 2006-11-29 16:57:37.000000000 -0500
24222+++ linux-2.6.19.1/include/linux/highmem.h 2006-12-03 15:16:24.000000000 -0500
24223@@ -74,9 +74,9 @@ alloc_zeroed_user_highpage(struct vm_are
24224
24225 static inline void clear_highpage(struct page *page)
24226 {
24227- void *kaddr = kmap_atomic(page, KM_USER0);
24228+ void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
24229 clear_page(kaddr);
24230- kunmap_atomic(kaddr, KM_USER0);
24231+ kunmap_atomic(kaddr, KM_CLEARPAGE);
24232 }
24233
24234 /*
24235diff -urNp linux-2.6.19.1/include/linux/jbd2.h linux-2.6.19.1/include/linux/jbd2.h
24236--- linux-2.6.19.1/include/linux/jbd2.h 2006-11-29 16:57:37.000000000 -0500
24237+++ linux-2.6.19.1/include/linux/jbd2.h 2006-12-03 15:16:24.000000000 -0500
24238@@ -68,7 +68,7 @@ extern int jbd2_journal_enable_debug;
24239 } \
24240 } while (0)
24241 #else
24242-#define jbd_debug(f, a...) /**/
24243+#define jbd_debug(f, a...) do {} while (0)
24244 #endif
24245
24246 extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
24247diff -urNp linux-2.6.19.1/include/linux/jbd.h linux-2.6.19.1/include/linux/jbd.h
24248--- linux-2.6.19.1/include/linux/jbd.h 2006-11-29 16:57:37.000000000 -0500
24249+++ linux-2.6.19.1/include/linux/jbd.h 2006-12-03 15:16:24.000000000 -0500
24250@@ -68,7 +68,7 @@ extern int journal_enable_debug;
24251 } \
24252 } while (0)
24253 #else
24254-#define jbd_debug(f, a...) /**/
24255+#define jbd_debug(f, a...) do {} while (0)
24256 #endif
24257
24258 extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
24259diff -urNp linux-2.6.19.1/include/linux/mman.h linux-2.6.19.1/include/linux/mman.h
24260--- linux-2.6.19.1/include/linux/mman.h 2006-11-29 16:57:37.000000000 -0500
24261+++ linux-2.6.19.1/include/linux/mman.h 2006-12-03 15:16:25.000000000 -0500
24262@@ -61,6 +61,11 @@ static inline unsigned long
24263 calc_vm_flag_bits(unsigned long flags)
24264 {
24265 return _calc_vm_trans(flags, MAP_GROWSDOWN, VM_GROWSDOWN ) |
24266+
24267+#ifdef CONFIG_PAX_SEGMEXEC
24268+ _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
24269+#endif
24270+
24271 _calc_vm_trans(flags, MAP_DENYWRITE, VM_DENYWRITE ) |
24272 _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
24273 _calc_vm_trans(flags, MAP_LOCKED, VM_LOCKED );
24274diff -urNp linux-2.6.19.1/include/linux/mm.h linux-2.6.19.1/include/linux/mm.h
24275--- linux-2.6.19.1/include/linux/mm.h 2006-11-29 16:57:37.000000000 -0500
24276+++ linux-2.6.19.1/include/linux/mm.h 2006-12-03 15:16:25.000000000 -0500
24277@@ -39,6 +39,7 @@ extern int sysctl_legacy_va_layout;
24278 #include <asm/page.h>
24279 #include <asm/pgtable.h>
24280 #include <asm/processor.h>
24281+#include <asm/mman.h>
24282
24283 #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
24284
24285@@ -112,8 +113,43 @@ struct vm_area_struct {
24286 #ifdef CONFIG_NUMA
24287 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
24288 #endif
24289+
24290+ unsigned long vm_mirror; /* PaX: mirror distance */
24291 };
24292
24293+#ifdef CONFIG_PAX_SOFTMODE
24294+extern unsigned int pax_softmode;
24295+#endif
24296+
24297+extern int pax_check_flags(unsigned long *);
24298+
24299+/* if tsk != current then task_lock must be held on it */
24300+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
24301+static inline unsigned long pax_get_flags(struct task_struct *tsk)
24302+{
24303+ if (likely(tsk->mm))
24304+ return tsk->mm->pax_flags;
24305+ else
24306+ return 0UL;
24307+}
24308+
24309+/* if tsk != current then task_lock must be held on it */
24310+static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
24311+{
24312+ if (likely(tsk->mm)) {
24313+ tsk->mm->pax_flags = flags;
24314+ return 0;
24315+ }
24316+ return -EINVAL;
24317+}
24318+#endif
24319+
24320+#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
24321+extern void pax_set_initial_flags(struct linux_binprm * bprm);
24322+#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
24323+extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
24324+#endif
24325+
24326 /*
24327 * This struct defines the per-mm list of VMAs for uClinux. If CONFIG_MMU is
24328 * disabled, then there's a single shared list of VMAs maintained by the
24329@@ -167,6 +203,18 @@ extern unsigned int kobjsize(const void
24330 #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */
24331 #define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
24332
24333+#ifdef CONFIG_PAX_SEGMEXEC
24334+#define VM_MIRROR 0x04000000 /* vma is mirroring another */
24335+#endif
24336+
24337+#ifdef CONFIG_PAX_MPROTECT
24338+#define VM_MAYNOTWRITE 0x08000000 /* vma cannot be granted VM_WRITE any more */
24339+#endif
24340+
24341+#ifdef __VM_STACK_FLAGS
24342+#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
24343+#endif
24344+
24345 #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
24346 #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
24347 #endif
24348@@ -1130,5 +1178,11 @@ extern int randomize_va_space;
24349
24350 __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma);
24351
24352+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
24353+extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
24354+#else
24355+static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
24356+#endif
24357+
24358 #endif /* __KERNEL__ */
24359 #endif /* _LINUX_MM_H */
24360diff -urNp linux-2.6.19.1/include/linux/module.h linux-2.6.19.1/include/linux/module.h
24361--- linux-2.6.19.1/include/linux/module.h 2006-11-29 16:57:37.000000000 -0500
24362+++ linux-2.6.19.1/include/linux/module.h 2006-12-03 15:16:25.000000000 -0500
24363@@ -297,16 +297,16 @@ struct module
24364 int (*init)(void);
24365
24366 /* If this is non-NULL, vfree after init() returns */
24367- void *module_init;
24368+ void *module_init_rx, *module_init_rw;
24369
24370 /* Here is the actual code + data, vfree'd on unload. */
24371- void *module_core;
24372+ void *module_core_rx, *module_core_rw;
24373
24374 /* Here are the sizes of the init and core sections */
24375- unsigned long init_size, core_size;
24376+ unsigned long init_size_rw, core_size_rw;
24377
24378 /* The size of the executable code in each section. */
24379- unsigned long init_text_size, core_text_size;
24380+ unsigned long init_size_rx, core_size_rx;
24381
24382 /* The handle returned from unwind_add_table. */
24383 void *unwind_info;
24384diff -urNp linux-2.6.19.1/include/linux/moduleloader.h linux-2.6.19.1/include/linux/moduleloader.h
24385--- linux-2.6.19.1/include/linux/moduleloader.h 2006-11-29 16:57:37.000000000 -0500
24386+++ linux-2.6.19.1/include/linux/moduleloader.h 2006-12-03 15:16:25.000000000 -0500
24387@@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
24388 sections. Returns NULL on failure. */
24389 void *module_alloc(unsigned long size);
24390
24391+#ifdef CONFIG_PAX_KERNEXEC
24392+void *module_alloc_exec(unsigned long size);
24393+#else
24394+#define module_alloc_exec(x) module_alloc(x)
24395+#endif
24396+
24397 /* Free memory returned from module_alloc. */
24398 void module_free(struct module *mod, void *module_region);
24399
24400+#ifdef CONFIG_PAX_KERNEXEC
24401+void module_free_exec(struct module *mod, void *module_region);
24402+#else
24403+#define module_free_exec(x, y) module_free(x, y)
24404+#endif
24405+
24406 /* Apply the given relocation to the (simplified) ELF. Return -error
24407 or 0. */
24408 int apply_relocate(Elf_Shdr *sechdrs,
24409diff -urNp linux-2.6.19.1/include/linux/random.h linux-2.6.19.1/include/linux/random.h
24410--- linux-2.6.19.1/include/linux/random.h 2006-11-29 16:57:37.000000000 -0500
24411+++ linux-2.6.19.1/include/linux/random.h 2006-12-03 15:16:25.000000000 -0500
24412@@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
24413 extern u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
24414 __u16 sport, __u16 dport);
24415
24416+extern unsigned long pax_get_random_long(void);
24417+
24418 #ifndef MODULE
24419 extern struct file_operations random_fops, urandom_fops;
24420 #endif
24421diff -urNp linux-2.6.19.1/include/linux/sched.h linux-2.6.19.1/include/linux/sched.h
24422--- linux-2.6.19.1/include/linux/sched.h 2006-11-29 16:57:37.000000000 -0500
24423+++ linux-2.6.19.1/include/linux/sched.h 2006-12-03 15:16:25.000000000 -0500
24424@@ -87,6 +87,7 @@ struct sched_param {
24425
24426 struct exec_domain;
24427 struct futex_pi_state;
24428+struct linux_binprm;
24429
24430 /*
24431 * List of flags we want to share for kernel threads,
24432@@ -355,8 +356,34 @@ struct mm_struct {
24433 /* aio bits */
24434 rwlock_t ioctx_list_lock;
24435 struct kioctx *ioctx_list;
24436+
24437+#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
24438+ unsigned long pax_flags;
24439+#endif
24440+
24441+#ifdef CONFIG_PAX_DLRESOLVE
24442+ unsigned long call_dl_resolve;
24443+#endif
24444+
24445+#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
24446+ unsigned long call_syscall;
24447+#endif
24448+
24449+#ifdef CONFIG_PAX_ASLR
24450+ unsigned long delta_mmap; /* randomized offset */
24451+ unsigned long delta_exec; /* randomized offset */
24452+ unsigned long delta_stack; /* randomized offset */
24453+#endif
24454+
24455 };
24456
24457+#define MF_PAX_PAGEEXEC 0x01000000 /* Paging based non-executable pages */
24458+#define MF_PAX_EMUTRAMP 0x02000000 /* Emulate trampolines */
24459+#define MF_PAX_MPROTECT 0x04000000 /* Restrict mprotect() */
24460+#define MF_PAX_RANDMMAP 0x08000000 /* Randomize mmap() base */
24461+/*#define MF_PAX_RANDEXEC 0x10000000*/ /* Randomize ET_EXEC base */
24462+#define MF_PAX_SEGMEXEC 0x20000000 /* Segmentation based non-executable pages */
24463+
24464 struct sighand_struct {
24465 atomic_t count;
24466 struct k_sigaction action[_NSIG];
24467@@ -468,6 +495,15 @@ struct signal_struct {
24468 #ifdef CONFIG_TASKSTATS
24469 struct taskstats *stats;
24470 #endif
24471+
24472+#ifdef CONFIG_GRKERNSEC
24473+ u32 curr_ip;
24474+ u32 gr_saddr;
24475+ u32 gr_daddr;
24476+ u16 gr_sport;
24477+ u16 gr_dport;
24478+ u8 used_accept:1;
24479+#endif
24480 };
24481
24482 /* Context switch must be unlocked if interrupts are to be enabled */
24483@@ -1013,6 +1049,17 @@ struct task_struct {
24484 struct list_head pi_state_list;
24485 struct futex_pi_state *pi_state_cache;
24486
24487+#ifdef CONFIG_GRKERNSEC
24488+ /* grsecurity */
24489+ struct acl_subject_label *acl;
24490+ struct acl_role_label *role;
24491+ struct file *exec_file;
24492+ u16 acl_role_id;
24493+ u8 acl_sp_role:1;
24494+ u8 is_writable:1;
24495+ u8 brute:1;
24496+#endif
24497+
24498 atomic_t fs_excl; /* holding fs exclusive resources */
24499 struct rcu_head rcu;
24500
24501@@ -1595,6 +1642,12 @@ extern void arch_pick_mmap_layout(struct
24502 static inline void arch_pick_mmap_layout(struct mm_struct *mm)
24503 {
24504 mm->mmap_base = TASK_UNMAPPED_BASE;
24505+
24506+#ifdef CONFIG_PAX_RANDMMAP
24507+ if (mm->pax_flags & MF_PAX_RANDMMAP)
24508+ mm->mmap_base += mm->delta_mmap;
24509+#endif
24510+
24511 mm->get_unmapped_area = arch_get_unmapped_area;
24512 mm->unmap_area = arch_unmap_area;
24513 }
24514diff -urNp linux-2.6.19.1/include/linux/shm.h linux-2.6.19.1/include/linux/shm.h
24515--- linux-2.6.19.1/include/linux/shm.h 2006-11-29 16:57:37.000000000 -0500
24516+++ linux-2.6.19.1/include/linux/shm.h 2006-12-03 15:16:25.000000000 -0500
24517@@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
24518 pid_t shm_cprid;
24519 pid_t shm_lprid;
24520 struct user_struct *mlock_user;
24521+#ifdef CONFIG_GRKERNSEC
24522+ time_t shm_createtime;
24523+ pid_t shm_lapid;
24524+#endif
24525 };
24526
24527 /* shm_mode upper byte flags */
24528diff -urNp linux-2.6.19.1/include/linux/skbuff.h linux-2.6.19.1/include/linux/skbuff.h
24529--- linux-2.6.19.1/include/linux/skbuff.h 2006-11-29 16:57:37.000000000 -0500
24530+++ linux-2.6.19.1/include/linux/skbuff.h 2006-12-03 15:16:25.000000000 -0500
24531@@ -372,7 +372,7 @@ extern void skb_truesize_bug(struc
24532
24533 static inline void skb_truesize_check(struct sk_buff *skb)
24534 {
24535- if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
24536+ if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
24537 skb_truesize_bug(skb);
24538 }
24539
24540diff -urNp linux-2.6.19.1/include/linux/sysctl.h linux-2.6.19.1/include/linux/sysctl.h
24541--- linux-2.6.19.1/include/linux/sysctl.h 2006-11-29 16:57:37.000000000 -0500
24542+++ linux-2.6.19.1/include/linux/sysctl.h 2006-12-03 15:16:25.000000000 -0500
24543@@ -160,9 +160,21 @@ enum
24544 KERN_MAX_LOCK_DEPTH=74,
24545 KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
24546 KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
24547-};
24548+#ifdef CONFIG_GRKERNSEC
24549+ KERN_GRSECURITY=98, /* grsecurity */
24550+#endif
24551+
24552+#ifdef CONFIG_PAX_SOFTMODE
24553+ KERN_PAX=99, /* PaX control */
24554+#endif
24555
24556+};
24557
24558+#ifdef CONFIG_PAX_SOFTMODE
24559+enum {
24560+ PAX_SOFTMODE=1 /* PaX: disable/enable soft mode */
24561+};
24562+#endif
24563
24564 /* CTL_VM names: */
24565 enum
24566diff -urNp linux-2.6.19.1/include/linux/uaccess.h linux-2.6.19.1/include/linux/uaccess.h
24567--- linux-2.6.19.1/include/linux/uaccess.h 2006-11-29 16:57:37.000000000 -0500
24568+++ linux-2.6.19.1/include/linux/uaccess.h 2006-12-03 15:16:25.000000000 -0500
24569@@ -34,9 +34,12 @@ static inline unsigned long __copy_from_
24570 #define probe_kernel_address(addr, retval) \
24571 ({ \
24572 long ret; \
24573+ mm_segment_t old_fs = get_fs(); \
24574 \
24575 inc_preempt_count(); \
24576+ set_fs(KERNEL_DS); \
24577 ret = __get_user(retval, addr); \
24578+ set_fs(old_fs); \
24579 dec_preempt_count(); \
24580 ret; \
24581 })
24582diff -urNp linux-2.6.19.1/include/linux/udf_fs.h linux-2.6.19.1/include/linux/udf_fs.h
24583--- linux-2.6.19.1/include/linux/udf_fs.h 2006-11-29 16:57:37.000000000 -0500
24584+++ linux-2.6.19.1/include/linux/udf_fs.h 2006-12-03 15:16:25.000000000 -0500
24585@@ -45,7 +45,7 @@
24586 printk (f, ##a); \
24587 }
24588 #else
24589-#define udf_debug(f, a...) /**/
24590+#define udf_debug(f, a...) do {} while (0)
24591 #endif
24592
24593 #define udf_info(f, a...) \
24594diff -urNp linux-2.6.19.1/include/net/sctp/sctp.h linux-2.6.19.1/include/net/sctp/sctp.h
24595--- linux-2.6.19.1/include/net/sctp/sctp.h 2006-11-29 16:57:37.000000000 -0500
24596+++ linux-2.6.19.1/include/net/sctp/sctp.h 2006-12-03 15:16:25.000000000 -0500
24597@@ -308,8 +308,8 @@ extern int sctp_debug_flag;
24598
24599 #else /* SCTP_DEBUG */
24600
24601-#define SCTP_DEBUG_PRINTK(whatever...)
24602-#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
24603+#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
24604+#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
24605 #define SCTP_ENABLE_DEBUG
24606 #define SCTP_DISABLE_DEBUG
24607 #define SCTP_ASSERT(expr, str, func)
24608diff -urNp linux-2.6.19.1/include/sound/core.h linux-2.6.19.1/include/sound/core.h
24609--- linux-2.6.19.1/include/sound/core.h 2006-11-29 16:57:37.000000000 -0500
24610+++ linux-2.6.19.1/include/sound/core.h 2006-12-03 15:16:25.000000000 -0500
24611@@ -351,9 +351,9 @@ void snd_verbose_printd(const char *file
24612
24613 #else /* !CONFIG_SND_DEBUG */
24614
24615-#define snd_printd(fmt, args...) /* nothing */
24616+#define snd_printd(fmt, args...) do {} while (0)
24617 #define snd_assert(expr, args...) (void)(expr)
24618-#define snd_BUG() /* nothing */
24619+#define snd_BUG() do {} while (0)
24620
24621 #endif /* CONFIG_SND_DEBUG */
24622
24623diff -urNp linux-2.6.19.1/init/do_mounts.c linux-2.6.19.1/init/do_mounts.c
24624--- linux-2.6.19.1/init/do_mounts.c 2006-11-29 16:57:37.000000000 -0500
24625+++ linux-2.6.19.1/init/do_mounts.c 2006-12-03 15:16:25.000000000 -0500
24626@@ -65,11 +65,12 @@ static dev_t try_name(char *name, int pa
24627
24628 /* read device number from .../dev */
24629
24630- sprintf(path, "/sys/block/%s/dev", name);
24631- fd = sys_open(path, 0, 0);
24632+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
24633+ goto fail;
24634+ fd = sys_open((char __user *)path, 0, 0);
24635 if (fd < 0)
24636 goto fail;
24637- len = sys_read(fd, buf, 32);
24638+ len = sys_read(fd, (char __user *)buf, 32);
24639 sys_close(fd);
24640 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
24641 goto fail;
24642@@ -95,11 +96,12 @@ static dev_t try_name(char *name, int pa
24643 return res;
24644
24645 /* otherwise read range from .../range */
24646- sprintf(path, "/sys/block/%s/range", name);
24647- fd = sys_open(path, 0, 0);
24648+ if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
24649+ goto fail;
24650+ fd = sys_open((char __user *)path, 0, 0);
24651 if (fd < 0)
24652 goto fail;
24653- len = sys_read(fd, buf, 32);
24654+ len = sys_read(fd, (char __user *)buf, 32);
24655 sys_close(fd);
24656 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
24657 goto fail;
62894557 24658@@ -158,7 +159,7 @@ dev_t name_to_dev_t(char *name)
b6fa5d20 24659 int part, mount_result;
c3e8c1b5 24660
24661 #ifdef CONFIG_SYSFS
24662- int mkdir_err = sys_mkdir("/sys", 0700);
c3e8c1b5 24663+ int mkdir_err = sys_mkdir((char __user *)"/sys", 0700);
62894557 24664 /*
24665 * When changing resume2 parameter for Software Suspend, sysfs may
24666 * already be mounted.
24667@@ -163,7 +164,7 @@ dev_t name_to_dev_t(char *name)
b6fa5d20 24668 * When changing resume2 parameter for Software Suspend, sysfs may
62894557 24669 * already be mounted.
b6fa5d20 24670 */
24671- mount_result = sys_mount("sysfs", "/sys", "sysfs", 0, NULL);
62894557 24672+ mount_result = sys_mount((char __user *)"sysfs", (char __user *)"/sys", (char __user *)"sysfs", 0, NULL);
b6fa5d20 24673 if (mount_result < 0 && mount_result != -EBUSY)
c3e8c1b5 24674 goto out;
24675 #endif
c3e8c1b5 24676@@ -195,10 +197,10 @@ dev_t name_to_dev_t(char *name)
c3e8c1b5 24677 done:
24678 #ifdef CONFIG_SYSFS
b6fa5d20 24679 if (mount_result >= 0)
24680- sys_umount("/sys", 0);
24681+ sys_umount((char __user *)"/sys", 0);
c3e8c1b5 24682 out:
24683 if (!mkdir_err)
24684- sys_rmdir("/sys");
24685+ sys_rmdir((char __user *)"/sys");
24686 #endif
24687 return res;
24688 fail:
24689@@ -268,11 +270,11 @@ static void __init get_fs_names(char *pa
24690
24691 static int __init do_mount_root(char *name, char *fs, int flags, void *data)
24692 {
24693- int err = sys_mount(name, "/root", fs, flags, data);
24694+ int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
24695 if (err)
24696 return err;
24697
24698- sys_chdir("/root");
24699+ sys_chdir((char __user *)"/root");
24700 ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
24701 printk("VFS: Mounted root (%s filesystem)%s.\n",
24702 current->fs->pwdmnt->mnt_sb->s_type->name,
24703@@ -354,18 +356,18 @@ void __init change_floppy(char *fmt, ...
24704 va_start(args, fmt);
24705 vsprintf(buf, fmt, args);
24706 va_end(args);
24707- fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
24708+ fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
24709 if (fd >= 0) {
24710 sys_ioctl(fd, FDEJECT, 0);
24711 sys_close(fd);
24712 }
24713 printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
24714- fd = sys_open("/dev/console", O_RDWR, 0);
24715+ fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
24716 if (fd >= 0) {
24717 sys_ioctl(fd, TCGETS, (long)&termios);
24718 termios.c_lflag &= ~ICANON;
24719 sys_ioctl(fd, TCSETSF, (long)&termios);
24720- sys_read(fd, &c, 1);
24721+ sys_read(fd, (char __user *)&c, 1);
24722 termios.c_lflag |= ICANON;
24723 sys_ioctl(fd, TCSETSF, (long)&termios);
24724 sys_close(fd);
24725@@ -442,8 +444,8 @@ void __init prepare_namespace(void)
24726
24727 mount_root();
24728 out:
24729- sys_mount(".", "/", NULL, MS_MOVE, NULL);
24730- sys_chroot(".");
24731+ sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
24732+ sys_chroot((char __user *)".");
24733 security_sb_post_mountroot();
24734 }
24735
24736diff -urNp linux-2.6.19.1/init/do_mounts.h linux-2.6.19.1/init/do_mounts.h
24737--- linux-2.6.19.1/init/do_mounts.h 2006-11-29 16:57:37.000000000 -0500
24738+++ linux-2.6.19.1/init/do_mounts.h 2006-12-03 15:16:25.000000000 -0500
24739@@ -15,15 +15,15 @@ extern char *root_device_name;
24740
24741 static inline int create_dev(char *name, dev_t dev)
24742 {
24743- sys_unlink(name);
24744- return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
24745+ sys_unlink((char __user *)name);
24746+ return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
24747 }
24748
24749 #if BITS_PER_LONG == 32
24750 static inline u32 bstat(char *name)
24751 {
24752 struct stat64 stat;
24753- if (sys_stat64(name, &stat) != 0)
24754+ if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
24755 return 0;
24756 if (!S_ISBLK(stat.st_mode))
24757 return 0;
24758diff -urNp linux-2.6.19.1/init/do_mounts_md.c linux-2.6.19.1/init/do_mounts_md.c
24759--- linux-2.6.19.1/init/do_mounts_md.c 2006-11-29 16:57:37.000000000 -0500
24760+++ linux-2.6.19.1/init/do_mounts_md.c 2006-12-03 15:16:25.000000000 -0500
24761@@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
24762 partitioned ? "_d" : "", minor,
24763 md_setup_args[ent].device_names);
24764
24765- fd = sys_open(name, 0, 0);
24766+ fd = sys_open((char __user *)name, 0, 0);
24767 if (fd < 0) {
24768 printk(KERN_ERR "md: open failed - cannot start "
24769 "array %s\n", name);
24770@@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
24771 * array without it
24772 */
24773 sys_close(fd);
24774- fd = sys_open(name, 0, 0);
24775+ fd = sys_open((char __user *)name, 0, 0);
24776 sys_ioctl(fd, BLKRRPART, 0);
24777 }
24778 sys_close(fd);
24779@@ -271,7 +271,7 @@ void __init md_run_setup(void)
24780 if (raid_noautodetect)
24781 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
24782 else {
24783- int fd = sys_open("/dev/md0", 0, 0);
24784+ int fd = sys_open((char __user *)"/dev/md0", 0, 0);
24785 if (fd >= 0) {
24786 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
24787 sys_close(fd);
24788diff -urNp linux-2.6.19.1/init/initramfs.c linux-2.6.19.1/init/initramfs.c
24789--- linux-2.6.19.1/init/initramfs.c 2006-11-29 16:57:37.000000000 -0500
24790+++ linux-2.6.19.1/init/initramfs.c 2006-12-03 15:16:25.000000000 -0500
24791@@ -236,7 +236,7 @@ static int __init maybe_link(void)
24792 if (nlink >= 2) {
24793 char *old = find_link(major, minor, ino, mode, collected);
24794 if (old)
24795- return (sys_link(old, collected) < 0) ? -1 : 1;
24796+ return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
24797 }
24798 return 0;
24799 }
24800@@ -245,11 +245,11 @@ static void __init clean_path(char *path
24801 {
24802 struct stat st;
24803
24804- if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
24805+ if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
24806 if (S_ISDIR(st.st_mode))
24807- sys_rmdir(path);
24808+ sys_rmdir((char __user *)path);
24809 else
24810- sys_unlink(path);
24811+ sys_unlink((char __user *)path);
24812 }
24813 }
24814
24815@@ -272,7 +272,7 @@ static int __init do_name(void)
24816 int openflags = O_WRONLY|O_CREAT;
24817 if (ml != 1)
24818 openflags |= O_TRUNC;
24819- wfd = sys_open(collected, openflags, mode);
24820+ wfd = sys_open((char __user *)collected, openflags, mode);
24821
24822 if (wfd >= 0) {
24823 sys_fchown(wfd, uid, gid);
24824@@ -281,15 +281,15 @@ static int __init do_name(void)
24825 }
24826 }
24827 } else if (S_ISDIR(mode)) {
24828- sys_mkdir(collected, mode);
24829- sys_chown(collected, uid, gid);
24830- sys_chmod(collected, mode);
24831+ sys_mkdir((char __user *)collected, mode);
24832+ sys_chown((char __user *)collected, uid, gid);
24833+ sys_chmod((char __user *)collected, mode);
24834 } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
24835 S_ISFIFO(mode) || S_ISSOCK(mode)) {
24836 if (maybe_link() == 0) {
24837- sys_mknod(collected, mode, rdev);
24838- sys_chown(collected, uid, gid);
24839- sys_chmod(collected, mode);
24840+ sys_mknod((char __user *)collected, mode, rdev);
24841+ sys_chown((char __user *)collected, uid, gid);
24842+ sys_chmod((char __user *)collected, mode);
24843 }
24844 }
24845 return 0;
24846@@ -298,13 +298,13 @@ static int __init do_name(void)
24847 static int __init do_copy(void)
24848 {
24849 if (count >= body_len) {
24850- sys_write(wfd, victim, body_len);
24851+ sys_write(wfd, (char __user *)victim, body_len);
24852 sys_close(wfd);
24853 eat(body_len);
24854 state = SkipIt;
24855 return 0;
24856 } else {
24857- sys_write(wfd, victim, count);
24858+ sys_write(wfd, (char __user *)victim, count);
24859 body_len -= count;
24860 eat(count);
24861 return 1;
24862@@ -315,8 +315,8 @@ static int __init do_symlink(void)
24863 {
24864 collected[N_ALIGN(name_len) + body_len] = '\0';
24865 clean_path(collected, 0);
24866- sys_symlink(collected + N_ALIGN(name_len), collected);
24867- sys_lchown(collected, uid, gid);
24868+ sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
24869+ sys_lchown((char __user *)collected, uid, gid);
24870 state = SkipIt;
24871 next_state = Reset;
24872 return 0;
24873diff -urNp linux-2.6.19.1/init/Kconfig linux-2.6.19.1/init/Kconfig
24874--- linux-2.6.19.1/init/Kconfig 2006-11-29 16:57:37.000000000 -0500
24875+++ linux-2.6.19.1/init/Kconfig 2006-12-03 15:16:25.000000000 -0500
24876@@ -321,6 +321,7 @@ config SYSCTL_SYSCALL
24877 config KALLSYMS
24878 bool "Load all symbols for debugging/kksymoops" if EMBEDDED
24879 default y
24880+ depends on !GRKERNSEC_HIDESYM
24881 help
24882 Say Y here to let the kernel print out symbolic crash information and
24883 symbolic stack backtraces. This increases the size of the kernel
24884diff -urNp linux-2.6.19.1/init/main.c linux-2.6.19.1/init/main.c
24885--- linux-2.6.19.1/init/main.c 2006-11-29 16:57:37.000000000 -0500
24886+++ linux-2.6.19.1/init/main.c 2006-12-03 15:16:25.000000000 -0500
24887@@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void)
24888 #ifdef CONFIG_TC
24889 extern void tc_init(void);
24890 #endif
24891+extern void grsecurity_init(void);
24892
24893 enum system_states system_state;
24894 EXPORT_SYMBOL(system_state);
24895@@ -171,6 +172,15 @@ static int __init set_reset_devices(char
24896
24897 __setup("reset_devices", set_reset_devices);
24898
24899+#ifdef CONFIG_PAX_SOFTMODE
24900+static int __init setup_pax_softmode(char *str)
24901+{
24902+ get_option(&str, &pax_softmode);
24903+ return 1;
24904+}
24905+__setup("pax_softmode=", setup_pax_softmode);
24906+#endif
24907+
24908 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
24909 char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
24910 static const char *panic_later, *panic_param;
24911@@ -754,6 +764,8 @@ static int init(void * unused)
24912 prepare_namespace();
24913 }
24914
24915+ grsecurity_init();
24916+
24917 /*
24918 * Ok, we have completed the initial bootup, and
24919 * we're essentially up and running. Get rid of the
24920diff -urNp linux-2.6.19.1/ipc/msg.c linux-2.6.19.1/ipc/msg.c
24921--- linux-2.6.19.1/ipc/msg.c 2006-11-29 16:57:37.000000000 -0500
24922+++ linux-2.6.19.1/ipc/msg.c 2006-12-03 15:16:26.000000000 -0500
24923@@ -36,6 +36,7 @@
c3e8c1b5 24924 #include <linux/mutex.h>
24925 #include <linux/nsproxy.h>
9bdf255b 24926 #include <linux/vs_base.h>
c3e8c1b5 24927+#include <linux/grsecurity.h>
24928
24929 #include <asm/current.h>
24930 #include <asm/uaccess.h>
24931@@ -288,6 +289,8 @@ asmlinkage long sys_msgget(key_t key, in
24932 }
24933 mutex_unlock(&msg_ids(ns).mutex);
24934
24935+ gr_log_msgget(ret, msgflg);
24936+
24937 return ret;
24938 }
24939
24940@@ -554,6 +557,7 @@ asmlinkage long sys_msgctl(int msqid, in
24941 break;
24942 }
24943 case IPC_RMID:
24944+ gr_log_msgrm(ipcp->uid, ipcp->cuid);
24945 freeque(ns, msq, msqid);
24946 break;
24947 }
24948diff -urNp linux-2.6.19.1/ipc/sem.c linux-2.6.19.1/ipc/sem.c
24949--- linux-2.6.19.1/ipc/sem.c 2006-11-29 16:57:37.000000000 -0500
24950+++ linux-2.6.19.1/ipc/sem.c 2006-12-03 15:16:26.000000000 -0500
24951@@ -83,6 +83,7 @@
c3e8c1b5 24952 #include <linux/nsproxy.h>
9bdf255b 24953 #include <linux/vs_base.h>
24954 #include <linux/vs_limit.h>
c3e8c1b5 24955+#include <linux/grsecurity.h>
24956
24957 #include <asm/uaccess.h>
24958 #include "util.h"
24959@@ -296,6 +297,9 @@ asmlinkage long sys_semget (key_t key, i
24960 }
24961
24962 mutex_unlock(&sem_ids(ns).mutex);
24963+
24964+ gr_log_semget(err, semflg);
24965+
24966 return err;
24967 }
24968
24969@@ -897,6 +901,7 @@ static int semctl_down(struct ipc_namesp
24970
24971 switch(cmd){
24972 case IPC_RMID:
24973+ gr_log_semrm(ipcp->uid, ipcp->cuid);
24974 freeary(ns, sma, semid);
24975 err = 0;
24976 break;
24977diff -urNp linux-2.6.19.1/ipc/shm.c linux-2.6.19.1/ipc/shm.c
24978--- linux-2.6.19.1/ipc/shm.c 2006-11-29 16:57:37.000000000 -0500
24979+++ linux-2.6.19.1/ipc/shm.c 2006-12-03 15:16:26.000000000 -0500
24980@@ -37,6 +37,7 @@
c3e8c1b5 24981 #include <linux/nsproxy.h>
9bdf255b 24982 #include <linux/vs_context.h>
24983 #include <linux/vs_limit.h>
c3e8c1b5 24984+#include <linux/grsecurity.h>
24985
24986 #include <asm/uaccess.h>
24987
24988@@ -67,6 +68,14 @@ static void shm_destroy (struct ipc_name
24989 static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
24990 #endif
24991
24992+#ifdef CONFIG_GRKERNSEC
24993+extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
24994+ const time_t shm_createtime, const uid_t cuid,
24995+ const int shmid);
24996+extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
24997+ const time_t shm_createtime);
24998+#endif
24999+
25000 static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
25001 {
25002 ns->ids[IPC_SHM_IDS] = ids;
25003@@ -79,6 +88,8 @@ static void __ipc_init __shm_init_ns(str
25004
25005 static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
25006 {
25007+ gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
25008+
25009 if (shp->shm_nattch){
25010 shp->shm_perm.mode |= SHM_DEST;
25011 /* Do not find it any more */
25012@@ -216,6 +227,17 @@ static void shm_close (struct vm_area_st
25013 shp->shm_lprid = current->tgid;
25014 shp->shm_dtim = get_seconds();
25015 shp->shm_nattch--;
25016+#ifdef CONFIG_GRKERNSEC_SHM
25017+ if (grsec_enable_shm) {
25018+ if (shp->shm_nattch == 0) {
25019+ shp->shm_perm.mode |= SHM_DEST;
25020+ shm_destroy(ns, shp);
25021+ } else
25022+ shm_unlock(shp);
25023+ mutex_unlock(&shm_ids(ns).mutex);
25024+ return;
25025+ }
25026+#endif
25027 if(shp->shm_nattch == 0 &&
25028 shp->shm_perm.mode & SHM_DEST)
25029 shm_destroy(ns, shp);
25030@@ -326,6 +348,9 @@ static int newseg (struct ipc_namespace
25031 shp->shm_lprid = 0;
25032 shp->shm_atim = shp->shm_dtim = 0;
25033 shp->shm_ctim = get_seconds();
25034+#ifdef CONFIG_GRKERNSEC
25035+ shp->shm_createtime = get_seconds();
25036+#endif
25037 shp->shm_segsz = size;
25038 shp->shm_nattch = 0;
25039 shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
25040@@ -385,6 +410,8 @@ asmlinkage long sys_shmget (key_t key, s
25041 }
25042 mutex_unlock(&shm_ids(ns).mutex);
25043
25044+ gr_log_shmget(err, shmflg, size);
25045+
25046 return err;
25047 }
25048
25049@@ -842,9 +869,27 @@ long do_shmat(int shmid, char __user *sh
25050 return err;
25051 }
25052
25053+#ifdef CONFIG_GRKERNSEC
25054+ if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
25055+ shp->shm_perm.cuid, shmid)) {
25056+ shm_unlock(shp);
25057+ return -EACCES;
25058+ }
25059+
25060+ if (!gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
25061+ shm_unlock(shp);
25062+ return -EACCES;
25063+ }
25064+#endif
25065+
25066 file = shp->shm_file;
25067 size = i_size_read(file->f_dentry->d_inode);
25068 shp->shm_nattch++;
25069+
25070+#ifdef CONFIG_GRKERNSEC
25071+ shp->shm_lapid = current->pid;
25072+#endif
25073+
25074 shm_unlock(shp);
25075
25076 down_write(&current->mm->mmap_sem);
25077@@ -1014,3 +1059,27 @@ static int sysvipc_shm_proc_show(struct
25078 shp->shm_ctim);
25079 }
25080 #endif
25081+
25082+void gr_shm_exit(struct task_struct *task)
25083+{
25084+#ifdef CONFIG_GRKERNSEC_SHM
25085+ int i;
25086+ struct shmid_kernel *shp;
25087+ struct ipc_namespace *ns;
25088+
25089+ ns = current->nsproxy->ipc_ns;
25090+
25091+ if (!grsec_enable_shm)
25092+ return;
25093+
25094+ for (i = 0; i <= shm_ids(ns).max_id; i++) {
25095+ shp = shm_get(ns, i);
25096+ if (shp && (shp->shm_cprid == task->pid) &&
25097+ (shp->shm_nattch <= 0)) {
25098+ shp->shm_perm.mode |= SHM_DEST;
25099+ shm_destroy(ns, shp);
25100+ }
25101+ }
25102+#endif
25103+ return;
25104+}
25105diff -urNp linux-2.6.19.1/kernel/acct.c linux-2.6.19.1/kernel/acct.c
25106--- linux-2.6.19.1/kernel/acct.c 2006-11-29 16:57:37.000000000 -0500
25107+++ linux-2.6.19.1/kernel/acct.c 2006-12-03 15:16:26.000000000 -0500
25108@@ -516,7 +516,7 @@ static void do_acct_process(struct file
25109 */
25110 flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
25111 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
25112- file->f_op->write(file, (char *)&ac,
25113+ file->f_op->write(file, (char __user *)&ac,
25114 sizeof(acct_t), &file->f_pos);
25115 current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
25116 set_fs(fs);
25117diff -urNp linux-2.6.19.1/kernel/capability.c linux-2.6.19.1/kernel/capability.c
25118--- linux-2.6.19.1/kernel/capability.c 2006-11-29 16:57:37.000000000 -0500
25119+++ linux-2.6.19.1/kernel/capability.c 2006-12-03 15:16:26.000000000 -0500
25120@@ -12,6 +12,7 @@
c3e8c1b5 25121 #include <linux/security.h>
25122 #include <linux/syscalls.h>
9bdf255b 25123 #include <linux/vs_context.h>
c3e8c1b5 25124+#include <linux/grsecurity.h>
25125 #include <asm/uaccess.h>
25126
25127 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
25128@@ -234,14 +235,25 @@ out:
25129 return ret;
25130 }
25131
25132+extern int gr_task_is_capable(struct task_struct *task, const int cap);
25133+extern int gr_is_capable_nolog(const int cap);
25134+
25135 int __capable(struct task_struct *t, int cap)
25136 {
25137- if (security_capable(t, cap) == 0) {
25138+ if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
25139 t->flags |= PF_SUPERPRIV;
25140 return 1;
25141 }
25142 return 0;
25143 }
25144+int capable_nolog(int cap)
25145+{
25146+ if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
25147+ current->flags |= PF_SUPERPRIV;
25148+ return 1;
25149+ }
25150+ return 0;
25151+}
25152 EXPORT_SYMBOL(__capable);
25153
25154 int capable(int cap)
25155@@ -249,3 +261,4 @@ int capable(int cap)
25156 return __capable(current, cap);
25157 }
25158 EXPORT_SYMBOL(capable);
25159+EXPORT_SYMBOL(capable_nolog);
25160diff -urNp linux-2.6.19.1/kernel/configs.c linux-2.6.19.1/kernel/configs.c
25161--- linux-2.6.19.1/kernel/configs.c 2006-11-29 16:57:37.000000000 -0500
25162+++ linux-2.6.19.1/kernel/configs.c 2006-12-03 15:16:26.000000000 -0500
25163@@ -88,8 +88,16 @@ static int __init ikconfig_init(void)
25164 struct proc_dir_entry *entry;
25165
25166 /* create the current config file */
25167+#ifdef CONFIG_GRKERNSEC_PROC_ADD
25168+#ifdef CONFIG_GRKERNSEC_PROC_USER
25169+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
25170+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
25171+ entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
25172+#endif
25173+#else
25174 entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
25175 &proc_root);
25176+#endif
25177 if (!entry)
25178 return -ENOMEM;
25179
25180diff -urNp linux-2.6.19.1/kernel/exit.c linux-2.6.19.1/kernel/exit.c
25181--- linux-2.6.19.1/kernel/exit.c 2006-11-29 16:57:37.000000000 -0500
25182+++ linux-2.6.19.1/kernel/exit.c 2006-12-03 15:16:26.000000000 -0500
25183@@ -41,6 +41,11 @@
9bdf255b 25184 #include <linux/vs_limit.h>
25185 #include <linux/vs_context.h>
25186 #include <linux/vs_network.h>
c3e8c1b5 25187+#include <linux/grsecurity.h>
25188+
25189+#ifdef CONFIG_GRKERNSEC
25190+extern rwlock_t grsec_exec_file_lock;
25191+#endif
25192
25193 #include <asm/uaccess.h>
25194 #include <asm/unistd.h>
25195@@ -118,6 +123,7 @@ static void __exit_signal(struct task_st
25196
25197 __unhash_process(tsk);
25198
25199+ gr_del_task_from_ip_table(tsk);
25200 tsk->signal = NULL;
25201 tsk->sighand = NULL;
25202 spin_unlock(&sighand->siglock);
25203@@ -275,6 +281,15 @@ static void reparent_to_init(void)
25204 {
25205 write_lock_irq(&tasklist_lock);
25206
25207+#ifdef CONFIG_GRKERNSEC
25208+ write_lock(&grsec_exec_file_lock);
25209+ if (current->exec_file) {
25210+ fput(current->exec_file);
25211+ current->exec_file = NULL;
25212+ }
25213+ write_unlock(&grsec_exec_file_lock);
25214+#endif
25215+
25216 ptrace_unlink(current);
25217 /* Reparent to init */
25218 remove_parent(current);
25219@@ -282,6 +297,8 @@ static void reparent_to_init(void)
25220 current->real_parent = child_reaper;
25221 add_parent(current);
25222
25223+ gr_set_kernel_label(current);
25224+
25225 /* Set the exit signal to SIGCHLD so we signal init on exit */
25226 current->exit_signal = SIGCHLD;
25227
25228@@ -376,6 +393,17 @@ void daemonize(const char *name, ...)
25229 vsnprintf(current->comm, sizeof(current->comm), name, args);
25230 va_end(args);
25231
25232+#ifdef CONFIG_GRKERNSEC
25233+ write_lock(&grsec_exec_file_lock);
25234+ if (current->exec_file) {
25235+ fput(current->exec_file);
25236+ current->exec_file = NULL;
25237+ }
25238+ write_unlock(&grsec_exec_file_lock);
25239+#endif
25240+
25241+ gr_set_kernel_label(current);
25242+
25243 /*
25244 * If we were started as result of loading a module, close all of the
25245 * user space pages. We don't need them, and if we didn't close them
25246@@ -914,11 +942,15 @@ fastcall NORET_TYPE void do_exit(long co
25247 taskstats_exit_send(tsk, tidstats, group_dead, mycpu);
25248 taskstats_exit_free(tidstats);
25249
25250+ gr_acl_handle_psacct(tsk, code);
25251+ gr_acl_handle_exit();
25252+
25253 exit_mm(tsk);
25254
25255 if (group_dead)
25256 acct_process();
25257 exit_sem(tsk);
25258+ gr_shm_exit(tsk);
25259 __exit_files(tsk);
25260 __exit_fs(tsk);
25261 exit_thread();
25262diff -urNp linux-2.6.19.1/kernel/fork.c linux-2.6.19.1/kernel/fork.c
25263--- linux-2.6.19.1/kernel/fork.c 2006-11-29 16:57:37.000000000 -0500
25264+++ linux-2.6.19.1/kernel/fork.c 2006-12-03 15:16:26.000000000 -0500
25265@@ -48,6 +48,7 @@
9bdf255b 25266 #include <linux/vs_network.h>
25267 #include <linux/vs_limit.h>
25268 #include <linux/vs_memory.h>
c3e8c1b5 25269+#include <linux/grsecurity.h>
25270
25271 #include <asm/pgtable.h>
25272 #include <asm/pgalloc.h>
25273@@ -179,7 +180,7 @@ static struct task_struct *dup_task_stru
25274 setup_thread_stack(tsk, orig);
25275
25276 #ifdef CONFIG_CC_STACKPROTECTOR
25277- tsk->stack_canary = get_random_int();
25278+ tsk->stack_canary = pax_get_random_long();
25279 #endif
25280
25281 /* One for us, one for whoever does the "release_task()" (usually parent) */
25282@@ -211,8 +212,8 @@ static inline int dup_mmap(struct mm_str
25283 mm->locked_vm = 0;
25284 mm->mmap = NULL;
25285 mm->mmap_cache = NULL;
25286- mm->free_area_cache = oldmm->mmap_base;
25287- mm->cached_hole_size = ~0UL;
25288+ mm->free_area_cache = oldmm->free_area_cache;
25289+ mm->cached_hole_size = oldmm->cached_hole_size;
25290 mm->map_count = 0;
25291 cpus_clear(mm->cpu_vm_mask);
25292 mm->mm_rb = RB_ROOT;
25293@@ -337,7 +338,7 @@ static struct mm_struct * mm_init(struct
25294 spin_lock_init(&mm->page_table_lock);
25295 rwlock_init(&mm->ioctx_list_lock);
25296 mm->ioctx_list = NULL;
25297- mm->free_area_cache = TASK_UNMAPPED_BASE;
25298+ mm->free_area_cache = ~0UL;
25299 mm->cached_hole_size = ~0UL;
25300
25301 if (likely(!mm_alloc_pgd(mm))) {
25302@@ -990,6 +991,9 @@ static struct task_struct *copy_process(
9bdf255b 25303 if (!vx_nproc_avail(1))
25304 goto bad_fork_cleanup_vm;
25305
c3e8c1b5 25306+
25307+ gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
25308+
25309 if (atomic_read(&p->user->processes) >=
25310 p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
25311 if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) &&
25312@@ -1122,6 +1126,8 @@ static struct task_struct *copy_process(
25313 if (retval)
25314 goto bad_fork_cleanup_namespaces;
25315
25316+ gr_copy_label(p);
25317+
25318 p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
25319 /*
25320 * Clear TID on mm_release()?
25321@@ -1300,6 +1306,8 @@ bad_fork_cleanup_count:
25322 bad_fork_free:
25323 free_task(p);
25324 fork_out:
25325+ gr_log_forkfail(retval);
25326+
25327 return ERR_PTR(retval);
25328 }
25329
25330@@ -1372,6 +1380,8 @@ long do_fork(unsigned long clone_flags,
25331 if (!IS_ERR(p)) {
25332 struct completion vfork;
25333
25334+ gr_handle_brute_check();
25335+
25336 if (clone_flags & CLONE_VFORK) {
25337 p->vfork_done = &vfork;
25338 init_completion(&vfork);
25339diff -urNp linux-2.6.19.1/kernel/futex.c linux-2.6.19.1/kernel/futex.c
25340--- linux-2.6.19.1/kernel/futex.c 2006-11-29 16:57:37.000000000 -0500
25341+++ linux-2.6.19.1/kernel/futex.c 2006-12-03 15:16:26.000000000 -0500
25342@@ -183,6 +183,11 @@ static int get_futex_key(u32 __user *uad
25343 struct page *page;
25344 int err;
25345
25346+#ifdef CONFIG_PAX_SEGMEXEC
25347+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
25348+ return -EFAULT;
25349+#endif
25350+
25351 /*
25352 * The futex address must be "naturally" aligned.
25353 */
25354diff -urNp linux-2.6.19.1/kernel/kallsyms.c linux-2.6.19.1/kernel/kallsyms.c
25355--- linux-2.6.19.1/kernel/kallsyms.c 2006-11-29 16:57:37.000000000 -0500
25356+++ linux-2.6.19.1/kernel/kallsyms.c 2006-12-03 15:16:26.000000000 -0500
25357@@ -337,7 +337,6 @@ static unsigned long get_ksymbol_core(st
25358
25359 static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
25360 {
25361- iter->name[0] = '\0';
25362 iter->nameoff = get_symbol_offset(new_pos);
25363 iter->pos = new_pos;
25364 }
25365@@ -416,7 +415,7 @@ static int kallsyms_open(struct inode *i
25366 struct kallsym_iter *iter;
25367 int ret;
25368
25369- iter = kmalloc(sizeof(*iter), GFP_KERNEL);
25370+ iter = kzalloc(sizeof(*iter), GFP_KERNEL);
25371 if (!iter)
25372 return -ENOMEM;
25373 reset_iter(iter, 0);
25374@@ -447,7 +446,15 @@ static int __init kallsyms_init(void)
25375 {
25376 struct proc_dir_entry *entry;
25377
25378+#ifdef CONFIG_GRKERNSEC_PROC_ADD
25379+#ifdef CONFIG_GRKERNSEC_PROC_USER
25380+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
25381+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
25382+ entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
25383+#endif
25384+#else
25385 entry = create_proc_entry("kallsyms", 0444, NULL);
25386+#endif
25387 if (entry)
25388 entry->proc_fops = &kallsyms_operations;
25389 return 0;
25390diff -urNp linux-2.6.19.1/kernel/kprobes.c linux-2.6.19.1/kernel/kprobes.c
25391--- linux-2.6.19.1/kernel/kprobes.c 2006-11-29 16:57:37.000000000 -0500
25392+++ linux-2.6.19.1/kernel/kprobes.c 2006-12-03 15:16:26.000000000 -0500
25393@@ -123,7 +123,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
25394 * kernel image and loaded module images reside. This is required
25395 * so x86_64 can correctly handle the %rip-relative fixups.
25396 */
25397- kip->insns = module_alloc(PAGE_SIZE);
25398+ kip->insns = module_alloc_exec(PAGE_SIZE);
25399 if (!kip->insns) {
25400 kfree(kip);
25401 return NULL;
25402diff -urNp linux-2.6.19.1/kernel/module.c linux-2.6.19.1/kernel/module.c
25403--- linux-2.6.19.1/kernel/module.c 2006-11-29 16:57:37.000000000 -0500
25404+++ linux-2.6.19.1/kernel/module.c 2006-12-03 15:16:26.000000000 -0500
25405@@ -43,6 +43,11 @@
25406 #include <asm/uaccess.h>
25407 #include <asm/semaphore.h>
25408 #include <asm/cacheflush.h>
25409+
25410+#ifdef CONFIG_PAX_KERNEXEC
25411+#include <asm/desc.h>
25412+#endif
25413+
25414 #include <linux/license.h>
25415
25416 #if 0
25417@@ -67,6 +72,8 @@ static LIST_HEAD(modules);
25418
25419 static BLOCKING_NOTIFIER_HEAD(module_notify_list);
25420
25421+extern int gr_check_modstop(void);
25422+
25423 int register_module_notifier(struct notifier_block * nb)
25424 {
25425 return blocking_notifier_chain_register(&module_notify_list, nb);
25426@@ -656,6 +663,9 @@ sys_delete_module(const char __user *nam
25427 char name[MODULE_NAME_LEN];
25428 int ret, forced = 0;
25429
25430+ if (gr_check_modstop())
25431+ return -EPERM;
25432+
25433 if (!capable(CAP_SYS_MODULE))
25434 return -EPERM;
25435
25436@@ -1142,16 +1152,19 @@ static void free_module(struct module *m
25437 module_unload_free(mod);
25438
25439 /* This may be NULL, but that's OK */
25440- module_free(mod, mod->module_init);
25441+ module_free(mod, mod->module_init_rw);
25442+ module_free_exec(mod, mod->module_init_rx);
25443 kfree(mod->args);
25444 if (mod->percpu)
25445 percpu_modfree(mod->percpu);
25446
25447 /* Free lock-classes: */
25448- lockdep_free_key_range(mod->module_core, mod->core_size);
25449+ lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
25450+ lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
25451
25452 /* Finally, free the core (containing the module structure) */
25453- module_free(mod, mod->module_core);
25454+ module_free_exec(mod, mod->module_core_rx);
25455+ module_free(mod, mod->module_core_rw);
25456 }
25457
25458 void *__symbol_get(const char *symbol)
25459@@ -1308,11 +1321,14 @@ static void layout_sections(struct modul
25460 || strncmp(secstrings + s->sh_name,
25461 ".init", 5) == 0)
25462 continue;
25463- s->sh_entsize = get_offset(&mod->core_size, s);
25464+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
25465+ s->sh_entsize = get_offset(&mod->core_size_rw, s);
25466+ else
25467+ s->sh_entsize = get_offset(&mod->core_size_rx, s);
25468 DEBUGP("\t%s\n", secstrings + s->sh_name);
25469 }
25470 if (m == 0)
25471- mod->core_text_size = mod->core_size;
25472+ mod->core_size_rx = mod->core_size_rx;
25473 }
25474
25475 DEBUGP("Init section allocation order:\n");
25476@@ -1326,12 +1342,15 @@ static void layout_sections(struct modul
25477 || strncmp(secstrings + s->sh_name,
25478 ".init", 5) != 0)
25479 continue;
25480- s->sh_entsize = (get_offset(&mod->init_size, s)
25481- | INIT_OFFSET_MASK);
25482+ if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
25483+ s->sh_entsize = get_offset(&mod->init_size_rw, s);
25484+ else
25485+ s->sh_entsize = get_offset(&mod->init_size_rx, s);
25486+ s->sh_entsize |= INIT_OFFSET_MASK;
25487 DEBUGP("\t%s\n", secstrings + s->sh_name);
25488 }
25489 if (m == 0)
25490- mod->init_text_size = mod->init_size;
25491+ mod->init_size_rx = mod->init_size_rx;
25492 }
25493 }
25494
25495@@ -1513,6 +1532,10 @@ static struct module *load_module(void _
25496 struct exception_table_entry *extable;
25497 mm_segment_t old_fs;
25498
25499+#ifdef CONFIG_PAX_KERNEXEC
25500+ unsigned long cr0;
25501+#endif
25502+
25503 DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
25504 umod, len, uargs);
25505 if (len < sizeof(*hdr))
25506@@ -1671,21 +1694,57 @@ static struct module *load_module(void _
25507 layout_sections(mod, hdr, sechdrs, secstrings);
25508
25509 /* Do the allocs. */
25510- ptr = module_alloc(mod->core_size);
25511+ ptr = module_alloc(mod->core_size_rw);
25512 if (!ptr) {
25513 err = -ENOMEM;
25514 goto free_percpu;
25515 }
25516- memset(ptr, 0, mod->core_size);
25517- mod->module_core = ptr;
25518+ memset(ptr, 0, mod->core_size_rw);
25519+ mod->module_core_rw = ptr;
25520+
25521+ ptr = module_alloc(mod->init_size_rw);
25522+ if (!ptr && mod->init_size_rw) {
25523+ err = -ENOMEM;
25524+ goto free_core_rw;
25525+ }
25526+ memset(ptr, 0, mod->init_size_rw);
25527+ mod->module_init_rw = ptr;
25528+
25529+ ptr = module_alloc_exec(mod->core_size_rx);
25530+ if (!ptr) {
25531+ err = -ENOMEM;
25532+ goto free_init_rw;
25533+ }
25534
25535- ptr = module_alloc(mod->init_size);
25536- if (!ptr && mod->init_size) {
25537+#ifdef CONFIG_PAX_KERNEXEC
25538+ pax_open_kernel(cr0);
25539+#endif
25540+
25541+ memset(ptr, 0, mod->core_size_rx);
25542+
25543+#ifdef CONFIG_PAX_KERNEXEC
25544+ pax_close_kernel(cr0);
25545+#endif
25546+
25547+ mod->module_core_rx = ptr;
25548+
25549+ ptr = module_alloc_exec(mod->init_size_rx);
25550+ if (!ptr && mod->init_size_rx) {
25551 err = -ENOMEM;
25552- goto free_core;
25553+ goto free_core_rx;
25554 }
25555- memset(ptr, 0, mod->init_size);
25556- mod->module_init = ptr;
25557+
25558+#ifdef CONFIG_PAX_KERNEXEC
25559+ pax_open_kernel(cr0);
25560+#endif
25561+
25562+ memset(ptr, 0, mod->init_size_rx);
25563+
25564+#ifdef CONFIG_PAX_KERNEXEC
25565+ pax_close_kernel(cr0);
25566+#endif
25567+
25568+ mod->module_init_rx = ptr;
25569
25570 /* Transfer each section which specifies SHF_ALLOC */
25571 DEBUGP("final section addresses:\n");
25572@@ -1695,17 +1754,44 @@ static struct module *load_module(void _
25573 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
25574 continue;
25575
25576- if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
25577- dest = mod->module_init
25578- + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
25579- else
25580- dest = mod->module_core + sechdrs[i].sh_entsize;
25581+ if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
25582+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
25583+ dest = mod->module_init_rw
25584+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
25585+ else
25586+ dest = mod->module_init_rx
25587+ + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
25588+ } else {
25589+ if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
25590+ dest = mod->module_core_rw + sechdrs[i].sh_entsize;
25591+ else
25592+ dest = mod->module_core_rx + sechdrs[i].sh_entsize;
25593+ }
25594+
25595+ if (sechdrs[i].sh_type != SHT_NOBITS) {
25596
25597- if (sechdrs[i].sh_type != SHT_NOBITS)
25598- memcpy(dest, (void *)sechdrs[i].sh_addr,
25599- sechdrs[i].sh_size);
25600+#ifdef CONFIG_PAX_KERNEXEC
25601+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
25602+ pax_open_kernel(cr0);
25603+#endif
25604+
25605+ memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
25606+
25607+#ifdef CONFIG_PAX_KERNEXEC
25608+ if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
25609+ pax_close_kernel(cr0);
25610+#endif
25611+
25612+ }
25613 /* Update sh_addr to point to copy in image. */
25614- sechdrs[i].sh_addr = (unsigned long)dest;
25615+
25616+#ifdef CONFIG_PAX_KERNEXEC
25617+ if (sechdrs[i].sh_flags & SHF_EXECINSTR)
25618+ sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
25619+ else
25620+#endif
25621+
25622+ sechdrs[i].sh_addr = (unsigned long)dest;
25623 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
25624 }
25625 /* Module has been moved. */
25626@@ -1726,8 +1812,18 @@ static struct module *load_module(void _
25627 setup_modinfo(mod, sechdrs, infoindex);
25628
25629 /* Fix up syms, so that st_value is a pointer to location. */
25630+
25631+#ifdef CONFIG_PAX_KERNEXEC
25632+ pax_open_kernel(cr0);
25633+#endif
25634+
25635 err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
25636 mod);
25637+
25638+#ifdef CONFIG_PAX_KERNEXEC
25639+ pax_close_kernel(cr0);
25640+#endif
25641+
25642 if (err < 0)
25643 goto cleanup;
25644
25645@@ -1782,11 +1878,20 @@ static struct module *load_module(void _
25646 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
25647 continue;
25648
25649+#ifdef CONFIG_PAX_KERNEXEC
25650+ pax_open_kernel(cr0);
25651+#endif
25652+
25653 if (sechdrs[i].sh_type == SHT_REL)
25654 err = apply_relocate(sechdrs, strtab, symindex, i,mod);
25655 else if (sechdrs[i].sh_type == SHT_RELA)
25656 err = apply_relocate_add(sechdrs, strtab, symindex, i,
25657 mod);
25658+
25659+#ifdef CONFIG_PAX_KERNEXEC
25660+ pax_close_kernel(cr0);
25661+#endif
25662+
25663 if (err < 0)
25664 goto cleanup;
25665 }
25666@@ -1800,14 +1905,31 @@ static struct module *load_module(void _
25667 /* Set up and sort exception table */
25668 mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
25669 mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
25670+
25671+#ifdef CONFIG_PAX_KERNEXEC
25672+ pax_open_kernel(cr0);
25673+#endif
25674+
25675 sort_extable(extable, extable + mod->num_exentries);
25676
25677+#ifdef CONFIG_PAX_KERNEXEC
25678+ pax_close_kernel(cr0);
25679+#endif
25680+
25681 /* Finally, copy percpu area over. */
25682 percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
25683 sechdrs[pcpuindex].sh_size);
25684
25685+#ifdef CONFIG_PAX_KERNEXEC
25686+ pax_open_kernel(cr0);
25687+#endif
25688+
25689 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
25690
25691+#ifdef CONFIG_PAX_KERNEXEC
25692+ pax_close_kernel(cr0);
25693+#endif
25694+
25695 err = module_finalize(hdr, sechdrs, mod);
25696 if (err < 0)
25697 goto cleanup;
25698@@ -1821,12 +1943,12 @@ static struct module *load_module(void _
25699 * Do it before processing of module parameters, so the module
25700 * can provide parameter accessor functions of its own.
25701 */
25702- if (mod->module_init)
25703- flush_icache_range((unsigned long)mod->module_init,
25704- (unsigned long)mod->module_init
25705- + mod->init_size);
25706- flush_icache_range((unsigned long)mod->module_core,
25707- (unsigned long)mod->module_core + mod->core_size);
25708+ if (mod->module_init_rx)
25709+ flush_icache_range((unsigned long)mod->module_init_rx,
25710+ (unsigned long)mod->module_init_rx
25711+ + mod->init_size_rx);
25712+ flush_icache_range((unsigned long)mod->module_core_rx,
25713+ (unsigned long)mod->module_core_rx + mod->core_size_rx);
25714
25715 set_fs(old_fs);
25716
25717@@ -1869,9 +1991,13 @@ static struct module *load_module(void _
25718 module_arch_cleanup(mod);
25719 cleanup:
25720 module_unload_free(mod);
25721- module_free(mod, mod->module_init);
25722- free_core:
25723- module_free(mod, mod->module_core);
25724+ module_free_exec(mod, mod->module_init_rx);
25725+ free_core_rx:
25726+ module_free_exec(mod, mod->module_core_rx);
25727+ free_init_rw:
25728+ module_free(mod, mod->module_init_rw);
25729+ free_core_rw:
25730+ module_free(mod, mod->module_core_rw);
25731 free_percpu:
25732 if (percpu)
25733 percpu_modfree(percpu);
25734@@ -1907,6 +2033,9 @@ sys_init_module(void __user *umod,
25735 struct module *mod;
25736 int ret = 0;
25737
25738+ if (gr_check_modstop())
25739+ return -EPERM;
25740+
25741 /* Must have permission */
25742 if (!capable(CAP_SYS_MODULE))
25743 return -EPERM;
25744@@ -1958,10 +2087,12 @@ sys_init_module(void __user *umod,
25745 /* Drop initial reference. */
25746 module_put(mod);
25747 unwind_remove_table(mod->unwind_info, 1);
25748- module_free(mod, mod->module_init);
25749- mod->module_init = NULL;
25750- mod->init_size = 0;
25751- mod->init_text_size = 0;
25752+ module_free(mod, mod->module_init_rw);
25753+ module_free_exec(mod, mod->module_init_rx);
25754+ mod->module_init_rw = NULL;
25755+ mod->module_init_rx = NULL;
25756+ mod->init_size_rw = 0;
25757+ mod->init_size_rx = 0;
25758 mutex_unlock(&module_mutex);
25759
25760 return 0;
25761@@ -1992,10 +2123,14 @@ static const char *get_ksymbol(struct mo
25762 unsigned long nextval;
25763
25764 /* At worse, next value is at end of module */
25765- if (within(addr, mod->module_init, mod->init_size))
25766- nextval = (unsigned long)mod->module_init+mod->init_text_size;
25767- else
25768- nextval = (unsigned long)mod->module_core+mod->core_text_size;
25769+ if (within(addr, mod->module_init_rx, mod->init_size_rx))
25770+ nextval = (unsigned long)mod->module_init_rw;
25771+ else if (within(addr, mod->module_init_rw, mod->init_size_rw))
25772+ nextval = (unsigned long)mod->module_core_rx;
25773+ else if (within(addr, mod->module_core_rx, mod->core_size_rx))
25774+ nextval = (unsigned long)mod->module_core_rw;
25775+ else
25776+ nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
25777
25778 /* Scan for closest preceeding symbol, and next symbol. (ELF
25779 starts real symbols at 1). */
25780@@ -2036,8 +2171,10 @@ const char *module_address_lookup(unsign
25781 struct module *mod;
25782
25783 list_for_each_entry(mod, &modules, list) {
25784- if (within(addr, mod->module_init, mod->init_size)
25785- || within(addr, mod->module_core, mod->core_size)) {
25786+ if (within(addr, mod->module_init_rx, mod->init_size_rx)
25787+ || within(addr, mod->module_init_rw, mod->init_size_rw)
25788+ || within(addr, mod->module_core_rx, mod->core_size_rx)
25789+ || within(addr, mod->module_core_rw, mod->core_size_rw)) {
25790 if (modname)
25791 *modname = mod->name;
25792 return get_ksymbol(mod, addr, size, offset);
25793@@ -2158,7 +2295,7 @@ static int m_show(struct seq_file *m, vo
25794 char buf[8];
25795
25796 seq_printf(m, "%s %lu",
25797- mod->name, mod->init_size + mod->core_size);
25798+ mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
25799 print_unload_info(m, mod);
25800
25801 /* Informative for users. */
25802@@ -2167,7 +2304,7 @@ static int m_show(struct seq_file *m, vo
25803 mod->state == MODULE_STATE_COMING ? "Loading":
25804 "Live");
25805 /* Used by oprofile and other similar tools. */
25806- seq_printf(m, " 0x%p", mod->module_core);
25807+ seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
25808
25809 /* Taints info */
25810 if (mod->taints)
25811@@ -2225,7 +2362,8 @@ int is_module_address(unsigned long addr
25812 spin_lock_irqsave(&modlist_lock, flags);
25813
25814 list_for_each_entry(mod, &modules, list) {
25815- if (within(addr, mod->module_core, mod->core_size)) {
25816+ if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
25817+ within(addr, mod->module_core_rw, mod->core_size_rw)) {
25818 spin_unlock_irqrestore(&modlist_lock, flags);
25819 return 1;
25820 }
25821@@ -2243,8 +2381,8 @@ struct module *__module_text_address(uns
25822 struct module *mod;
25823
25824 list_for_each_entry(mod, &modules, list)
25825- if (within(addr, mod->module_init, mod->init_text_size)
25826- || within(addr, mod->module_core, mod->core_text_size))
25827+ if (within(addr, mod->module_init_rx, mod->init_size_rx)
25828+ || within(addr, mod->module_core_rx, mod->core_size_rx))
25829 return mod;
25830 return NULL;
25831 }
25832diff -urNp linux-2.6.19.1/kernel/mutex.c linux-2.6.19.1/kernel/mutex.c
25833--- linux-2.6.19.1/kernel/mutex.c 2006-11-29 16:57:37.000000000 -0500
25834+++ linux-2.6.19.1/kernel/mutex.c 2006-12-03 15:16:26.000000000 -0500
25835@@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
25836 *
25837 * This function is similar to (but not equivalent to) down().
25838 */
25839-void inline fastcall __sched mutex_lock(struct mutex *lock)
25840+inline void fastcall __sched mutex_lock(struct mutex *lock)
25841 {
25842 might_sleep();
25843 /*
25844diff -urNp linux-2.6.19.1/kernel/pid.c linux-2.6.19.1/kernel/pid.c
25845--- linux-2.6.19.1/kernel/pid.c 2006-11-29 16:57:37.000000000 -0500
25846+++ linux-2.6.19.1/kernel/pid.c 2006-12-03 15:16:26.000000000 -0500
25847@@ -27,6 +27,7 @@
c3e8c1b5 25848 #include <linux/hash.h>
25849 #include <linux/pspace.h>
9bdf255b 25850 #include <linux/vs_pid.h>
c3e8c1b5 25851+#include <linux/grsecurity.h>
25852
25853 #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
25854 static struct hlist_head *pid_hash;
25855@@ -35,7 +36,7 @@ static kmem_cache_t *pid_cachep;
25856
25857 int pid_max = PID_MAX_DEFAULT;
25858
25859-#define RESERVED_PIDS 300
25860+#define RESERVED_PIDS 500
25861
25862 int pid_max_min = RESERVED_PIDS + 1;
25863 int pid_max_max = PID_MAX_LIMIT;
25864@@ -94,7 +95,9 @@ static int alloc_pidmap(struct pspace *p
25865 int i, offset, max_scan, pid, last = pspace->last_pid;
25866 struct pidmap *map;
25867
25868- pid = last + 1;
25869+ pid = gr_random_pid();
25870+ if (!pid)
25871+ pid = pspace->last_pid + 1;
25872 if (pid >= pid_max)
25873 pid = RESERVED_PIDS;
25874 offset = pid & BITS_PER_PAGE_MASK;
9bdf255b 25875@@ -299,11 +302,18 @@ struct task_struct * fastcall pid_task(s
c3e8c1b5 25876 */
25877 struct task_struct *find_task_by_pid_type(int type, int nr)
25878 {
9bdf255b 25879+ struct task_struct *task;
25880+
25881 if (type == PIDTYPE_PID)
25882 nr = vx_rmap_pid(nr);
25883 else if (type == PIDTYPE_REALPID)
25884 type = PIDTYPE_PID;
c3e8c1b5 25885- return pid_task(find_pid(nr), type);
c3e8c1b5 25886+ task = pid_task(find_pid(nr), type);
25887+
25888+ if (gr_pid_is_chrooted(task))
25889+ return NULL;
25890+
25891+ return task;
25892 }
25893
25894 EXPORT_SYMBOL(find_task_by_pid_type);
25895@@ -318,6 +328,8 @@ struct task_struct *fastcall get_pid_tas
25896 struct task_struct *result;
25897 rcu_read_lock();
25898 result = pid_task(pid, type);
25899+ if (gr_pid_is_chrooted(result))
25900+ result = NULL;
25901 if (result)
25902 get_task_struct(result);
25903 rcu_read_unlock();
25904diff -urNp linux-2.6.19.1/kernel/posix-cpu-timers.c linux-2.6.19.1/kernel/posix-cpu-timers.c
25905--- linux-2.6.19.1/kernel/posix-cpu-timers.c 2006-11-29 16:57:37.000000000 -0500
25906+++ linux-2.6.19.1/kernel/posix-cpu-timers.c 2006-12-03 15:16:26.000000000 -0500
25907@@ -6,6 +6,7 @@
25908 #include <linux/posix-timers.h>
25909 #include <asm/uaccess.h>
25910 #include <linux/errno.h>
25911+#include <linux/grsecurity.h>
25912
25913 static int check_clock(const clockid_t which_clock)
25914 {
25915@@ -1139,6 +1140,7 @@ static void check_process_timers(struct
25916 __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
25917 return;
25918 }
25919+ gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
25920 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
25921 /*
25922 * At the soft limit, send a SIGXCPU every second.
25923diff -urNp linux-2.6.19.1/kernel/power/poweroff.c linux-2.6.19.1/kernel/power/poweroff.c
25924--- linux-2.6.19.1/kernel/power/poweroff.c 2006-11-29 16:57:37.000000000 -0500
25925+++ linux-2.6.19.1/kernel/power/poweroff.c 2006-12-10 21:43:36.000000000 -0500
25926@@ -35,7 +35,7 @@ static struct sysrq_key_op sysrq_powerof
25927 .enable_mask = SYSRQ_ENABLE_BOOT,
25928 };
25929
25930-static int pm_sysrq_init(void)
25931+static int __init pm_sysrq_init(void)
25932 {
25933 register_sysrq_key('o', &sysrq_poweroff_op);
25934 return 0;
25935diff -urNp linux-2.6.19.1/kernel/printk.c linux-2.6.19.1/kernel/printk.c
25936--- linux-2.6.19.1/kernel/printk.c 2006-11-29 16:57:37.000000000 -0500
25937+++ linux-2.6.19.1/kernel/printk.c 2006-12-03 15:16:26.000000000 -0500
25938@@ -32,6 +32,7 @@
c3e8c1b5 25939 #include <linux/syscalls.h>
25940 #include <linux/jiffies.h>
9bdf255b 25941 #include <linux/vs_cvirt.h>
c3e8c1b5 25942+#include <linux/grsecurity.h>
25943
25944 #include <asm/uaccess.h>
25945
25946@@ -187,6 +188,11 @@ int do_syslog(int type, char __user *buf
25947 char c;
25948 int error = 0;
25949
25950+#ifdef CONFIG_GRKERNSEC_DMESG
25951+ if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
25952+ return -EPERM;
25953+#endif
25954+
25955 error = security_syslog(type);
25956 if (error)
25957 return error;
25958diff -urNp linux-2.6.19.1/kernel/ptrace.c linux-2.6.19.1/kernel/ptrace.c
25959--- linux-2.6.19.1/kernel/ptrace.c 2006-11-29 16:57:37.000000000 -0500
25960+++ linux-2.6.19.1/kernel/ptrace.c 2006-12-03 15:16:26.000000000 -0500
25961@@ -18,6 +18,7 @@
c3e8c1b5 25962 #include <linux/security.h>
25963 #include <linux/signal.h>
9bdf255b 25964 #include <linux/vs_context.h>
c3e8c1b5 25965+#include <linux/grsecurity.h>
25966
25967 #include <asm/pgtable.h>
25968 #include <asm/uaccess.h>
25969@@ -137,12 +138,12 @@ static int may_attach(struct task_struct
25970 (current->uid != task->uid) ||
25971 (current->gid != task->egid) ||
25972 (current->gid != task->sgid) ||
25973- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
25974+ (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
25975 return -EPERM;
25976 smp_rmb();
25977 if (task->mm)
25978 dumpable = task->mm->dumpable;
25979- if (!dumpable && !capable(CAP_SYS_PTRACE))
25980+ if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
25981 return -EPERM;
25982
25983 return security_ptrace(current, task);
25984@@ -477,6 +478,11 @@ asmlinkage long sys_ptrace(long request,
25985 if (ret < 0)
25986 goto out_put_task_struct;
25987
25988+ if (gr_handle_ptrace(child, request)) {
25989+ ret = -EPERM;
25990+ goto out_put_task_struct;
25991+ }
25992+
25993 ret = arch_ptrace(child, request, addr, data);
25994 if (ret < 0)
25995 goto out_put_task_struct;
25996diff -urNp linux-2.6.19.1/kernel/resource.c linux-2.6.19.1/kernel/resource.c
25997--- linux-2.6.19.1/kernel/resource.c 2006-11-29 16:57:37.000000000 -0500
25998+++ linux-2.6.19.1/kernel/resource.c 2006-12-03 15:16:26.000000000 -0500
25999@@ -133,10 +133,27 @@ static int __init ioresources_init(void)
26000 {
26001 struct proc_dir_entry *entry;
26002
26003+#ifdef CONFIG_GRKERNSEC_PROC_ADD
26004+#ifdef CONFIG_GRKERNSEC_PROC_USER
26005+ entry = create_proc_entry("ioports", S_IRUSR, NULL);
26006+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
26007+ entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
26008+#endif
26009+#else
26010 entry = create_proc_entry("ioports", 0, NULL);
26011+#endif
26012 if (entry)
26013 entry->proc_fops = &proc_ioports_operations;
26014+
26015+#ifdef CONFIG_GRKERNSEC_PROC_ADD
26016+#ifdef CONFIG_GRKERNSEC_PROC_USER
26017+ entry = create_proc_entry("iomem", S_IRUSR, NULL);
26018+#elif CONFIG_GRKERNSEC_PROC_USERGROUP
26019+ entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
26020+#endif
26021+#else
26022 entry = create_proc_entry("iomem", 0, NULL);
26023+#endif
26024 if (entry)
26025 entry->proc_fops = &proc_iomem_operations;
26026 return 0;
26027diff -urNp linux-2.6.19.1/kernel/sched.c linux-2.6.19.1/kernel/sched.c
26028--- linux-2.6.19.1/kernel/sched.c 2006-11-29 16:57:37.000000000 -0500
26029+++ linux-2.6.19.1/kernel/sched.c 2006-12-03 15:16:26.000000000 -0500
26030@@ -52,6 +52,7 @@
26031 #include <linux/tsacct_kern.h>
26032 #include <linux/kprobes.h>
26033 #include <linux/delayacct.h>
26034+#include <linux/grsecurity.h>
26035 #include <asm/tlb.h>
26036
26037 #include <asm/unistd.h>
26038@@ -4012,7 +4013,8 @@ asmlinkage long sys_nice(int increment)
26039 if (nice > 19)
26040 nice = 19;
26041
26042- if (increment < 0 && !can_nice(current, nice))
26043+ if (increment < 0 && (!can_nice(current, nice) ||
26044+ gr_handle_chroot_nice()))
9bdf255b 26045 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
c3e8c1b5 26046
26047 retval = security_task_setnice(current, nice);
26048diff -urNp linux-2.6.19.1/kernel/signal.c linux-2.6.19.1/kernel/signal.c
26049--- linux-2.6.19.1/kernel/signal.c 2006-11-29 16:57:37.000000000 -0500
26050+++ linux-2.6.19.1/kernel/signal.c 2006-12-03 15:16:26.000000000 -0500
26051@@ -23,6 +23,7 @@
c3e8c1b5 26052 #include <linux/capability.h>
9bdf255b 26053 #include <linux/vs_context.h>
26054 #include <linux/freezer.h>
c3e8c1b5 26055+#include <linux/grsecurity.h>
26056 #include <asm/param.h>
26057 #include <asm/uaccess.h>
26058 #include <asm/unistd.h>
9bdf255b 26059@@ -581,11 +582,11 @@ static int check_kill_permission(int sig
26060 goto skip;
26061
c3e8c1b5 26062 error = -EPERM;
9bdf255b 26063- if (((sig != SIGCONT) ||
26064+ if (((((sig != SIGCONT) ||
c3e8c1b5 26065 (current->signal->session != t->signal->session))
26066 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
26067 && (current->uid ^ t->suid) && (current->uid ^ t->uid)
26068- && !capable(CAP_KILL))
26069+ && !capable(CAP_KILL)) || gr_handle_signal(t, sig)))
26070 return error;
26071
9bdf255b 26072 error = -ESRCH;
26073@@ -604,8 +605,10 @@ static int check_kill_permission(int sig
26074 }
26075 skip:
c3e8c1b5 26076 error = security_task_kill(t, info, sig, 0);
26077- if (!error)
26078+ if (!error) {
26079 audit_signal_info(sig, t); /* Let audit system see the signal */
26080+ gr_log_signal(sig, t);
26081+ }
26082 return error;
26083 }
26084
26085@@ -768,7 +771,7 @@ out_set:
26086 (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
26087
26088
26089-static int
26090+int
26091 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
26092 {
26093 int ret = 0;
26094@@ -822,6 +825,10 @@ force_sig_info(int sig, struct siginfo *
26095 }
26096 }
26097 ret = specific_send_sig_info(sig, info, t);
26098+
26099+ gr_log_signal(sig, t);
26100+ gr_handle_crash(t, sig);
26101+
26102 spin_unlock_irqrestore(&t->sighand->siglock, flags);
26103
26104 return ret;
26105diff -urNp linux-2.6.19.1/kernel/sys.c linux-2.6.19.1/kernel/sys.c
26106--- linux-2.6.19.1/kernel/sys.c 2006-11-29 16:57:37.000000000 -0500
26107+++ linux-2.6.19.1/kernel/sys.c 2006-12-03 15:16:26.000000000 -0500
26108@@ -29,6 +29,7 @@
26109 #include <linux/signal.h>
26110 #include <linux/cn_proc.h>
26111 #include <linux/getcpu.h>
26112+#include <linux/grsecurity.h>
26113
26114 #include <linux/compat.h>
26115 #include <linux/syscalls.h>
26116@@ -572,6 +573,12 @@ static int set_one_prio(struct task_stru
26117 error = -EACCES;
26118 goto out;
26119 }
26120+
26121+ if (gr_handle_chroot_setpriority(p, niceval)) {
26122+ error = -EACCES;
26123+ goto out;
26124+ }
26125+
26126 no_nice = security_task_setnice(p, niceval);
26127 if (no_nice) {
26128 error = no_nice;
26129@@ -954,6 +961,9 @@ asmlinkage long sys_setregid(gid_t rgid,
26130 if (rgid != (gid_t) -1 ||
26131 (egid != (gid_t) -1 && egid != old_rgid))
26132 current->sgid = new_egid;
26133+
26134+ gr_set_role_label(current, current->uid, new_rgid);
26135+
26136 current->fsgid = new_egid;
26137 current->egid = new_egid;
26138 current->gid = new_rgid;
26139@@ -981,6 +991,9 @@ asmlinkage long sys_setgid(gid_t gid)
26140 current->mm->dumpable = suid_dumpable;
26141 smp_wmb();
26142 }
26143+
26144+ gr_set_role_label(current, current->uid, gid);
26145+
26146 current->gid = current->egid = current->sgid = current->fsgid = gid;
26147 } else if ((gid == current->gid) || (gid == current->sgid)) {
26148 if (old_egid != gid) {
26149@@ -1018,6 +1031,9 @@ static int set_user(uid_t new_ruid, int
26150 current->mm->dumpable = suid_dumpable;
26151 smp_wmb();
26152 }
26153+
26154+ gr_set_role_label(current, new_ruid, current->gid);
26155+
26156 current->uid = new_ruid;
26157 return 0;
26158 }
26159@@ -1120,6 +1136,9 @@ asmlinkage long sys_setuid(uid_t uid)
26160 } else if ((uid != current->uid) && (uid != new_suid))
26161 return -EPERM;
26162
26163+ if (gr_check_crash_uid(uid))
26164+ return -EPERM;
26165+
26166 if (old_euid != uid) {
26167 current->mm->dumpable = suid_dumpable;
26168 smp_wmb();
26169@@ -1222,8 +1241,10 @@ asmlinkage long sys_setresgid(gid_t rgid
26170 current->egid = egid;
26171 }
26172 current->fsgid = current->egid;
26173- if (rgid != (gid_t) -1)
26174+ if (rgid != (gid_t) -1) {
26175+ gr_set_role_label(current, current->uid, rgid);
26176 current->gid = rgid;
26177+ }
26178 if (sgid != (gid_t) -1)
26179 current->sgid = sgid;
26180
26181@@ -2086,7 +2107,7 @@ asmlinkage long sys_prctl(int option, un
26182 error = current->mm->dumpable;
26183 break;
26184 case PR_SET_DUMPABLE:
26185- if (arg2 < 0 || arg2 > 1) {
26186+ if (arg2 > 1) {
26187 error = -EINVAL;
26188 break;
26189 }
26190diff -urNp linux-2.6.19.1/kernel/sysctl.c linux-2.6.19.1/kernel/sysctl.c
26191--- linux-2.6.19.1/kernel/sysctl.c 2006-11-29 16:57:37.000000000 -0500
26192+++ linux-2.6.19.1/kernel/sysctl.c 2006-12-03 15:16:26.000000000 -0500
26193@@ -57,6 +57,14 @@ extern int proc_nr_files(ctl_table *tabl
26194 #endif
26195
26196 #if defined(CONFIG_SYSCTL)
26197+#include <linux/grsecurity.h>
26198+#include <linux/grinternal.h>
26199+
26200+extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
26201+ const void *newval);
26202+extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
26203+ const int op);
26204+extern int gr_handle_chroot_sysctl(const int op);
26205
26206 /* External variables not in a header file. */
26207 extern int C_A_D;
26208@@ -161,6 +169,22 @@ extern ctl_table inotify_table[];
26209 #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
26210 int sysctl_legacy_va_layout;
26211 #endif
26212+extern ctl_table grsecurity_table[];
26213+
26214+#ifdef CONFIG_PAX_SOFTMODE
26215+static ctl_table pax_table[] = {
26216+ {
26217+ .ctl_name = PAX_SOFTMODE,
26218+ .procname = "softmode",
26219+ .data = &pax_softmode,
26220+ .maxlen = sizeof(unsigned int),
26221+ .mode = 0600,
26222+ .proc_handler = &proc_dointvec,
26223+ },
26224+
26225+ { .ctl_name = 0 }
26226+};
26227+#endif
26228
26229 /* /proc declarations: */
26230
26231@@ -223,7 +247,6 @@ static ctl_table root_table[] = {
26232 .mode = 0555,
26233 .child = dev_table,
26234 },
26235-
26236 { .ctl_name = 0 }
26237 };
26238
26239@@ -769,6 +792,24 @@ static ctl_table kern_table[] = {
26240 },
26241 #endif
26242
26243+#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
26244+ {
26245+ .ctl_name = KERN_GRSECURITY,
26246+ .procname = "grsecurity",
26247+ .mode = 0500,
26248+ .child = grsecurity_table,
26249+ },
26250+#endif
26251+
26252+#ifdef CONFIG_PAX_SOFTMODE
26253+ {
26254+ .ctl_name = KERN_PAX,
26255+ .procname = "pax",
26256+ .mode = 0500,
26257+ .child = pax_table,
26258+ },
26259+#endif
26260+
26261 { .ctl_name = 0 }
26262 };
26263
26264@@ -1297,6 +1338,10 @@ static int test_perm(int mode, int op)
26265 static inline int ctl_perm(ctl_table *table, int op)
26266 {
26267 int error;
26268+ if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
26269+ return -EACCES;
26270+ if (gr_handle_chroot_sysctl(op))
26271+ return -EACCES;
26272 error = security_sysctl(table, op);
26273 if (error)
26274 return error;
26275@@ -1336,6 +1381,10 @@ repeat:
26276 table = table->child;
26277 goto repeat;
26278 }
26279+
26280+ if (!gr_handle_sysctl(table, oldval, newval))
26281+ return -EPERM;
26282+
26283 error = do_sysctl_strategy(table, name, nlen,
26284 oldval, oldlenp,
26285 newval, newlen, context);
26286diff -urNp linux-2.6.19.1/kernel/time.c linux-2.6.19.1/kernel/time.c
26287--- linux-2.6.19.1/kernel/time.c 2006-11-29 16:57:37.000000000 -0500
26288+++ linux-2.6.19.1/kernel/time.c 2006-12-03 15:16:26.000000000 -0500
26289@@ -36,6 +36,7 @@
26290 #include <linux/security.h>
26291 #include <linux/fs.h>
26292 #include <linux/module.h>
26293+#include <linux/grsecurity.h>
26294
26295 #include <asm/uaccess.h>
26296 #include <asm/unistd.h>
26297@@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user
26298 return err;
26299
9bdf255b 26300 vx_settimeofday(&tv);
c3e8c1b5 26301+
26302+ gr_log_timechange();
26303+
26304 return 0;
26305 }
26306
26307@@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct
26308 return -EFAULT;
26309 }
26310
26311+ gr_log_timechange();
26312+
26313 return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
26314 }
26315
26316diff -urNp linux-2.6.19.1/kernel/unwind.c linux-2.6.19.1/kernel/unwind.c
26317--- linux-2.6.19.1/kernel/unwind.c 2006-11-29 16:57:37.000000000 -0500
26318+++ linux-2.6.19.1/kernel/unwind.c 2006-12-03 15:16:26.000000000 -0500
26319@@ -351,8 +351,8 @@ void *unwind_add_table(struct module *mo
26320 return NULL;
26321
26322 init_unwind_table(table, module->name,
26323- module->module_core, module->core_size,
26324- module->module_init, module->init_size,
26325+ module->module_core_rx, module->core_size_rx,
26326+ module->module_init_rx, module->init_size_rx,
26327 table_start, table_size,
26328 NULL, 0);
26329
c3e8c1b5 26330diff -urNp linux-2.6.19.1/Makefile linux-2.6.19.1/Makefile
26331--- linux-2.6.19.1/Makefile 2006-12-10 21:40:26.000000000 -0500
26332+++ linux-2.6.19.1/Makefile 2006-12-10 21:40:15.000000000 -0500
26333@@ -313,7 +313,7 @@ LINUXINCLUDE := -Iinclude \
26334
26335 CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
26336
26337-CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
26338+CFLAGS := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
26339 -fno-strict-aliasing -fno-common
26340 AFLAGS := -D__ASSEMBLY__
26341
26342@@ -559,7 +559,7 @@ export mod_strip_cmd
26343
26344
26345 ifeq ($(KBUILD_EXTMOD),)
26346-core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
26347+core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
26348
26349 vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
26350 $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
26351diff -urNp linux-2.6.19.1/mm/filemap.c linux-2.6.19.1/mm/filemap.c
26352--- linux-2.6.19.1/mm/filemap.c 2006-11-29 16:57:37.000000000 -0500
26353+++ linux-2.6.19.1/mm/filemap.c 2006-12-03 15:16:26.000000000 -0500
26354@@ -30,6 +30,7 @@
26355 #include <linux/security.h>
26356 #include <linux/syscalls.h>
26357 #include <linux/cpuset.h>
26358+#include <linux/grsecurity.h>
26359 #include "filemap.h"
26360 #include "internal.h"
26361
26362@@ -1720,7 +1721,13 @@ int generic_file_mmap(struct file * file
26363 struct address_space *mapping = file->f_mapping;
26364
26365 if (!mapping->a_ops->readpage)
26366- return -ENOEXEC;
26367+ return -ENODEV;
26368+
26369+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26370+ if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
26371+ vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
26372+#endif
26373+
26374 file_accessed(file);
26375 vma->vm_ops = &generic_file_vm_ops;
26376 return 0;
26377@@ -1957,6 +1964,7 @@ inline int generic_write_checks(struct f
26378 *pos = i_size_read(inode);
26379
26380 if (limit != RLIM_INFINITY) {
26381+ gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
26382 if (*pos >= limit) {
26383 send_sig(SIGXFSZ, current, 0);
26384 return -EFBIG;
26385diff -urNp linux-2.6.19.1/mm/filemap_xip.c linux-2.6.19.1/mm/filemap_xip.c
26386--- linux-2.6.19.1/mm/filemap_xip.c 2006-11-29 16:57:37.000000000 -0500
26387+++ linux-2.6.19.1/mm/filemap_xip.c 2006-12-03 15:16:26.000000000 -0500
26388@@ -262,6 +262,11 @@ int xip_file_mmap(struct file * file, st
26389 {
26390 BUG_ON(!file->f_mapping->a_ops->get_xip_page);
26391
26392+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
26393+ if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
26394+ vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
26395+#endif
26396+
26397 file_accessed(file);
26398 vma->vm_ops = &xip_file_vm_ops;
26399 return 0;
26400diff -urNp linux-2.6.19.1/mm/madvise.c linux-2.6.19.1/mm/madvise.c
26401--- linux-2.6.19.1/mm/madvise.c 2006-11-29 16:57:37.000000000 -0500
26402+++ linux-2.6.19.1/mm/madvise.c 2006-12-03 15:16:26.000000000 -0500
26403@@ -15,9 +15,46 @@
26404 * We can potentially split a vm area into separate
26405 * areas, each area with its own behavior.
26406 */
26407+
26408+#ifdef CONFIG_PAX_SEGMEXEC
26409+static long __madvise_behavior(struct vm_area_struct * vma,
26410+ struct vm_area_struct **prev,
26411+ unsigned long start, unsigned long end, int behavior);
26412+
26413+static long madvise_behavior(struct vm_area_struct * vma,
26414+ struct vm_area_struct **prev,
26415+ unsigned long start, unsigned long end, int behavior)
26416+{
26417+ if (vma->vm_flags & VM_MIRROR) {
26418+ struct vm_area_struct * vma_m, * prev_m;
26419+ unsigned long start_m, end_m;
26420+ int error;
26421+
26422+ start_m = vma->vm_start + vma->vm_mirror;
26423+ vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
26424+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
26425+ start_m = start + vma->vm_mirror;
26426+ end_m = end + vma->vm_mirror;
26427+ error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
26428+ if (error)
26429+ return error;
26430+ } else {
26431+ printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
26432+ return -ENOMEM;
26433+ }
26434+ }
26435+
26436+ return __madvise_behavior(vma, prev, start, end, behavior);
26437+}
26438+
26439+static long __madvise_behavior(struct vm_area_struct * vma,
26440+ struct vm_area_struct **prev,
26441+ unsigned long start, unsigned long end, int behavior)
26442+#else
26443 static long madvise_behavior(struct vm_area_struct * vma,
26444 struct vm_area_struct **prev,
26445 unsigned long start, unsigned long end, int behavior)
26446+#endif
26447 {
26448 struct mm_struct * mm = vma->vm_mm;
26449 int error = 0;
26450diff -urNp linux-2.6.19.1/mm/memory.c linux-2.6.19.1/mm/memory.c
26451--- linux-2.6.19.1/mm/memory.c 2006-11-29 16:57:37.000000000 -0500
26452+++ linux-2.6.19.1/mm/memory.c 2006-12-03 15:16:26.000000000 -0500
26453@@ -50,6 +50,7 @@
26454 #include <linux/delayacct.h>
26455 #include <linux/init.h>
26456 #include <linux/writeback.h>
26457+#include <linux/grsecurity.h>
26458
26459 #include <asm/pgalloc.h>
26460 #include <asm/uaccess.h>
26461@@ -322,6 +323,11 @@ int __pte_alloc(struct mm_struct *mm, pm
26462
26463 int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
26464 {
26465+
26466+#ifdef CONFIG_PAX_KERNEXEC
26467+ unsigned long cr0;
26468+#endif
26469+
26470 pte_t *new = pte_alloc_one_kernel(&init_mm, address);
26471 if (!new)
26472 return -ENOMEM;
26473@@ -329,8 +335,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
26474 spin_lock(&init_mm.page_table_lock);
26475 if (pmd_present(*pmd)) /* Another has populated it */
26476 pte_free_kernel(new);
26477- else
26478+ else {
26479+
26480+#ifdef CONFIG_PAX_KERNEXEC
26481+ pax_open_kernel(cr0);
26482+#endif
26483+
26484 pmd_populate_kernel(&init_mm, pmd, new);
26485+
26486+#ifdef CONFIG_PAX_KERNEXEC
26487+ pax_close_kernel(cr0);
26488+#endif
26489+
26490+ }
26491 spin_unlock(&init_mm.page_table_lock);
26492 return 0;
26493 }
26494@@ -1459,6 +1476,88 @@ static inline void cow_user_page(struct
26495 copy_user_highpage(dst, src, va);
26496 }
26497
26498+#ifdef CONFIG_PAX_SEGMEXEC
26499+/* PaX: if vma is mirrored, synchronize the mirror's PTE
26500+ *
26501+ * the ptl of the lower mapped page is held on entry and is not released on exit
26502+ * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
26503+ */
26504+static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
26505+{
26506+ struct mm_struct *mm = vma->vm_mm;
26507+ unsigned long address_m, pfn_m;
26508+ struct vm_area_struct * vma_m = NULL;
26509+ pte_t * pte_m, entry_m;
26510+ struct page * page_m = NULL;
26511+
26512+ address_m = vma->vm_start + vma->vm_mirror;
26513+ vma_m = find_vma(mm, address_m);
26514+ BUG_ON(!vma_m || vma_m->vm_start != address_m);
26515+
26516+ address_m = address + vma->vm_mirror;
26517+ pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
26518+
26519+ if (pte_same(*pte, *pte_m)) {
26520+ pte_unmap_nested(pte_m);
26521+ return;
26522+ }
26523+
26524+ pfn_m = pte_pfn(*pte);
26525+ if (pte_present(*pte_m)) {
26526+ page_m = vm_normal_page(vma_m, address_m, *pte_m);
26527+ if (page_m) {
26528+ flush_cache_page(vma_m, address_m, pfn_m);
26529+ flush_icache_page(vma_m, page_m);
26530+ }
26531+ }
26532+
26533+ if (pte_present(*pte_m))
26534+ entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
26535+ else
26536+ entry_m = ptep_get_and_clear(mm, address_m, pte_m);
26537+
26538+ if (pte_none(entry_m)) {
26539+ } else if (pte_present(entry_m)) {
26540+ if (page_m) {
26541+ page_remove_rmap(page_m);
26542+ if (PageAnon(page_m))
26543+ dec_mm_counter(mm, anon_rss);
26544+ else
26545+ dec_mm_counter(mm, file_rss);
26546+ page_cache_release(page_m);
26547+ }
26548+ } else if (!pte_file(entry_m)) {
26549+ free_swap_and_cache(pte_to_swp_entry(entry_m));
26550+ } else {
26551+ printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
26552+ address, vma->vm_start, address_m, vma_m->vm_start);
26553+ }
26554+
26555+ page_m = vm_normal_page(vma, address, *pte);
26556+ entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
26557+ if (pte_write(*pte))
26558+ entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
26559+ if (page_m) {
26560+ page_cache_get(page_m);
26561+ /*
26562+ * we can test PAGE_MAPPING_ANON without holding page_map_lock because
26563+ * we hold the page table lock and have a reference to page_m
26564+ */
26565+ if (PageAnon(page_m)) {
26566+ page_add_anon_rmap(page_m, vma_m, address_m);
26567+ inc_mm_counter(mm, anon_rss);
26568+ } else {
26569+ page_add_file_rmap(page_m);
26570+ inc_mm_counter(mm, file_rss);
26571+ }
26572+ }
26573+ set_pte_at(mm, address_m, pte_m, entry_m);
26574+ update_mmu_cache(vma_m, address_m, entry_m);
26575+ lazy_mmu_prot_update(entry_m);
26576+ pte_unmap_nested(pte_m);
26577+}
26578+#endif
26579+
26580 /*
26581 * This routine handles present pages, when users try to write
26582 * to a shared page. It is done by copying the page to a new address
26583@@ -1602,6 +1701,12 @@ gotten:
26584 /* Free the old page.. */
26585 new_page = old_page;
26586 ret |= VM_FAULT_WRITE;
26587+
26588+#ifdef CONFIG_PAX_SEGMEXEC
26589+ if (vma->vm_flags & VM_MIRROR)
26590+ pax_mirror_fault(vma, address, page_table);
26591+#endif
26592+
26593 }
26594 if (new_page)
26595 page_cache_release(new_page);
26596@@ -1861,6 +1966,7 @@ int vmtruncate(struct inode * inode, lof
26597
26598 do_expand:
26599 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
26600+ gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
26601 if (limit != RLIM_INFINITY && offset > limit)
26602 goto out_sig;
26603 if (offset > inode->i_sb->s_maxbytes)
26604@@ -2055,6 +2161,12 @@ static int do_swap_page(struct mm_struct
26605 /* No need to invalidate - it was non-present before */
26606 update_mmu_cache(vma, address, pte);
26607 lazy_mmu_prot_update(pte);
26608+
26609+#ifdef CONFIG_PAX_SEGMEXEC
26610+ if (vma->vm_flags & VM_MIRROR)
26611+ pax_mirror_fault(vma, address, page_table);
26612+#endif
26613+
26614 unlock:
26615 pte_unmap_unlock(page_table, ptl);
26616 out:
26617@@ -2117,6 +2229,12 @@ static int do_anonymous_page(struct mm_s
26618 /* No need to invalidate - it was non-present before */
26619 update_mmu_cache(vma, address, entry);
26620 lazy_mmu_prot_update(entry);
26621+
26622+#ifdef CONFIG_PAX_SEGMEXEC
26623+ if (vma->vm_flags & VM_MIRROR)
26624+ pax_mirror_fault(vma, address, page_table);
26625+#endif
26626+
26627 unlock:
26628 pte_unmap_unlock(page_table, ptl);
26629 return VM_FAULT_MINOR;
26630@@ -2262,6 +2380,12 @@ retry:
26631 /* no need to invalidate: a not-present page shouldn't be cached */
26632 update_mmu_cache(vma, address, entry);
26633 lazy_mmu_prot_update(entry);
26634+
26635+#ifdef CONFIG_PAX_SEGMEXEC
26636+ if (vma->vm_flags & VM_MIRROR)
26637+ pax_mirror_fault(vma, address, page_table);
26638+#endif
26639+
26640 unlock:
26641 pte_unmap_unlock(page_table, ptl);
26642 if (dirty_page) {
26643@@ -2429,6 +2553,12 @@ static inline int handle_pte_fault(struc
26644 flush_tlb_page(vma, address);
26645 }
26646 unlock:
26647+
26648+#ifdef CONFIG_PAX_SEGMEXEC
26649+ if (vma->vm_flags & VM_MIRROR)
26650+ pax_mirror_fault(vma, address, pte);
26651+#endif
26652+
26653 pte_unmap_unlock(pte, ptl);
26654 return VM_FAULT_MINOR;
26655 }
26656@@ -2451,6 +2581,49 @@ int __handle_mm_fault(struct mm_struct *
26657 if (unlikely(is_vm_hugetlb_page(vma)))
26658 return hugetlb_fault(mm, vma, address, write_access);
26659
26660+#ifdef CONFIG_PAX_SEGMEXEC
26661+ if (vma->vm_flags & VM_MIRROR) {
26662+ unsigned long address_m;
26663+ struct vm_area_struct * vma_m;
26664+ pgd_t *pgd_m;
26665+ pud_t *pud_m;
26666+ pmd_t *pmd_m;
26667+
26668+ address_m = vma->vm_start + vma->vm_mirror;
26669+ vma_m = find_vma(mm, address_m);
26670+
26671+ /* PaX: sanity checks */
26672+ if (!vma_m) {
26673+ printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
26674+ address, vma, address_m, vma_m);
26675+ return VM_FAULT_SIGBUS;
26676+ } else if (!(vma_m->vm_flags & VM_MIRROR) ||
26677+ vma_m->vm_start != address_m ||
26678+ vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
26679+ {
26680+ printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
26681+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
26682+ return VM_FAULT_SIGBUS;
26683+ }
26684+
26685+ if (address_m < address) {
26686+ address += vma->vm_mirror;
26687+ vma = vma_m;
26688+ }
26689+
26690+ address_m = address + vma->vm_mirror;
26691+ pgd_m = pgd_offset(mm, address_m);
26692+ pud_m = pud_alloc(mm, pgd_m, address_m);
26693+ if (!pud_m)
26694+ return VM_FAULT_OOM;
26695+ pmd_m = pmd_alloc(mm, pud_m, address_m);
26696+ if (!pmd_m)
26697+ return VM_FAULT_OOM;
26698+ if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
26699+ return VM_FAULT_OOM;
26700+ }
26701+#endif
26702+
26703 pgd = pgd_offset(mm, address);
26704 pud = pud_alloc(mm, pgd, address);
26705 if (!pud)
26706diff -urNp linux-2.6.19.1/mm/mempolicy.c linux-2.6.19.1/mm/mempolicy.c
26707--- linux-2.6.19.1/mm/mempolicy.c 2006-11-29 16:57:37.000000000 -0500
26708+++ linux-2.6.19.1/mm/mempolicy.c 2006-12-03 15:16:26.000000000 -0500
26709@@ -353,6 +353,12 @@ check_range(struct mm_struct *mm, unsign
26710 if (prev && prev->vm_end < vma->vm_start)
26711 return ERR_PTR(-EFAULT);
26712 }
26713+
26714+#ifdef CONFIG_PAX_SEGMEXEC
26715+ if (vma->vm_flags & VM_MIRROR)
26716+ return ERR_PTR(-EFAULT);
26717+#endif
26718+
26719 if (!is_vm_hugetlb_page(vma) &&
26720 ((flags & MPOL_MF_STRICT) ||
26721 ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
26722diff -urNp linux-2.6.19.1/mm/mlock.c linux-2.6.19.1/mm/mlock.c
26723--- linux-2.6.19.1/mm/mlock.c 2006-11-29 16:57:37.000000000 -0500
26724+++ linux-2.6.19.1/mm/mlock.c 2006-12-03 15:16:26.000000000 -0500
26725@@ -10,14 +10,85 @@
c3e8c1b5 26726 #include <linux/mempolicy.h>
26727 #include <linux/syscalls.h>
9bdf255b 26728 #include <linux/vs_memory.h>
c3e8c1b5 26729+#include <linux/grsecurity.h>
26730
26731+static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
26732+ unsigned long start, unsigned long end, unsigned int newflags);
26733
26734 static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
26735 unsigned long start, unsigned long end, unsigned int newflags)
26736 {
26737 struct mm_struct * mm = vma->vm_mm;
26738- pgoff_t pgoff;
26739 int pages;
26740+ int ret;
26741+
26742+#ifdef CONFIG_PAX_SEGMEXEC
26743+ struct vm_area_struct * vma_m = NULL, *prev_m;
26744+ unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
26745+
26746+ if (vma->vm_flags & VM_MIRROR) {
26747+ start_m = vma->vm_start + vma->vm_mirror;
26748+ vma_m = find_vma_prev(mm, start_m, &prev_m);
26749+ if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
26750+ printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
26751+ return -ENOMEM;
26752+ }
26753+
26754+ start_m = start + vma->vm_mirror;
26755+ end_m = end + vma->vm_mirror;
26756+ if (newflags & VM_LOCKED)
26757+ newflags_m = vma_m->vm_flags | VM_LOCKED;
26758+ else
26759+ newflags_m = vma_m->vm_flags & ~VM_LOCKED;
26760+ ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
26761+ if (ret)
26762+ return ret;
26763+ }
26764+#endif
26765+
26766+ ret = __mlock_fixup(vma, prev, start, end, newflags);
26767+ if (ret)
26768+ return ret;
26769+
26770+ /*
26771+ * vm_flags is protected by the mmap_sem held in write mode.
26772+ * It's okay if try_to_unmap_one unmaps a page just after we
26773+ * set VM_LOCKED, make_pages_present below will bring it back.
26774+ */
26775+ vma->vm_flags = newflags;
26776+
26777+#ifdef CONFIG_PAX_SEGMEXEC
26778+ if (vma->vm_flags & VM_MIRROR)
26779+ vma_m->vm_flags = newflags_m;
26780+#endif
26781+
26782+ /*
26783+ * Keep track of amount of locked VM.
26784+ */
26785+ pages = (end - start) >> PAGE_SHIFT;
26786+ if (newflags & VM_LOCKED) {
26787+ pages = -pages;
26788+ if (!(newflags & VM_IO))
26789+ ret = make_pages_present(start, end);
26790+ }
26791+
26792+ mm->locked_vm -= pages;
26793+
26794+#ifdef CONFIG_PAX_SEGMEXEC
26795+ if (vma->vm_flags & VM_MIRROR)
26796+ mm->locked_vm -= pages;
26797+#endif
26798+
26799+ if (ret == -ENOMEM)
26800+ ret = -EAGAIN;
26801+ return ret;
26802+}
26803+
26804+static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
26805+ unsigned long start, unsigned long end, unsigned int newflags)
26806+{
26807+ struct mm_struct * mm = vma->vm_mm;
26808+ pgoff_t pgoff;
26809 int ret = 0;
26810
26811 if (newflags == vma->vm_flags) {
26812@@ -30,7 +101,7 @@ static int mlock_fixup(struct vm_area_st
26813 vma->vm_file, pgoff, vma_policy(vma));
26814 if (*prev) {
26815 vma = *prev;
26816- goto success;
26817+ goto out;
26818 }
26819
26820 *prev = vma;
26821@@ -41,31 +112,9 @@ static int mlock_fixup(struct vm_area_st
26822 goto out;
26823 }
26824
26825- if (end != vma->vm_end) {
26826+ if (end != vma->vm_end)
26827 ret = split_vma(mm, vma, end, 0);
26828- if (ret)
26829- goto out;
26830- }
26831
26832-success:
26833- /*
26834- * vm_flags is protected by the mmap_sem held in write mode.
26835- * It's okay if try_to_unmap_one unmaps a page just after we
26836- * set VM_LOCKED, make_pages_present below will bring it back.
26837- */
26838- vma->vm_flags = newflags;
26839-
26840- /*
26841- * Keep track of amount of locked VM.
26842- */
26843- pages = (end - start) >> PAGE_SHIFT;
26844- if (newflags & VM_LOCKED) {
26845- pages = -pages;
26846- if (!(newflags & VM_IO))
26847- ret = make_pages_present(start, end);
26848- }
26849-
9bdf255b 26850- vx_vmlocked_sub(vma->vm_mm, pages);
c3e8c1b5 26851 out:
26852 if (ret == -ENOMEM)
26853 ret = -EAGAIN;
26854@@ -84,6 +133,17 @@ static int do_mlock(unsigned long start,
26855 return -EINVAL;
26856 if (end == start)
26857 return 0;
26858+
26859+#ifdef CONFIG_PAX_SEGMEXEC
26860+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
26861+ if (end > SEGMEXEC_TASK_SIZE)
26862+ return -EINVAL;
26863+ } else
26864+#endif
26865+
26866+ if (end > TASK_SIZE)
26867+ return -EINVAL;
26868+
26869 vma = find_vma_prev(current->mm, start, &prev);
26870 if (!vma || vma->vm_start > start)
26871 return -ENOMEM;
26872@@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long
26873 lock_limit >>= PAGE_SHIFT;
26874
26875 /* check against resource limits */
26876+ gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
26877 if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
26878 error = do_mlock(start, len, 1);
26879 up_write(&current->mm->mmap_sem);
26880@@ -173,6 +234,16 @@ static int do_mlockall(int flags)
26881 for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
26882 unsigned int newflags;
26883
26884+#ifdef CONFIG_PAX_SEGMEXEC
26885+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
26886+ if (vma->vm_end > SEGMEXEC_TASK_SIZE)
26887+ break;
26888+ } else
26889+#endif
26890+
26891+ if (vma->vm_end > TASK_SIZE)
26892+ break;
26893+
26894 newflags = vma->vm_flags | VM_LOCKED;
26895 if (!(flags & MCL_CURRENT))
26896 newflags &= ~VM_LOCKED;
26897@@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
26898 lock_limit >>= PAGE_SHIFT;
26899
26900 ret = -ENOMEM;
26901+ gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
9bdf255b 26902 if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
c3e8c1b5 26903 capable(CAP_IPC_LOCK))
9bdf255b 26904 ret = do_mlockall(flags);
c3e8c1b5 26905diff -urNp linux-2.6.19.1/mm/mmap.c linux-2.6.19.1/mm/mmap.c
26906--- linux-2.6.19.1/mm/mmap.c 2006-11-29 16:57:37.000000000 -0500
26907+++ linux-2.6.19.1/mm/mmap.c 2006-12-03 15:16:26.000000000 -0500
26908@@ -25,6 +25,7 @@
26909 #include <linux/mount.h>
26910 #include <linux/mempolicy.h>
26911 #include <linux/rmap.h>
26912+#include <linux/grsecurity.h>
26913
26914 #include <asm/uaccess.h>
26915 #include <asm/cacheflush.h>
26916@@ -251,6 +252,7 @@ asmlinkage unsigned long sys_brk(unsigne
26917 * not page aligned -Ram Gupta
26918 */
26919 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
26920+ gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
26921 if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
26922 goto out;
26923
26924@@ -639,11 +641,17 @@ again: remove_next = 1 + (end > next->
26925 * If the vma has a ->close operation then the driver probably needs to release
26926 * per-vma resources, so we don't attempt to merge those.
26927 */
26928+#ifdef CONFIG_PAX_SEGMEXEC
26929+#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
26930+#else
26931 #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
26932+#endif
26933
26934 static inline int is_mergeable_vma(struct vm_area_struct *vma,
26935 struct file *file, unsigned long vm_flags)
26936 {
26937+ if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
26938+ return 0;
26939 if (vma->vm_flags != vm_flags)
26940 return 0;
26941 if (vma->vm_file != file)
26942@@ -868,14 +876,11 @@ none:
26943 void vm_stat_account(struct mm_struct *mm, unsigned long flags,
26944 struct file *file, long pages)
26945 {
26946- const unsigned long stack_flags
26947- = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
26948-
26949 if (file) {
26950 mm->shared_vm += pages;
26951 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
26952 mm->exec_vm += pages;
26953- } else if (flags & stack_flags)
26954+ } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
26955 mm->stack_vm += pages;
26956 if (flags & (VM_RESERVED|VM_IO))
26957 mm->reserved_vm += pages;
26958@@ -886,9 +891,54 @@ void vm_stat_account(struct mm_struct *m
26959 * The caller must hold down_write(current->mm->mmap_sem).
26960 */
26961
26962+#ifdef CONFIG_PAX_SEGMEXEC
26963+static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
26964+ unsigned long len, unsigned long prot,
26965+ unsigned long flags, unsigned long pgoff);
26966+
26967+unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
26968+ unsigned long len, unsigned long prot,
26969+ unsigned long flags, unsigned long pgoff)
26970+{
26971+ unsigned long ret = -EINVAL;
26972+
26973+ if (flags & MAP_MIRROR)
26974+ return ret;
26975+
26976+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
26977+ (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
26978+ return ret;
26979+
26980+ ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
26981+
26982+ if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
26983+
26984+#ifdef CONFIG_PAX_MPROTECT
26985+ && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
26986+#endif
26987+
26988+ )
26989+ {
26990+ unsigned long ret_m;
26991+ prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
26992+ ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
26993+ if (ret_m >= TASK_SIZE) {
26994+ do_munmap(current->mm, ret, len);
26995+ ret = ret_m;
26996+ }
26997+ }
26998+
26999+ return ret;
27000+}
27001+
27002+static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
27003+ unsigned long len, unsigned long prot,
27004+ unsigned long flags, unsigned long pgoff)
27005+#else
27006 unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
27007 unsigned long len, unsigned long prot,
27008 unsigned long flags, unsigned long pgoff)
27009+#endif
27010 {
27011 struct mm_struct * mm = current->mm;
27012 struct vm_area_struct * vma, * prev;
27013@@ -900,13 +950,35 @@ unsigned long do_mmap_pgoff(struct file
27014 int accountable = 1;
27015 unsigned long charged = 0, reqprot = prot;
27016
27017+#ifdef CONFIG_PAX_SEGMEXEC
27018+ struct vm_area_struct * vma_m = NULL;
27019+
27020+ if (flags & MAP_MIRROR) {
27021+ /* PaX: sanity checks, to be removed when proved to be stable */
27022+ if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
27023+ return -EINVAL;
27024+
27025+ vma_m = find_vma(mm, pgoff);
27026+
27027+ if (!vma_m || is_vm_hugetlb_page(vma_m) ||
27028+ vma_m->vm_start != pgoff ||
27029+ (vma_m->vm_flags & VM_SPECIAL) ||
27030+ (prot & PROT_WRITE))
27031+ return -EINVAL;
27032+
27033+ file = vma_m->vm_file;
27034+ pgoff = vma_m->vm_pgoff;
27035+ len = vma_m->vm_end - vma_m->vm_start;
27036+ }
27037+#endif
27038+
27039 /*
27040 * Does the application expect PROT_READ to imply PROT_EXEC?
27041 *
27042 * (the exception is when the underlying filesystem is noexec
27043 * mounted, in which case we dont add PROT_EXEC.)
27044 */
27045- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
27046+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
27047 if (!(file && (file->f_vfsmnt->mnt_flags & MNT_NOEXEC)))
27048 prot |= PROT_EXEC;
27049
27050@@ -933,7 +1005,7 @@ unsigned long do_mmap_pgoff(struct file
27051 /* Obtain the address to map to. we verify (or select) it and ensure
27052 * that it represents a valid section of the address space.
27053 */
27054- addr = get_unmapped_area(file, addr, len, pgoff, flags);
27055+ addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
27056 if (addr & ~PAGE_MASK)
27057 return addr;
27058
27059@@ -944,6 +1016,21 @@ unsigned long do_mmap_pgoff(struct file
27060 vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
27061 mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
27062
27063+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27064+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
27065+
27066+#ifdef CONFIG_PAX_MPROTECT
27067+ if (mm->pax_flags & MF_PAX_MPROTECT) {
27068+ if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
27069+ vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
27070+ else
27071+ vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
27072+ }
27073+#endif
27074+
27075+ }
27076+#endif
27077+
27078 if (flags & MAP_LOCKED) {
27079 if (!can_do_mlock())
27080 return -EPERM;
27081@@ -956,6 +1043,7 @@ unsigned long do_mmap_pgoff(struct file
27082 locked += mm->locked_vm;
27083 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
27084 lock_limit >>= PAGE_SHIFT;
27085+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
27086 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
27087 return -EAGAIN;
27088 }
27089@@ -1013,6 +1101,11 @@ unsigned long do_mmap_pgoff(struct file
27090 /*
27091 * Set pgoff according to addr for anon_vma.
27092 */
27093+
27094+#ifdef CONFIG_PAX_SEGMEXEC
27095+ if (!(flags & MAP_MIRROR))
27096+#endif
27097+
27098 pgoff = addr >> PAGE_SHIFT;
27099 break;
27100 default:
27101@@ -1024,14 +1117,17 @@ unsigned long do_mmap_pgoff(struct file
27102 if (error)
27103 return error;
27104
27105+ if (!gr_acl_handle_mmap(file, prot))
27106+ return -EACCES;
27107+
27108 /* Clear old maps */
27109 error = -ENOMEM;
27110-munmap_back:
27111 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
27112 if (vma && vma->vm_start < addr + len) {
27113 if (do_munmap(mm, addr, len))
27114 return -ENOMEM;
27115- goto munmap_back;
27116+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
27117+ BUG_ON(vma && vma->vm_start < addr + len);
27118 }
27119
27120 /* Check against address space limit. */
27121@@ -1079,6 +1175,13 @@ munmap_back:
27122 vma->vm_start = addr;
27123 vma->vm_end = addr + len;
27124 vma->vm_flags = vm_flags;
27125+
27126+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
27127+ if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
27128+ vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27129+ else
27130+#endif
27131+
27132 vma->vm_page_prot = protection_map[vm_flags &
27133 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27134 vma->vm_pgoff = pgoff;
27135@@ -1104,6 +1207,14 @@ munmap_back:
27136 goto free_vma;
27137 }
27138
27139+#ifdef CONFIG_PAX_SEGMEXEC
27140+ if (flags & MAP_MIRROR) {
27141+ vma_m->vm_flags |= VM_MIRROR;
27142+ vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
27143+ vma->vm_mirror = vma_m->vm_start - vma->vm_start;
27144+ }
27145+#endif
27146+
27147 /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
27148 * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
27149 * that memory reservation must be checked; but that reservation
27150@@ -1121,9 +1232,17 @@ munmap_back:
27151 pgoff = vma->vm_pgoff;
27152 vm_flags = vma->vm_flags;
27153
27154- if (vma_wants_writenotify(vma))
27155+ if (vma_wants_writenotify(vma)) {
27156+
27157+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
27158+ if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
27159+ vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
27160+ else
27161+#endif
27162+
27163 vma->vm_page_prot =
27164 protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
27165+ }
27166
27167 if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
27168 vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
27169@@ -1143,6 +1262,7 @@ munmap_back:
27170 out:
27171 mm->total_vm += len >> PAGE_SHIFT;
27172 vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
27173+ track_exec_limit(mm, addr, addr + len, vm_flags);
27174 if (vm_flags & VM_LOCKED) {
27175 mm->locked_vm += len >> PAGE_SHIFT;
27176 make_pages_present(addr, addr + len);
27177@@ -1197,6 +1317,10 @@ arch_get_unmapped_area(struct file *filp
27178 if (len > TASK_SIZE)
27179 return -ENOMEM;
27180
27181+#ifdef CONFIG_PAX_RANDMMAP
27182+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
27183+#endif
27184+
27185 if (addr) {
27186 addr = PAGE_ALIGN(addr);
27187 vma = find_vma(mm, addr);
27188@@ -1207,7 +1331,7 @@ arch_get_unmapped_area(struct file *filp
27189 if (len > mm->cached_hole_size) {
27190 start_addr = addr = mm->free_area_cache;
27191 } else {
27192- start_addr = addr = TASK_UNMAPPED_BASE;
27193+ start_addr = addr = mm->mmap_base;
27194 mm->cached_hole_size = 0;
27195 }
27196
27197@@ -1219,9 +1343,8 @@ full_search:
27198 * Start a new search - just in case we missed
27199 * some holes.
27200 */
27201- if (start_addr != TASK_UNMAPPED_BASE) {
27202- addr = TASK_UNMAPPED_BASE;
27203- start_addr = addr;
27204+ if (start_addr != mm->mmap_base) {
27205+ start_addr = addr = mm->mmap_base;
27206 mm->cached_hole_size = 0;
27207 goto full_search;
27208 }
27209@@ -1246,7 +1369,7 @@ void arch_unmap_area(struct mm_struct *m
27210 /*
27211 * Is this a new hole at the lowest possible address?
27212 */
27213- if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
27214+ if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
27215 mm->free_area_cache = addr;
27216 mm->cached_hole_size = ~0UL;
27217 }
27218@@ -1264,12 +1387,16 @@ arch_get_unmapped_area_topdown(struct fi
27219 {
27220 struct vm_area_struct *vma;
27221 struct mm_struct *mm = current->mm;
27222- unsigned long addr = addr0;
27223+ unsigned long base = mm->mmap_base, addr = addr0;
27224
27225 /* requested length too big for entire address space */
27226 if (len > TASK_SIZE)
27227 return -ENOMEM;
27228
27229+#ifdef CONFIG_PAX_RANDMMAP
27230+ if (!(mm->pax_flags & MF_PAX_RANDMMAP))
27231+#endif
27232+
27233 /* requesting a specific address */
27234 if (addr) {
27235 addr = PAGE_ALIGN(addr);
27236@@ -1327,13 +1454,21 @@ bottomup:
27237 * can happen with large stack limits and large mmap()
27238 * allocations.
27239 */
27240+ mm->mmap_base = TASK_UNMAPPED_BASE;
27241+
27242+#ifdef CONFIG_PAX_RANDMMAP
27243+ if (mm->pax_flags & MF_PAX_RANDMMAP)
27244+ mm->mmap_base += mm->delta_mmap;
27245+#endif
27246+
27247+ mm->free_area_cache = mm->mmap_base;
27248 mm->cached_hole_size = ~0UL;
27249- mm->free_area_cache = TASK_UNMAPPED_BASE;
27250 addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
27251 /*
27252 * Restore the topdown base:
27253 */
27254- mm->free_area_cache = mm->mmap_base;
27255+ mm->mmap_base = base;
27256+ mm->free_area_cache = base;
27257 mm->cached_hole_size = ~0UL;
27258
27259 return addr;
27260@@ -1349,8 +1484,10 @@ void arch_unmap_area_topdown(struct mm_s
27261 mm->free_area_cache = addr;
27262
27263 /* dont allow allocations above current base */
27264- if (mm->free_area_cache > mm->mmap_base)
27265+ if (mm->free_area_cache > mm->mmap_base) {
27266 mm->free_area_cache = mm->mmap_base;
27267+ mm->cached_hole_size = ~0UL;
27268+ }
27269 }
27270
27271 unsigned long
27272@@ -1483,6 +1620,7 @@ static int acct_stack_growth(struct vm_a
27273 return -ENOMEM;
27274
27275 /* Stack limit test */
27276+ gr_learn_resource(current, RLIMIT_STACK, size, 1);
27277 if (size > rlim[RLIMIT_STACK].rlim_cur)
27278 return -ENOMEM;
27279
27280@@ -1492,6 +1630,7 @@ static int acct_stack_growth(struct vm_a
27281 unsigned long limit;
27282 locked = mm->locked_vm + grow;
27283 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
27284+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
27285 if (locked > limit && !capable(CAP_IPC_LOCK))
27286 return -ENOMEM;
27287 }
27288@@ -1609,13 +1748,49 @@ int expand_stack(struct vm_area_struct *
27289 if (address < vma->vm_start) {
27290 unsigned long size, grow;
27291
27292+#ifdef CONFIG_PAX_SEGMEXEC
27293+ struct vm_area_struct *vma_m = NULL;
27294+ unsigned long address_m = 0UL;
27295+
27296+ if (vma->vm_flags & VM_MIRROR) {
27297+ address_m = vma->vm_start + vma->vm_mirror;
27298+ vma_m = find_vma(vma->vm_mm, address_m);
27299+ if (!vma_m || vma_m->vm_start != address_m ||
27300+ !(vma_m->vm_flags & VM_MIRROR) ||
27301+ vma->vm_end - vma->vm_start !=
27302+ vma_m->vm_end - vma_m->vm_start ||
27303+ vma->anon_vma != vma_m->anon_vma) {
27304+ printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
27305+ address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
27306+ anon_vma_unlock(vma);
27307+ return -EFAULT;
27308+ }
27309+ address_m = address + vma->vm_mirror;
27310+ }
27311+#endif
27312+
27313 size = vma->vm_end - address;
27314 grow = (vma->vm_start - address) >> PAGE_SHIFT;
27315
27316+#ifdef CONFIG_PAX_SEGMEXEC
27317+ if (vma_m)
27318+ error = acct_stack_growth(vma, size, 2*grow);
27319+ else
27320+#endif
27321+
27322 error = acct_stack_growth(vma, size, grow);
27323 if (!error) {
27324 vma->vm_start = address;
27325 vma->vm_pgoff -= grow;
27326+ track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
27327+
27328+#ifdef CONFIG_PAX_SEGMEXEC
27329+ if (vma_m) {
27330+ vma_m->vm_start = address_m;
27331+ vma_m->vm_pgoff -= grow;
27332+ }
27333+#endif
27334+
27335 }
27336 }
27337 anon_vma_unlock(vma);
27338@@ -1777,8 +1952,25 @@ int split_vma(struct mm_struct * mm, str
27339 * work. This now handles partial unmappings.
27340 * Jeremy Fitzhardinge <jeremy@goop.org>
27341 */
27342+#ifdef CONFIG_PAX_SEGMEXEC
27343+static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
27344+
27345 int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
27346 {
27347+ if (mm->pax_flags & MF_PAX_SEGMEXEC) {
27348+ int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
27349+ if (ret)
27350+ return ret;
27351+ }
27352+
27353+ return __do_munmap(mm, start, len);
27354+}
27355+
27356+static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
27357+#else
27358+int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
27359+#endif
27360+{
27361 unsigned long end;
27362 struct vm_area_struct *vma, *prev, *last;
27363
27364@@ -1831,6 +2023,8 @@ int do_munmap(struct mm_struct *mm, unsi
27365 /* Fix up all other VM information */
27366 remove_vma_list(mm, vma);
27367
27368+ track_exec_limit(mm, start, end, 0UL);
27369+
27370 return 0;
27371 }
27372
27373@@ -1843,6 +2037,12 @@ asmlinkage long sys_munmap(unsigned long
27374
27375 profile_munmap(addr);
27376
27377+#ifdef CONFIG_PAX_SEGMEXEC
27378+ if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
27379+ (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
27380+ return -EINVAL;
27381+#endif
27382+
27383 down_write(&mm->mmap_sem);
27384 ret = do_munmap(mm, addr, len);
27385 up_write(&mm->mmap_sem);
27386@@ -1864,11 +2064,35 @@ static inline void verify_mm_writelocked
27387 * anonymous maps. eventually we may be able to do some
27388 * brk-specific accounting here.
27389 */
27390+#ifdef CONFIG_PAX_SEGMEXEC
27391+static unsigned long __do_brk(unsigned long addr, unsigned long len);
27392+
27393 unsigned long do_brk(unsigned long addr, unsigned long len)
27394 {
27395+ unsigned long ret;
27396+
27397+ ret = __do_brk(addr, len);
27398+ if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
27399+ unsigned long ret_m;
27400+
27401+ ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
27402+ if (ret_m > TASK_SIZE) {
27403+ do_munmap(current->mm, addr, len);
27404+ ret = ret_m;
27405+ }
27406+ }
27407+
27408+ return ret;
27409+}
27410+
27411+static unsigned long __do_brk(unsigned long addr, unsigned long len)
27412+#else
27413+unsigned long do_brk(unsigned long addr, unsigned long len)
27414+#endif
27415+{
27416 struct mm_struct * mm = current->mm;
27417 struct vm_area_struct * vma, * prev;
27418- unsigned long flags;
27419+ unsigned long flags, task_size = TASK_SIZE;
27420 struct rb_node ** rb_link, * rb_parent;
27421 pgoff_t pgoff = addr >> PAGE_SHIFT;
27422 int error;
27423@@ -1877,7 +2101,12 @@ unsigned long do_brk(unsigned long addr,
27424 if (!len)
27425 return addr;
27426
27427- if ((addr + len) > TASK_SIZE || (addr + len) < addr)
27428+#ifdef CONFIG_PAX_SEGMEXEC
27429+ if (mm->pax_flags & MF_PAX_SEGMEXEC)
27430+ task_size = SEGMEXEC_TASK_SIZE;
27431+#endif
27432+
27433+ if ((addr + len) > task_size || (addr + len) < addr)
27434 return -EINVAL;
27435
27436 if (is_hugepage_only_range(mm, addr, len))
27437@@ -1885,6 +2114,18 @@ unsigned long do_brk(unsigned long addr,
27438
27439 flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
27440
27441+#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27442+ if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
27443+ flags &= ~VM_EXEC;
27444+
27445+#ifdef CONFIG_PAX_MPROTECT
27446+ if (mm->pax_flags & MF_PAX_MPROTECT)
27447+ flags &= ~VM_MAYEXEC;
27448+#endif
27449+
27450+ }
27451+#endif
27452+
27453 error = arch_mmap_check(addr, len, flags);
27454 if (error)
27455 return error;
27456@@ -1898,6 +2139,7 @@ unsigned long do_brk(unsigned long addr,
27457 locked += mm->locked_vm;
27458 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
27459 lock_limit >>= PAGE_SHIFT;
27460+ gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
27461 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
27462 return -EAGAIN;
27463 }
27464@@ -1911,12 +2153,12 @@ unsigned long do_brk(unsigned long addr,
27465 /*
27466 * Clear old maps. this also does some error checking for us
27467 */
27468- munmap_back:
27469 vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
27470 if (vma && vma->vm_start < addr + len) {
27471 if (do_munmap(mm, addr, len))
27472 return -ENOMEM;
27473- goto munmap_back;
27474+ vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
27475+ BUG_ON(vma && vma->vm_start < addr + len);
27476 }
27477
27478 /* Check against address space limits *after* clearing old maps... */
27479@@ -1948,6 +2190,13 @@ unsigned long do_brk(unsigned long addr,
27480 vma->vm_end = addr + len;
27481 vma->vm_pgoff = pgoff;
27482 vma->vm_flags = flags;
27483+
27484+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
27485+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
27486+ vma->vm_page_prot = protection_map[(flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27487+ else
27488+#endif
27489+
27490 vma->vm_page_prot = protection_map[flags &
27491 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27492 vma_link(mm, vma, prev, rb_link, rb_parent);
27493@@ -1957,6 +2206,7 @@ out:
27494 mm->locked_vm += len >> PAGE_SHIFT;
27495 make_pages_present(addr, addr + len);
27496 }
27497+ track_exec_limit(mm, addr, addr + len, flags);
27498 return addr;
27499 }
27500
27501@@ -2089,7 +2339,7 @@ int may_expand_vm(struct mm_struct *mm,
27502 unsigned long lim;
27503
27504 lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
27505-
27506+ gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
27507 if (cur + npages > lim)
27508 return 0;
27509 return 1;
27510diff -urNp linux-2.6.19.1/mm/mprotect.c linux-2.6.19.1/mm/mprotect.c
27511--- linux-2.6.19.1/mm/mprotect.c 2006-11-29 16:57:37.000000000 -0500
27512+++ linux-2.6.19.1/mm/mprotect.c 2006-12-03 15:16:26.000000000 -0500
27513@@ -21,10 +21,17 @@
27514 #include <linux/syscalls.h>
27515 #include <linux/swap.h>
27516 #include <linux/swapops.h>
27517+#include <linux/grsecurity.h>
27518+
27519+#ifdef CONFIG_PAX_MPROTECT
27520+#include <linux/elf.h>
27521+#endif
27522+
27523 #include <asm/uaccess.h>
27524 #include <asm/pgtable.h>
27525 #include <asm/cacheflush.h>
27526 #include <asm/tlbflush.h>
27527+#include <asm/mmu_context.h>
27528
27529 static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
27530 unsigned long addr, unsigned long end, pgprot_t newprot,
27531@@ -128,6 +135,94 @@ static void change_protection(struct vm_
27532 flush_tlb_range(vma, start, end);
27533 }
27534
27535+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
27536+/* called while holding the mmap semaphor for writing */
27537+static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
27538+{
27539+ struct vm_area_struct *vma = find_vma(mm, start);
27540+
27541+ for (; vma && vma->vm_start < end; vma = vma->vm_next)
27542+ change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
27543+
27544+}
27545+
27546+void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
27547+{
27548+ unsigned long oldlimit, newlimit = 0UL;
27549+
27550+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
27551+ return;
27552+
27553+ spin_lock(&mm->page_table_lock);
27554+ oldlimit = mm->context.user_cs_limit;
27555+ if ((prot & VM_EXEC) && oldlimit < end)
27556+ /* USER_CS limit moved up */
27557+ newlimit = end;
27558+ else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
27559+ /* USER_CS limit moved down */
27560+ newlimit = start;
27561+
27562+ if (newlimit) {
27563+ mm->context.user_cs_limit = newlimit;
27564+
27565+#ifdef CONFIG_SMP
27566+ wmb();
27567+ cpus_clear(mm->context.cpu_user_cs_mask);
27568+ cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
27569+#endif
27570+
27571+ set_user_cs(mm, smp_processor_id());
27572+ }
27573+ spin_unlock(&mm->page_table_lock);
27574+ if (newlimit == end)
27575+ establish_user_cs_limit(mm, oldlimit, end);
27576+}
27577+#endif
27578+
27579+#ifdef CONFIG_PAX_SEGMEXEC
27580+static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27581+ unsigned long start, unsigned long end, unsigned int newflags);
27582+
27583+static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27584+ unsigned long start, unsigned long end, unsigned int newflags)
27585+{
27586+ if (vma->vm_flags & VM_MIRROR) {
27587+ struct vm_area_struct * vma_m, * prev_m;
27588+ unsigned long start_m, end_m;
27589+ int error;
27590+
27591+ start_m = vma->vm_start + vma->vm_mirror;
27592+ vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
27593+ if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
27594+ start_m = start + vma->vm_mirror;
27595+ end_m = end + vma->vm_mirror;
27596+
27597+ if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
27598+ error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
27599+ else
27600+ error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
27601+ if (error)
27602+ return error;
27603+ } else {
27604+ printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
27605+ return -ENOMEM;
27606+ }
27607+ }
27608+
27609+ return __mprotect_fixup(vma, pprev, start, end, newflags);
27610+}
27611+
27612+static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27613+ unsigned long start, unsigned long end, unsigned int newflags)
27614+{
27615+ struct mm_struct * mm = vma->vm_mm;
27616+ unsigned long oldflags = vma->vm_flags;
27617+ long nrpages = (end - start) >> PAGE_SHIFT;
27618+ unsigned long charged = 0;
27619+ pgoff_t pgoff;
27620+ int error;
27621+ int dirty_accountable = 0;
27622+#else
27623 static int
27624 mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
27625 unsigned long start, unsigned long end, unsigned long newflags)
27626@@ -144,6 +239,7 @@ mprotect_fixup(struct vm_area_struct *vm
27627 *pprev = vma;
27628 return 0;
27629 }
27630+#endif
27631
27632 /*
27633 * If we make a private mapping writable we increase our commit;
27634@@ -193,12 +289,29 @@ success:
27635 * held in write mode.
27636 */
27637 vma->vm_flags = newflags;
27638- vma->vm_page_prot = protection_map[newflags &
27639- (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27640 if (vma_wants_writenotify(vma)) {
27641+
27642+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
27643+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
27644+ vma->vm_page_prot = protection_map[(newflags | VM_EXEC) &
27645+ (VM_READ|VM_WRITE|VM_EXEC)];
27646+ else
27647+#endif
27648+
27649 vma->vm_page_prot = protection_map[newflags &
27650 (VM_READ|VM_WRITE|VM_EXEC)];
27651 dirty_accountable = 1;
27652+ } else {
27653+
27654+#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
27655+ if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
27656+ vma->vm_page_prot = protection_map[(newflags | VM_EXEC) &
27657+ (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27658+ else
27659+#endif
27660+
27661+ vma->vm_page_prot = protection_map[newflags &
27662+ (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
27663 }
27664
27665 if (is_vm_hugetlb_page(vma))
27666@@ -214,6 +327,69 @@ fail:
27667 return error;
27668 }
27669
27670+#ifdef CONFIG_PAX_MPROTECT
27671+/* PaX: non-PIC ELF libraries need relocations on their executable segments
27672+ * therefore we'll grant them VM_MAYWRITE once during their life.
27673+ *
27674+ * The checks favour ld-linux.so behaviour which operates on a per ELF segment
27675+ * basis because we want to allow the common case and not the special ones.
27676+ */
27677+static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
27678+{
27679+ struct elfhdr elf_h;
27680+ struct elf_phdr elf_p, p_dyn;
27681+ elf_dyn dyn;
27682+ unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
27683+
27684+#ifndef CONFIG_PAX_NOELFRELOCS
27685+ if ((vma->vm_start != start) ||
27686+ !vma->vm_file ||
27687+ !(vma->vm_flags & VM_MAYEXEC) ||
27688+ (vma->vm_flags & VM_MAYNOTWRITE))
27689+#endif
27690+
27691+ return;
27692+
27693+ if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
27694+ memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
27695+
27696+#ifdef CONFIG_PAX_ETEXECRELOCS
27697+ (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
27698+#else
27699+ elf_h.e_type != ET_DYN ||
27700+#endif
27701+
27702+ !elf_check_arch(&elf_h) ||
27703+ elf_h.e_phentsize != sizeof(struct elf_phdr) ||
27704+ elf_h.e_phnum > j)
27705+ return;
27706+
27707+ for (i = 0UL; i < elf_h.e_phnum; i++) {
27708+ if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
27709+ return;
27710+ if (elf_p.p_type == PT_DYNAMIC) {
27711+ p_dyn = elf_p;
27712+ j = i;
27713+ }
27714+ }
27715+ if (elf_h.e_phnum <= j)
27716+ return;
27717+
27718+ i = 0UL;
27719+ do {
27720+ if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
27721+ return;
27722+ if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
27723+ vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
27724+ gr_log_textrel(vma);
27725+ return;
27726+ }
27727+ i++;
27728+ } while (dyn.d_tag != DT_NULL);
27729+ return;
27730+}
27731+#endif
27732+
27733 asmlinkage long
27734 sys_mprotect(unsigned long start, size_t len, unsigned long prot)
27735 {
27736@@ -233,6 +409,17 @@ sys_mprotect(unsigned long start, size_t
27737 end = start + len;
27738 if (end <= start)
27739 return -ENOMEM;
27740+
27741+#ifdef CONFIG_PAX_SEGMEXEC
27742+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
27743+ if (end > SEGMEXEC_TASK_SIZE)
27744+ return -EINVAL;
27745+ } else
27746+#endif
27747+
27748+ if (end > TASK_SIZE)
27749+ return -EINVAL;
27750+
27751 if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
27752 return -EINVAL;
27753
27754@@ -240,7 +427,7 @@ sys_mprotect(unsigned long start, size_t
27755 /*
27756 * Does the application expect PROT_READ to imply PROT_EXEC:
27757 */
27758- if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
27759+ if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
27760 prot |= PROT_EXEC;
27761
27762 vm_flags = calc_vm_prot_bits(prot);
27763@@ -272,6 +459,16 @@ sys_mprotect(unsigned long start, size_t
27764 if (start > vma->vm_start)
27765 prev = vma;
27766
27767+ if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
27768+ error = -EACCES;
27769+ goto out;
27770+ }
27771+
27772+#ifdef CONFIG_PAX_MPROTECT
27773+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
27774+ pax_handle_maywrite(vma, start);
27775+#endif
27776+
27777 for (nstart = start ; ; ) {
27778 unsigned long newflags;
27779
27780@@ -285,6 +482,12 @@ sys_mprotect(unsigned long start, size_t
27781 goto out;
27782 }
27783
27784+#ifdef CONFIG_PAX_MPROTECT
27785+ /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
27786+ if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
27787+ newflags &= ~VM_MAYWRITE;
27788+#endif
27789+
27790 error = security_file_mprotect(vma, reqprot, prot);
27791 if (error)
27792 goto out;
27793@@ -308,6 +511,9 @@ sys_mprotect(unsigned long start, size_t
27794 goto out;
27795 }
27796 }
27797+
27798+ track_exec_limit(current->mm, start, end, vm_flags);
27799+
27800 out:
27801 up_write(&current->mm->mmap_sem);
27802 return error;
27803diff -urNp linux-2.6.19.1/mm/mremap.c linux-2.6.19.1/mm/mremap.c
27804--- linux-2.6.19.1/mm/mremap.c 2006-11-29 16:57:37.000000000 -0500
27805+++ linux-2.6.19.1/mm/mremap.c 2006-12-03 15:16:26.000000000 -0500
27806@@ -107,6 +107,12 @@ static void move_ptes(struct vm_area_str
27807 pte = ptep_clear_flush(vma, old_addr, old_pte);
27808 /* ZERO_PAGE can be dependant on virtual addr */
27809 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
27810+
27811+#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
27812+ if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
27813+ pte_exprotect(pte);
27814+#endif
27815+
27816 set_pte_at(mm, new_addr, new_pte, pte);
27817 }
27818
27819@@ -255,6 +261,7 @@ unsigned long do_mremap(unsigned long ad
27820 struct vm_area_struct *vma;
27821 unsigned long ret = -EINVAL;
27822 unsigned long charged = 0;
27823+ unsigned long task_size = TASK_SIZE;
27824
27825 if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
27826 goto out;
27827@@ -273,6 +280,15 @@ unsigned long do_mremap(unsigned long ad
27828 if (!new_len)
27829 goto out;
27830
27831+#ifdef CONFIG_PAX_SEGMEXEC
27832+ if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
27833+ task_size = SEGMEXEC_TASK_SIZE;
27834+#endif
27835+
27836+ if (new_len > task_size || addr > task_size-new_len ||
27837+ old_len > task_size || addr > task_size-old_len)
27838+ goto out;
27839+
27840 /* new_addr is only valid if MREMAP_FIXED is specified */
27841 if (flags & MREMAP_FIXED) {
27842 if (new_addr & ~PAGE_MASK)
27843@@ -280,16 +296,13 @@ unsigned long do_mremap(unsigned long ad
27844 if (!(flags & MREMAP_MAYMOVE))
27845 goto out;
27846
27847- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
27848+ if (new_addr > task_size - new_len)
27849 goto out;
27850
27851 /* Check if the location we're moving into overlaps the
27852 * old location at all, and fail if it does.
27853 */
27854- if ((new_addr <= addr) && (new_addr+new_len) > addr)
27855- goto out;
27856-
27857- if ((addr <= new_addr) && (addr+old_len) > new_addr)
27858+ if (addr + old_len > new_addr && new_addr + new_len > addr)
27859 goto out;
27860
27861 ret = do_munmap(mm, new_addr, new_len);
27862@@ -323,6 +336,14 @@ unsigned long do_mremap(unsigned long ad
27863 ret = -EINVAL;
27864 goto out;
27865 }
27866+
27867+#ifdef CONFIG_PAX_SEGMEXEC
27868+ if (vma->vm_flags & VM_MIRROR) {
27869+ ret = -EINVAL;
27870+ goto out;
27871+ }
27872+#endif
27873+
27874 /* We can't remap across vm area boundaries */
27875 if (old_len > vma->vm_end - addr)
27876 goto out;
27877@@ -356,7 +377,7 @@ unsigned long do_mremap(unsigned long ad
27878 if (old_len == vma->vm_end - addr &&
27879 !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
27880 (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
27881- unsigned long max_addr = TASK_SIZE;
27882+ unsigned long max_addr = task_size;
27883 if (vma->vm_next)
27884 max_addr = vma->vm_next->vm_start;
27885 /* can we just expand the current mapping? */
27886@@ -374,6 +395,7 @@ unsigned long do_mremap(unsigned long ad
27887 addr + new_len);
27888 }
27889 ret = addr;
27890+ track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
27891 goto out;
27892 }
27893 }
27894@@ -384,8 +406,8 @@ unsigned long do_mremap(unsigned long ad
27895 */
27896 ret = -ENOMEM;
27897 if (flags & MREMAP_MAYMOVE) {
27898+ unsigned long map_flags = 0;
27899 if (!(flags & MREMAP_FIXED)) {
27900- unsigned long map_flags = 0;
27901 if (vma->vm_flags & VM_MAYSHARE)
27902 map_flags |= MAP_SHARED;
27903
27904@@ -395,7 +417,12 @@ unsigned long do_mremap(unsigned long ad
27905 if (new_addr & ~PAGE_MASK)
27906 goto out;
27907 }
27908+ map_flags = vma->vm_flags;
27909 ret = move_vma(vma, addr, old_len, new_len, new_addr);
27910+ if (!(ret & ~PAGE_MASK)) {
27911+ track_exec_limit(current->mm, addr, addr + old_len, 0UL);
27912+ track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
27913+ }
27914 }
27915 out:
27916 if (ret & ~PAGE_MASK)
27917diff -urNp linux-2.6.19.1/mm/page_alloc.c linux-2.6.19.1/mm/page_alloc.c
27918--- linux-2.6.19.1/mm/page_alloc.c 2006-11-29 16:57:37.000000000 -0500
27919+++ linux-2.6.19.1/mm/page_alloc.c 2006-12-03 15:16:26.000000000 -0500
27920@@ -390,7 +390,7 @@ static inline int page_is_buddy(struct p
27921 static inline void __free_one_page(struct page *page,
27922 struct zone *zone, unsigned int order)
27923 {
27924- unsigned long page_idx;
27925+ unsigned long page_idx, index;
27926 int order_size = 1 << order;
27927
27928 if (unlikely(PageCompound(page)))
27929@@ -401,6 +401,11 @@ static inline void __free_one_page(struc
27930 VM_BUG_ON(page_idx & (order_size - 1));
27931 VM_BUG_ON(bad_range(zone, page));
27932
27933+#ifdef CONFIG_PAX_MEMORY_SANITIZE
27934+ for (index = order_size; index; --index)
27935+ clear_highpage(page + index - 1);
27936+#endif
27937+
27938 zone->free_pages += order_size;
27939 while (order < MAX_ORDER-1) {
27940 unsigned long combined_idx;
27941diff -urNp linux-2.6.19.1/mm/rmap.c linux-2.6.19.1/mm/rmap.c
27942--- linux-2.6.19.1/mm/rmap.c 2006-11-29 16:57:37.000000000 -0500
27943+++ linux-2.6.19.1/mm/rmap.c 2006-12-03 15:16:26.000000000 -0500
27944@@ -99,6 +99,19 @@ int anon_vma_prepare(struct vm_area_stru
27945 vma->anon_vma = anon_vma;
27946 list_add_tail(&vma->anon_vma_node, &anon_vma->head);
27947 allocated = NULL;
27948+
27949+#ifdef CONFIG_PAX_SEGMEXEC
27950+ if (vma->vm_flags & VM_MIRROR) {
27951+ struct vm_area_struct *vma_m;
27952+
27953+ vma_m = find_vma(vma->vm_mm, vma->vm_start + vma->vm_mirror);
27954+ BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
27955+ BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
27956+ vma_m->anon_vma = anon_vma;
27957+ __anon_vma_link(vma_m);
27958+ }
27959+#endif
27960+
27961 }
27962 spin_unlock(&mm->page_table_lock);
27963
27964diff -urNp linux-2.6.19.1/mm/shmem.c linux-2.6.19.1/mm/shmem.c
27965--- linux-2.6.19.1/mm/shmem.c 2006-11-29 16:57:37.000000000 -0500
27966+++ linux-2.6.19.1/mm/shmem.c 2006-12-03 15:16:26.000000000 -0500
27967@@ -2411,7 +2411,7 @@ static struct file_system_type tmpfs_fs_
27968 .get_sb = shmem_get_sb,
27969 .kill_sb = kill_litter_super,
27970 };
27971-static struct vfsmount *shm_mnt;
27972+struct vfsmount *shm_mnt;
27973
27974 static int __init init_tmpfs(void)
27975 {
27976diff -urNp linux-2.6.19.1/mm/slab.c linux-2.6.19.1/mm/slab.c
27977--- linux-2.6.19.1/mm/slab.c 2006-11-29 16:57:37.000000000 -0500
27978+++ linux-2.6.19.1/mm/slab.c 2006-12-03 15:16:26.000000000 -0500
27979@@ -1661,6 +1661,11 @@ static void store_stackinfo(struct kmem_
27980
27981 while (!kstack_end(sptr)) {
27982 svalue = *sptr++;
27983+
27984+#ifdef CONFIG_PAX_KERNEXEC
27985+ svalue += __KERNEL_TEXT_OFFSET;
27986+#endif
27987+
27988 if (kernel_text_address(svalue)) {
27989 *addr++ = svalue;
27990 size -= sizeof(unsigned long);
27991@@ -2116,7 +2121,7 @@ kmem_cache_create (const char *name, siz
27992 * area of the module. Print a warning.
27993 */
27994 set_fs(KERNEL_DS);
27995- res = __get_user(tmp, pc->name);
27996+ res = __get_user(tmp, (char __user *)pc->name);
27997 set_fs(old_fs);
27998 if (res) {
27999 printk("SLAB: cache with size %d has lost its name\n",
28000diff -urNp linux-2.6.19.1/mm/tiny-shmem.c linux-2.6.19.1/mm/tiny-shmem.c
28001--- linux-2.6.19.1/mm/tiny-shmem.c 2006-11-29 16:57:37.000000000 -0500
28002+++ linux-2.6.19.1/mm/tiny-shmem.c 2006-12-03 15:16:26.000000000 -0500
28003@@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
28004 .kill_sb = kill_litter_super,
28005 };
28006
28007-static struct vfsmount *shm_mnt;
28008+struct vfsmount *shm_mnt;
28009
28010 static int __init init_tmpfs(void)
28011 {
28012diff -urNp linux-2.6.19.1/mm/vmalloc.c linux-2.6.19.1/mm/vmalloc.c
28013--- linux-2.6.19.1/mm/vmalloc.c 2006-11-29 16:57:37.000000000 -0500
28014+++ linux-2.6.19.1/mm/vmalloc.c 2006-12-03 15:16:26.000000000 -0500
28015@@ -195,6 +195,8 @@ static struct vm_struct *__get_vm_area_n
28016
28017 write_lock(&vmlist_lock);
28018 for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
28019+ if (addr > end - size)
28020+ goto out;
28021 if ((unsigned long)tmp->addr < addr) {
28022 if((unsigned long)tmp->addr + tmp->size >= addr)
28023 addr = ALIGN(tmp->size +
28024@@ -206,8 +208,6 @@ static struct vm_struct *__get_vm_area_n
28025 if (size + addr <= (unsigned long)tmp->addr)
28026 goto found;
28027 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
28028- if (addr > end - size)
28029- goto out;
28030 }
28031
28032 found:
28033diff -urNp linux-2.6.19.1/net/core/sock.c linux-2.6.19.1/net/core/sock.c
28034--- linux-2.6.19.1/net/core/sock.c 2006-11-29 16:57:37.000000000 -0500
28035+++ linux-2.6.19.1/net/core/sock.c 2006-12-03 15:16:26.000000000 -0500
28036@@ -804,7 +804,7 @@ lenout:
28037 *
28038 * (We also register the sk_lock with the lock validator.)
28039 */
28040-static void inline sock_lock_init(struct sock *sk)
28041+static inline void sock_lock_init(struct sock *sk)
28042 {
28043 spin_lock_init(&sk->sk_lock.slock);
28044 sk->sk_lock.owner = NULL;
28045diff -urNp linux-2.6.19.1/net/dccp/ccids/ccid3.c linux-2.6.19.1/net/dccp/ccids/ccid3.c
28046--- linux-2.6.19.1/net/dccp/ccids/ccid3.c 2006-11-29 16:57:37.000000000 -0500
28047+++ linux-2.6.19.1/net/dccp/ccids/ccid3.c 2006-12-03 15:16:26.000000000 -0500
28048@@ -68,7 +68,7 @@ static int ccid3_debug;
28049 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
28050 } while (0)
28051 #else
28052-#define ccid3_pr_debug(format, a...)
28053+#define ccid3_pr_debug(format, a...) do {} while (0)
28054 #endif
28055
28056 static struct dccp_tx_hist *ccid3_tx_hist;
28057diff -urNp linux-2.6.19.1/net/dccp/dccp.h linux-2.6.19.1/net/dccp/dccp.h
28058--- linux-2.6.19.1/net/dccp/dccp.h 2006-11-29 16:57:37.000000000 -0500
28059+++ linux-2.6.19.1/net/dccp/dccp.h 2006-12-03 15:16:26.000000000 -0500
28060@@ -28,8 +28,8 @@ extern int dccp_debug;
28061 #define dccp_pr_debug_cat(format, a...) do { if (dccp_debug) \
28062 printk(format, ##a); } while (0)
28063 #else
28064-#define dccp_pr_debug(format, a...)
28065-#define dccp_pr_debug_cat(format, a...)
28066+#define dccp_pr_debug(format, a...) do {} while (0)
28067+#define dccp_pr_debug_cat(format, a...) do {} while (0)
28068 #endif
28069
28070 extern struct inet_hashinfo dccp_hashinfo;
28071diff -urNp linux-2.6.19.1/net/ipv4/inet_connection_sock.c linux-2.6.19.1/net/ipv4/inet_connection_sock.c
28072--- linux-2.6.19.1/net/ipv4/inet_connection_sock.c 2006-11-29 16:57:37.000000000 -0500
28073+++ linux-2.6.19.1/net/ipv4/inet_connection_sock.c 2006-12-03 15:16:27.000000000 -0500
28074@@ -15,6 +15,7 @@
28075
28076 #include <linux/module.h>
28077 #include <linux/jhash.h>
28078+#include <linux/grsecurity.h>
28079
28080 #include <net/inet_connection_sock.h>
28081 #include <net/inet_hashtables.h>
28082diff -urNp linux-2.6.19.1/net/ipv4/inet_hashtables.c linux-2.6.19.1/net/ipv4/inet_hashtables.c
28083--- linux-2.6.19.1/net/ipv4/inet_hashtables.c 2006-11-29 16:57:37.000000000 -0500
28084+++ linux-2.6.19.1/net/ipv4/inet_hashtables.c 2006-12-03 15:16:27.000000000 -0500
28085@@ -18,11 +18,14 @@
28086 #include <linux/sched.h>
28087 #include <linux/slab.h>
28088 #include <linux/wait.h>
28089+#include <linux/grsecurity.h>
28090
28091 #include <net/inet_connection_sock.h>
28092 #include <net/inet_hashtables.h>
28093 #include <net/ip.h>
28094
28095+extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
28096+
28097 /*
28098 * Allocate and initialize a new local port bind bucket.
28099 * The bindhash mutex for snum's hash chain must be held here.
28100@@ -338,6 +341,8 @@ ok:
28101 }
28102 spin_unlock(&head->lock);
28103
28104+ gr_update_task_in_ip_table(current, inet_sk(sk));
28105+
28106 if (tw) {
28107 inet_twsk_deschedule(tw, death_row);
28108 inet_twsk_put(tw);
28109diff -urNp linux-2.6.19.1/net/ipv4/netfilter/ipt_stealth.c linux-2.6.19.1/net/ipv4/netfilter/ipt_stealth.c
28110--- linux-2.6.19.1/net/ipv4/netfilter/ipt_stealth.c 1969-12-31 19:00:00.000000000 -0500
28111+++ linux-2.6.19.1/net/ipv4/netfilter/ipt_stealth.c 2006-12-03 15:16:27.000000000 -0500
28112@@ -0,0 +1,116 @@
28113+/* Kernel module to add stealth support.
28114+ *
28115+ * Copyright (C) 2002,2005 Brad Spengler <spender@grsecurity.net>
28116+ *
28117+ */
28118+
28119+#include <linux/kernel.h>
28120+#include <linux/module.h>
28121+#include <linux/skbuff.h>
28122+#include <linux/net.h>
28123+#include <linux/sched.h>
28124+#include <linux/inet.h>
28125+#include <linux/stddef.h>
28126+
28127+#include <net/ip.h>
28128+#include <net/sock.h>
28129+#include <net/tcp.h>
28130+#include <net/udp.h>
28131+#include <net/route.h>
28132+#include <net/inet_common.h>
28133+
28134+#include <linux/netfilter_ipv4/ip_tables.h>
28135+
28136+MODULE_LICENSE("GPL");
28137+
28138+extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
28139+
28140+static int
28141+match(const struct sk_buff *skb,
28142+ const struct net_device *in,
28143+ const struct net_device *out,
28144+ const struct xt_match *match,
28145+ const void *matchinfo,
28146+ int offset,
28147+ unsigned int protoff,
28148+ int *hotdrop)
28149+{
28150+ struct iphdr *ip = skb->nh.iph;
28151+ struct tcphdr th;
28152+ struct udphdr uh;
28153+ struct sock *sk = NULL;
28154+
28155+ if (!ip || offset) return 0;
28156+
28157+ switch(ip->protocol) {
28158+ case IPPROTO_TCP:
28159+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
28160+ *hotdrop = 1;
28161+ return 0;
28162+ }
28163+ if (!(th.syn && !th.ack)) return 0;
28164+ sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);
28165+ break;
28166+ case IPPROTO_UDP:
28167+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
28168+ *hotdrop = 1;
28169+ return 0;
28170+ }
28171+ sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
28172+ break;
28173+ default:
28174+ return 0;
28175+ }
28176+
28177+ if(!sk) // port is being listened on, match this
28178+ return 1;
28179+ else {
28180+ sock_put(sk);
28181+ return 0;
28182+ }
28183+}
28184+
28185+/* Called when user tries to insert an entry of this type. */
28186+static int
28187+checkentry(const char *tablename,
28188+ const void *nip,
28189+ const struct xt_match *match,
28190+ void *matchinfo,
28191+ unsigned int matchsize,
28192+ unsigned int hook_mask)
28193+{
28194+ const struct ipt_ip *ip = (const struct ipt_ip *)nip;
28195+ if (matchsize != IPT_ALIGN(0))
28196+ return 0;
28197+
28198+ if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
28199+ ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
28200+ && (hook_mask & (1 << NF_IP_LOCAL_IN)))
28201+ return 1;
28202+
28203+ printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
28204+
28205+ return 0;
28206+}
28207+
28208+
28209+static struct ipt_match stealth_match = {
28210+ .name = "stealth",
28211+ .match = match,
28212+ .checkentry = checkentry,
28213+ .destroy = NULL,
28214+ .me = THIS_MODULE
28215+};
28216+
28217+static int __init init(void)
28218+{
28219+ return ipt_register_match(&stealth_match);
28220+}
28221+
28222+static void __exit fini(void)
28223+{
28224+ ipt_unregister_match(&stealth_match);
28225+}
28226+
28227+module_init(init);
28228+module_exit(fini);
28229diff -urNp linux-2.6.19.1/net/ipv4/netfilter/Kconfig linux-2.6.19.1/net/ipv4/netfilter/Kconfig
28230--- linux-2.6.19.1/net/ipv4/netfilter/Kconfig 2006-11-29 16:57:37.000000000 -0500
28231+++ linux-2.6.19.1/net/ipv4/netfilter/Kconfig 2006-12-03 15:16:27.000000000 -0500
28232@@ -329,6 +329,21 @@ config IP_NF_MATCH_HASHLIMIT
28233 destination IP' or `500pps from any given source IP' with a single
28234 IPtables rule.
28235
28236+config IP_NF_MATCH_STEALTH
28237+ tristate "stealth match support"
28238+ depends on IP_NF_IPTABLES
28239+ help
28240+ Enabling this option will drop all syn packets coming to unserved tcp
28241+ ports as well as all packets coming to unserved udp ports. If you
28242+ are using your system to route any type of packets (ie. via NAT)
28243+ you should put this module at the end of your ruleset, since it will
28244+ drop packets that aren't going to ports that are listening on your
28245+ machine itself, it doesn't take into account that the packet might be
28246+ destined for someone on your internal network if you're using NAT for
28247+ instance.
28248+
28249+ To compile it as a module, choose M here. If unsure, say N.
28250+
28251 # `filter', generic and specific targets
28252 config IP_NF_FILTER
28253 tristate "Packet filtering"
28254@@ -624,4 +639,3 @@ config IP_NF_ARP_MANGLE
28255 hardware and network addresses.
28256
28257 endmenu
28258-
28259diff -urNp linux-2.6.19.1/net/ipv4/netfilter/Makefile linux-2.6.19.1/net/ipv4/netfilter/Makefile
28260--- linux-2.6.19.1/net/ipv4/netfilter/Makefile 2006-11-29 16:57:37.000000000 -0500
28261+++ linux-2.6.19.1/net/ipv4/netfilter/Makefile 2006-12-03 15:16:27.000000000 -0500
28262@@ -62,6 +62,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn
28263 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
28264 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
28265 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
28266+obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
28267
28268 # targets
28269 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
28270diff -urNp linux-2.6.19.1/net/ipv4/tcp_ipv4.c linux-2.6.19.1/net/ipv4/tcp_ipv4.c
28271--- linux-2.6.19.1/net/ipv4/tcp_ipv4.c 2006-11-29 16:57:37.000000000 -0500
28272+++ linux-2.6.19.1/net/ipv4/tcp_ipv4.c 2006-12-03 15:16:27.000000000 -0500
28273@@ -61,6 +61,7 @@
28274 #include <linux/jhash.h>
28275 #include <linux/init.h>
28276 #include <linux/times.h>
28277+#include <linux/grsecurity.h>
28278
28279 #include <net/icmp.h>
28280 #include <net/inet_hashtables.h>
28281diff -urNp linux-2.6.19.1/net/ipv4/udp.c linux-2.6.19.1/net/ipv4/udp.c
28282--- linux-2.6.19.1/net/ipv4/udp.c 2006-11-29 16:57:37.000000000 -0500
28283+++ linux-2.6.19.1/net/ipv4/udp.c 2006-12-03 15:16:27.000000000 -0500
28284@@ -101,6 +101,7 @@
28285 #include <linux/skbuff.h>
28286 #include <linux/proc_fs.h>
28287 #include <linux/seq_file.h>
28288+#include <linux/grsecurity.h>
28289 #include <net/sock.h>
28290 #include <net/udp.h>
28291 #include <net/icmp.h>
28292@@ -109,6 +110,12 @@
28293 #include <net/checksum.h>
28294 #include <net/xfrm.h>
28295
28296+extern int gr_search_udp_recvmsg(const struct sock *sk,
28297+ const struct sk_buff *skb);
28298+extern int gr_search_udp_sendmsg(const struct sock *sk,
28299+ const struct sockaddr_in *addr);
28300+
28301+
28302 /*
28303 * Snmp MIB for the UDP layer
28304 */
28305@@ -288,8 +295,8 @@ static struct sock *udp_v4_lookup_longwa
28306 return result;
28307 }
28308
28309-static __inline__ struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
28310- __be32 daddr, __be16 dport, int dif)
28311+struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
28312+ __be32 daddr, __be16 dport, int dif)
28313 {
28314 struct sock *sk;
28315
28316@@ -564,9 +571,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
28317 dport = usin->sin_port;
28318 if (dport == 0)
28319 return -EINVAL;
28320+
28321+ if (!gr_search_udp_sendmsg(sk, usin))
28322+ return -EPERM;
28323 } else {
28324 if (sk->sk_state != TCP_ESTABLISHED)
28325 return -EDESTADDRREQ;
28326+
28327+ if (!gr_search_udp_sendmsg(sk, NULL))
28328+ return -EPERM;
28329+
28330 daddr = inet->daddr;
28331 dport = inet->dport;
28332 /* Open fast path for connected socket.
28333@@ -833,6 +847,11 @@ try_again:
28334 if (!skb)
28335 goto out;
28336
28337+ if (!gr_search_udp_recvmsg(sk, skb)) {
28338+ err = -EPERM;
28339+ goto out_free;
28340+ }
28341+
28342 copied = skb->len - sizeof(struct udphdr);
28343 if (copied > len) {
28344 copied = len;
28345diff -urNp linux-2.6.19.1/net/ipv6/addrconf.c linux-2.6.19.1/net/ipv6/addrconf.c
28346--- linux-2.6.19.1/net/ipv6/addrconf.c 2006-11-29 16:57:37.000000000 -0500
28347+++ linux-2.6.19.1/net/ipv6/addrconf.c 2006-12-03 15:16:27.000000000 -0500
28348@@ -869,7 +869,7 @@ struct ipv6_saddr_score {
28349 #define IPV6_SADDR_SCORE_LABEL 0x0020
28350 #define IPV6_SADDR_SCORE_PRIVACY 0x0040
28351
28352-static int inline ipv6_saddr_preferred(int type)
28353+static inline int ipv6_saddr_preferred(int type)
28354 {
28355 if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
28356 IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
28357@@ -878,7 +878,7 @@ static int inline ipv6_saddr_preferred(i
28358 }
28359
28360 /* static matching label */
28361-static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
28362+static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
28363 {
28364 /*
28365 * prefix (longest match) label
28366@@ -3362,7 +3362,7 @@ errout:
28367 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
28368 }
28369
28370-static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
28371+static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
28372 __s32 *array, int bytes)
28373 {
28374 memset(array, 0, bytes);
28375diff -urNp linux-2.6.19.1/net/ipv6/raw.c linux-2.6.19.1/net/ipv6/raw.c
28376--- linux-2.6.19.1/net/ipv6/raw.c 2006-11-29 16:57:37.000000000 -0500
28377+++ linux-2.6.19.1/net/ipv6/raw.c 2006-12-03 15:16:29.000000000 -0500
28378@@ -549,7 +549,7 @@ out:
28379 return err;
28380 }
28381
28382-static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
28383+static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
28384 struct flowi *fl, struct rt6_info *rt,
28385 unsigned int flags)
28386 {
28387@@ -691,7 +691,7 @@ static int rawv6_sendmsg(struct kiocb *i
28388 /* Rough check on arithmetic overflow,
28389 better check is made in ip6_build_xmit
28390 */
28391- if (len < 0)
28392+ if ((ssize_t)len < 0)
28393 return -EMSGSIZE;
28394
28395 /* Mirror BSD error message compatibility */
28396diff -urNp linux-2.6.19.1/net/ipv6/route.c linux-2.6.19.1/net/ipv6/route.c
28397--- linux-2.6.19.1/net/ipv6/route.c 2006-11-29 16:57:37.000000000 -0500
28398+++ linux-2.6.19.1/net/ipv6/route.c 2006-12-03 15:16:29.000000000 -0500
28399@@ -308,7 +308,7 @@ static inline void rt6_probe(struct rt6_
28400 /*
28401 * Default Router Selection (RFC 2461 6.3.6)
28402 */
28403-static int inline rt6_check_dev(struct rt6_info *rt, int oif)
28404+static inline int rt6_check_dev(struct rt6_info *rt, int oif)
28405 {
28406 struct net_device *dev = rt->rt6i_dev;
28407 if (!oif || dev->ifindex == oif)
28408@@ -319,7 +319,7 @@ static int inline rt6_check_dev(struct r
28409 return 0;
28410 }
28411
28412-static int inline rt6_check_neigh(struct rt6_info *rt)
28413+static inline int rt6_check_neigh(struct rt6_info *rt)
28414 {
28415 struct neighbour *neigh = rt->rt6i_nexthop;
28416 int m = 0;
28417diff -urNp linux-2.6.19.1/net/ipv6/xfrm6_tunnel.c linux-2.6.19.1/net/ipv6/xfrm6_tunnel.c
28418--- linux-2.6.19.1/net/ipv6/xfrm6_tunnel.c 2006-11-29 16:57:37.000000000 -0500
28419+++ linux-2.6.19.1/net/ipv6/xfrm6_tunnel.c 2006-12-03 15:16:29.000000000 -0500
28420@@ -58,7 +58,7 @@ static kmem_cache_t *xfrm6_tunnel_spi_km
28421 static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
28422 static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
28423
28424-static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
28425+static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
28426 {
28427 unsigned h;
28428
28429@@ -70,7 +70,7 @@ static unsigned inline xfrm6_tunnel_spi_
28430 return h;
28431 }
28432
28433-static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
28434+static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
28435 {
28436 return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
28437 }
28438diff -urNp linux-2.6.19.1/net/sctp/sm_statetable.c linux-2.6.19.1/net/sctp/sm_statetable.c
28439--- linux-2.6.19.1/net/sctp/sm_statetable.c 2006-11-29 16:57:37.000000000 -0500
28440+++ linux-2.6.19.1/net/sctp/sm_statetable.c 2006-12-03 15:16:29.000000000 -0500
28441@@ -986,7 +986,7 @@ static const sctp_sm_table_entry_t *sctp
28442 if (state > SCTP_STATE_MAX)
28443 return &bug;
28444
28445- if (cid >= 0 && cid <= SCTP_CID_BASE_MAX)
28446+ if (cid <= SCTP_CID_BASE_MAX)
28447 return &chunk_event_table[cid][state];
28448
28449 if (sctp_prsctp_enable) {
28450diff -urNp linux-2.6.19.1/net/socket.c linux-2.6.19.1/net/socket.c
28451--- linux-2.6.19.1/net/socket.c 2006-11-29 16:57:37.000000000 -0500
28452+++ linux-2.6.19.1/net/socket.c 2006-12-03 15:16:29.000000000 -0500
28453@@ -85,6 +85,7 @@
28454 #include <linux/kmod.h>
28455 #include <linux/audit.h>
28456 #include <linux/wireless.h>
28457+#include <linux/in.h>
28458
28459 #include <asm/uaccess.h>
28460 #include <asm/unistd.h>
28461@@ -94,6 +95,21 @@
28462 #include <net/sock.h>
28463 #include <linux/netfilter.h>
28464
28465+extern void gr_attach_curr_ip(const struct sock *sk);
28466+extern int gr_handle_sock_all(const int family, const int type,
28467+ const int protocol);
28468+extern int gr_handle_sock_server(const struct sockaddr *sck);
28469+extern int gr_handle_sock_server_other(const struct socket *sck);
28470+extern int gr_handle_sock_client(const struct sockaddr *sck);
28471+extern int gr_search_connect(const struct socket * sock,
28472+ const struct sockaddr_in * addr);
28473+extern int gr_search_bind(const struct socket * sock,
28474+ const struct sockaddr_in * addr);
28475+extern int gr_search_listen(const struct socket * sock);
28476+extern int gr_search_accept(const struct socket * sock);
28477+extern int gr_search_socket(const int domain, const int type,
28478+ const int protocol);
28479+
28480 static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
28481 static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
28482 unsigned long nr_segs, loff_t pos);
28483@@ -296,7 +312,7 @@ static int sockfs_get_sb(struct file_sys
28484 mnt);
28485 }
28486
28487-static struct vfsmount *sock_mnt __read_mostly;
28488+struct vfsmount *sock_mnt __read_mostly;
28489
28490 static struct file_system_type sock_fs_type = {
28491 .name = "sockfs",
28492@@ -1174,6 +1190,16 @@ asmlinkage long sys_socket(int family, i
28493 int retval;
28494 struct socket *sock;
28495
28496+ if(!gr_search_socket(family, type, protocol)) {
28497+ retval = -EACCES;
28498+ goto out;
28499+ }
28500+
28501+ if (gr_handle_sock_all(family, type, protocol)) {
28502+ retval = -EACCES;
28503+ goto out;
28504+ }
28505+
28506 retval = sock_create(family, type, protocol, &sock);
28507 if (retval < 0)
28508 goto out;
28509@@ -1269,12 +1295,20 @@ asmlinkage long sys_bind(int fd, struct
28510 {
28511 struct socket *sock;
28512 char address[MAX_SOCK_ADDR];
28513+ struct sockaddr *sck;
28514 int err, fput_needed;
28515
28516 sock = sockfd_lookup_light(fd, &err, &fput_needed);
28517 if(sock) {
28518 err = move_addr_to_kernel(umyaddr, addrlen, address);
28519 if (err >= 0) {
28520+ sck = (struct sockaddr *)address;
28521+ if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
28522+ gr_handle_sock_server(sck)) {
28523+ err = -EACCES;
28524+ goto error;
28525+ }
28526+
28527 err = security_socket_bind(sock,
28528 (struct sockaddr *)address,
28529 addrlen);
28530@@ -1283,6 +1317,7 @@ asmlinkage long sys_bind(int fd, struct
28531 (struct sockaddr *)
28532 address, addrlen);
28533 }
28534+error:
28535 fput_light(sock->file, fput_needed);
28536 }
28537 return err;
28538@@ -1306,10 +1341,17 @@ asmlinkage long sys_listen(int fd, int b
28539 if ((unsigned)backlog > sysctl_somaxconn)
28540 backlog = sysctl_somaxconn;
28541
28542+ if (gr_handle_sock_server_other(sock) ||
28543+ !gr_search_listen(sock)) {
28544+ err = -EPERM;
28545+ goto error;
28546+ }
28547+
28548 err = security_socket_listen(sock, backlog);
28549 if (!err)
28550 err = sock->ops->listen(sock, backlog);
28551
28552+error:
28553 fput_light(sock->file, fput_needed);
28554 }
28555 return err;
28556@@ -1346,6 +1388,13 @@ asmlinkage long sys_accept(int fd, struc
28557 newsock->type = sock->type;
28558 newsock->ops = sock->ops;
28559
28560+ if (gr_handle_sock_server_other(sock) ||
28561+ !gr_search_accept(sock)) {
28562+ err = -EPERM;
28563+ sock_release(newsock);
28564+ goto out_put;
28565+ }
28566+
28567 /*
28568 * We don't need try_module_get here, as the listening socket (sock)
28569 * has the protocol module (sock->ops->owner) held.
28570@@ -1389,6 +1438,7 @@ asmlinkage long sys_accept(int fd, struc
28571 err = newfd;
28572
28573 security_socket_post_accept(sock, newsock);
28574+ gr_attach_curr_ip(newsock->sk);
28575
28576 out_put:
28577 fput_light(sock->file, fput_needed);
28578@@ -1417,6 +1467,7 @@ asmlinkage long sys_connect(int fd, stru
28579 {
28580 struct socket *sock;
28581 char address[MAX_SOCK_ADDR];
28582+ struct sockaddr *sck;
28583 int err, fput_needed;
28584
28585 sock = sockfd_lookup_light(fd, &err, &fput_needed);
28586@@ -1426,6 +1477,13 @@ asmlinkage long sys_connect(int fd, stru
28587 if (err < 0)
28588 goto out_put;
28589
28590+ sck = (struct sockaddr *)address;
28591+ if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
28592+ gr_handle_sock_client(sck)) {
28593+ err = -EACCES;
28594+ goto out_put;
28595+ }
28596+
28597 err =
28598 security_socket_connect(sock, (struct sockaddr *)address, addrlen);
28599 if (err)
28600@@ -1699,6 +1757,7 @@ asmlinkage long sys_shutdown(int fd, int
28601 err = sock->ops->shutdown(sock, how);
28602 fput_light(sock->file, fput_needed);
28603 }
28604+
28605 return err;
28606 }
28607
28608diff -urNp linux-2.6.19.1/net/unix/af_unix.c linux-2.6.19.1/net/unix/af_unix.c
28609--- linux-2.6.19.1/net/unix/af_unix.c 2006-11-29 16:57:37.000000000 -0500
28610+++ linux-2.6.19.1/net/unix/af_unix.c 2006-12-03 15:16:30.000000000 -0500
28611@@ -116,6 +116,7 @@
c3e8c1b5 28612 #include <linux/security.h>
5c9295bc 28613 #include <linux/vs_context.h>
28614 #include <linux/vs_limit.h>
c3e8c1b5 28615+#include <linux/grsecurity.h>
28616
28617 int sysctl_unix_max_dgram_qlen __read_mostly = 10;
28618
28619@@ -706,6 +707,11 @@ static struct sock *unix_find_other(stru
28620 if (err)
28621 goto put_fail;
28622
28623+ if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
28624+ err = -EACCES;
28625+ goto put_fail;
28626+ }
28627+
28628 err = -ECONNREFUSED;
28629 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
28630 goto put_fail;
28631@@ -729,6 +735,13 @@ static struct sock *unix_find_other(stru
28632 if (u) {
28633 struct dentry *dentry;
28634 dentry = unix_sk(u)->dentry;
28635+
28636+ if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
28637+ err = -EPERM;
28638+ sock_put(u);
28639+ goto fail;
28640+ }
28641+
28642 if (dentry)
28643 touch_atime(unix_sk(u)->mnt, dentry);
28644 } else
28645@@ -807,9 +820,18 @@ static int unix_bind(struct socket *sock
28646 */
28647 mode = S_IFSOCK |
28648 (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
28649+
28650+ if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
28651+ err = -EACCES;
28652+ goto out_mknod_dput;
28653+ }
28654+
5c9295bc 28655 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
c3e8c1b5 28656 if (err)
28657 goto out_mknod_dput;
28658+
28659+ gr_handle_create(dentry, nd.mnt);
28660+
28661 mutex_unlock(&nd.dentry->d_inode->i_mutex);
28662 dput(nd.dentry);
28663 nd.dentry = dentry;
28664@@ -827,6 +849,10 @@ static int unix_bind(struct socket *sock
28665 goto out_unlock;
28666 }
28667
28668+#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
28669+ sk->sk_peercred.pid = current->pid;
28670+#endif
28671+
28672 list = &unix_socket_table[addr->hash];
28673 } else {
28674 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
28675diff -urNp linux-2.6.19.1/net/xfrm/xfrm_user.c linux-2.6.19.1/net/xfrm/xfrm_user.c
28676--- linux-2.6.19.1/net/xfrm/xfrm_user.c 2006-11-29 16:57:37.000000000 -0500
28677+++ linux-2.6.19.1/net/xfrm/xfrm_user.c 2006-12-03 15:16:30.000000000 -0500
28678@@ -1782,7 +1782,7 @@ nlmsg_failure:
28679 return -1;
28680 }
28681
28682-static int inline xfrm_sa_len(struct xfrm_state *x)
28683+static inline int xfrm_sa_len(struct xfrm_state *x)
28684 {
28685 int l = 0;
28686 if (x->aalg)
28687diff -urNp linux-2.6.19.1/scripts/Kbuild.include linux-2.6.19.1/scripts/Kbuild.include
28688--- linux-2.6.19.1/scripts/Kbuild.include 2006-11-29 16:57:37.000000000 -0500
28689+++ linux-2.6.19.1/scripts/Kbuild.include 2006-12-10 21:43:36.000000000 -0500
28690@@ -66,9 +66,8 @@ as-option = $(shell if $(CC) $(CFLAGS) $
28691 # as-instr
28692 # Usage: cflags-y += $(call as-instr, instr, option1, option2)
28693
28694-as-instr = $(shell if echo -e "$(1)" | $(AS) >/dev/null 2>&1 -W -Z -o astest$$$$.out ; \
28695- then echo "$(2)"; else echo "$(3)"; fi; \
28696- rm -f astest$$$$.out)
28697+as-instr = $(shell if echo -e "$(1)" | $(AS) >/dev/null 2>&1 -W -Z -o /dev/null ; \
28698+ then echo "$(2)"; else echo "$(3)"; fi; )
28699
28700 # cc-option
28701 # Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586)
28702diff -urNp linux-2.6.19.1/security/commoncap.c linux-2.6.19.1/security/commoncap.c
28703--- linux-2.6.19.1/security/commoncap.c 2006-11-29 16:57:37.000000000 -0500
28704+++ linux-2.6.19.1/security/commoncap.c 2006-12-03 15:16:30.000000000 -0500
62894557 28705@@ -23,6 +23,7 @@
c3e8c1b5 28706 #include <linux/xattr.h>
28707 #include <linux/hugetlb.h>
62894557 28708 #include <linux/vs_context.h>
c3e8c1b5 28709+#include <linux/grsecurity.h>
28710
28711 int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
28712 {
c3e8c1b5 28713@@ -44,7 +45,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
28714 int cap_capable (struct task_struct *tsk, int cap)
28715 {
28716 /* Derived from include/linux/sched.h:capable. */
62894557 28717- if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
28718+ if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap) && gr_task_is_capable(tsk, cap))
c3e8c1b5 28719+ return 0;
28720+ return -EPERM;
28721+}
28722+
28723+int cap_capable_nolog (struct task_struct *tsk, int cap)
28724+{
28725+ /* Derived from include/linux/sched.h:capable. */
da3dbdc5 28726+ if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
c3e8c1b5 28727 return 0;
28728 return -EPERM;
28729 }
28730@@ -163,8 +172,11 @@ void cap_bprm_apply_creds (struct linux_
28731 }
28732 }
28733
28734- current->suid = current->euid = current->fsuid = bprm->e_uid;
28735- current->sgid = current->egid = current->fsgid = bprm->e_gid;
28736+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
28737+ current->suid = current->euid = current->fsuid = bprm->e_uid;
28738+
28739+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
28740+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
28741
28742 /* For init, we want to retain the capabilities set
28743 * in the init_task struct. Thus we skip the usual
28744@@ -175,6 +187,8 @@ void cap_bprm_apply_creds (struct linux_
28745 cap_intersect (new_permitted, bprm->cap_effective);
28746 }
28747
28748+ gr_handle_chroot_caps(current);
28749+
28750 /* AUD: Audit candidate if current->cap_effective is set */
28751
28752 current->keep_capabilities = 0;
28753@@ -320,12 +334,13 @@ int cap_vm_enough_memory(long pages)
28754 {
28755 int cap_sys_admin = 0;
28756
28757- if (cap_capable(current, CAP_SYS_ADMIN) == 0)
28758+ if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
28759 cap_sys_admin = 1;
28760 return __vm_enough_memory(pages, cap_sys_admin);
28761 }
28762
28763 EXPORT_SYMBOL(cap_capable);
28764+EXPORT_SYMBOL(cap_capable_nolog);
28765 EXPORT_SYMBOL(cap_settime);
28766 EXPORT_SYMBOL(cap_ptrace);
28767 EXPORT_SYMBOL(cap_capget);
28768diff -urNp linux-2.6.19.1/security/dummy.c linux-2.6.19.1/security/dummy.c
28769--- linux-2.6.19.1/security/dummy.c 2006-11-29 16:57:37.000000000 -0500
28770+++ linux-2.6.19.1/security/dummy.c 2006-12-03 15:16:30.000000000 -0500
28771@@ -28,6 +28,7 @@
c3e8c1b5 28772 #include <linux/ptrace.h>
28773 #include <linux/file.h>
62894557 28774 #include <linux/vs_context.h>
c3e8c1b5 28775+#include <linux/grsecurity.h>
28776
28777 static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
28778 {
28779@@ -138,8 +139,11 @@ static void dummy_bprm_apply_creds (stru
28780 }
28781 }
28782
28783- current->suid = current->euid = current->fsuid = bprm->e_uid;
28784- current->sgid = current->egid = current->fsgid = bprm->e_gid;
28785+ if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
28786+ current->suid = current->euid = current->fsuid = bprm->e_uid;
28787+
28788+ if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
28789+ current->sgid = current->egid = current->fsgid = bprm->e_gid;
28790
28791 dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
28792 }
28793diff -urNp linux-2.6.19.1/security/Kconfig linux-2.6.19.1/security/Kconfig
28794--- linux-2.6.19.1/security/Kconfig 2006-11-29 16:57:37.000000000 -0500
28795+++ linux-2.6.19.1/security/Kconfig 2006-12-03 15:16:30.000000000 -0500
28796@@ -4,6 +4,432 @@
28797
28798 menu "Security options"
28799
28800+menu "PaX"
28801+
28802+config PAX
28803+ bool "Enable various PaX features"
28804+ depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
28805+ help
28806+ This allows you to enable various PaX features. PaX adds
28807+ intrusion prevention mechanisms to the kernel that reduce
28808+ the risks posed by exploitable memory corruption bugs.
28809+
28810+menu "PaX Control"
28811+ depends on PAX
28812+
28813+config PAX_SOFTMODE
28814+ bool 'Support soft mode'
28815+ help
28816+ Enabling this option will allow you to run PaX in soft mode, that
28817+ is, PaX features will not be enforced by default, only on executables
28818+ marked explicitly. You must also enable PT_PAX_FLAGS support as it
28819+ is the only way to mark executables for soft mode use.
28820+
28821+ Soft mode can be activated by using the "pax_softmode=1" kernel command
28822+ line option on boot. Furthermore you can control various PaX features
28823+ at runtime via the entries in /proc/sys/kernel/pax.
28824+
28825+config PAX_EI_PAX
28826+ bool 'Use legacy ELF header marking'
28827+ help
28828+ Enabling this option will allow you to control PaX features on
28829+ a per executable basis via the 'chpax' utility available at
28830+ http://pax.grsecurity.net/. The control flags will be read from
28831+ an otherwise reserved part of the ELF header. This marking has
28832+ numerous drawbacks (no support for soft-mode, toolchain does not
28833+ know about the non-standard use of the ELF header) therefore it
28834+ has been deprecated in favour of PT_PAX_FLAGS support.
28835+
28836+ If you have applications not marked by the PT_PAX_FLAGS ELF
28837+ program header then you MUST enable this option otherwise they
28838+ will not get any protection.
28839+
28840+ Note that if you enable PT_PAX_FLAGS marking support as well,
28841+ the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
28842+
28843+config PAX_PT_PAX_FLAGS
28844+ bool 'Use ELF program header marking'
28845+ help
28846+ Enabling this option will allow you to control PaX features on
28847+ a per executable basis via the 'paxctl' utility available at
28848+ http://pax.grsecurity.net/. The control flags will be read from
28849+ a PaX specific ELF program header (PT_PAX_FLAGS). This marking
28850+ has the benefits of supporting both soft mode and being fully
28851+ integrated into the toolchain (the binutils patch is available
28852+ from http://pax.grsecurity.net).
28853+
28854+ If you have applications not marked by the PT_PAX_FLAGS ELF
28855+ program header then you MUST enable the EI_PAX marking support
28856+ otherwise they will not get any protection.
28857+
28858+ Note that if you enable the legacy EI_PAX marking support as well,
28859+ the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
28860+
28861+choice
28862+ prompt 'MAC system integration'
28863+ default PAX_NO_ACL_FLAGS
28864+ help
28865+ Mandatory Access Control systems have the option of controlling
28866+ PaX flags on a per executable basis, choose the method supported
28867+ by your particular system.
28868+
28869+ - "none": if your MAC system does not interact with PaX,
28870+ - "direct": if your MAC system defines pax_set_flags() itself,
28871+ - "hook": if your MAC system uses the pax_set_flags_func callback.
28872+
28873+ NOTE: this option is for developers/integrators only.
28874+
28875+config PAX_NO_ACL_FLAGS
28876+ bool 'none'
28877+
28878+config PAX_HAVE_ACL_FLAGS
28879+ bool 'direct'
28880+
28881+config PAX_HOOK_ACL_FLAGS
28882+ bool 'hook'
28883+endchoice
28884+
28885+endmenu
28886+
28887+menu "Non-executable pages"
28888+ depends on PAX
28889+
28890+config PAX_NOEXEC
28891+ bool "Enforce non-executable pages"
28892+ 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)
28893+ help
28894+ By design some architectures do not allow for protecting memory
28895+ pages against execution or even if they do, Linux does not make
28896+ use of this feature. In practice this means that if a page is
28897+ readable (such as the stack or heap) it is also executable.
28898+
28899+ There is a well known exploit technique that makes use of this
28900+ fact and a common programming mistake where an attacker can
28901+ introduce code of his choice somewhere in the attacked program's
28902+ memory (typically the stack or the heap) and then execute it.
28903+
28904+ If the attacked program was running with different (typically
28905+ higher) privileges than that of the attacker, then he can elevate
28906+ his own privilege level (e.g. get a root shell, write to files for
28907+ which he does not have write access to, etc).
28908+
28909+ Enabling this option will let you choose from various features
28910+ that prevent the injection and execution of 'foreign' code in
28911+ a program.
28912+
28913+ This will also break programs that rely on the old behaviour and
28914+ expect that dynamically allocated memory via the malloc() family
28915+ of functions is executable (which it is not). Notable examples
28916+ are the XFree86 4.x server, the java runtime and wine.
28917+
28918+config PAX_PAGEEXEC
28919+ bool "Paging based non-executable pages"
28920+ depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
28921+ help
28922+ This implementation is based on the paging feature of the CPU.
28923+ On i386 and ppc there is a variable but usually low performance
28924+ impact on applications. On alpha, ia64, parisc, sparc, sparc64
28925+ and x86_64 there is no performance impact.
28926+
28927+config PAX_SEGMEXEC
28928+ bool "Segmentation based non-executable pages"
28929+ depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
28930+ help
28931+ This implementation is based on the segmentation feature of the
28932+ CPU and has little performance impact, however applications will
28933+ be limited to a 1.5 GB address space instead of the normal 3 GB.
28934+
28935+choice
28936+ prompt "Default non-executable page method"
28937+ depends on PAX_PAGEEXEC && PAX_SEGMEXEC
28938+ default PAX_DEFAULT_SEGMEXEC
28939+ help
28940+ Select the default non-executable page method applied to applications
28941+ that do not select one themselves.
28942+
28943+config PAX_DEFAULT_PAGEEXEC
28944+ bool "PAGEEXEC"
28945+
28946+config PAX_DEFAULT_SEGMEXEC
28947+ bool "SEGMEXEC"
28948+endchoice
28949+
28950+config PAX_EMUTRAMP
28951+ bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
28952+ default y if PARISC || PPC32
28953+ help
28954+ There are some programs and libraries that for one reason or
28955+ another attempt to execute special small code snippets from
28956+ non-executable memory pages. Most notable examples are the
28957+ signal handler return code generated by the kernel itself and
28958+ the GCC trampolines.
28959+
28960+ If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
28961+ such programs will no longer work under your kernel.
28962+
28963+ As a remedy you can say Y here and use the 'chpax' or 'paxctl'
28964+ utilities to enable trampoline emulation for the affected programs
28965+ yet still have the protection provided by the non-executable pages.
28966+
28967+ On parisc and ppc you MUST enable this option and EMUSIGRT as
28968+ well, otherwise your system will not even boot.
28969+
28970+ Alternatively you can say N here and use the 'chpax' or 'paxctl'
28971+ utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
28972+ for the affected files.
28973+
28974+ NOTE: enabling this feature *may* open up a loophole in the
28975+ protection provided by non-executable pages that an attacker
28976+ could abuse. Therefore the best solution is to not have any
28977+ files on your system that would require this option. This can
28978+ be achieved by not using libc5 (which relies on the kernel
28979+ signal handler return code) and not using or rewriting programs
28980+ that make use of the nested function implementation of GCC.
28981+ Skilled users can just fix GCC itself so that it implements
28982+ nested function calls in a way that does not interfere with PaX.
28983+
28984+config PAX_EMUSIGRT
28985+ bool "Automatically emulate sigreturn trampolines"
28986+ depends on PAX_EMUTRAMP && (PARISC || PPC32)
28987+ default y
28988+ help
28989+ Enabling this option will have the kernel automatically detect
28990+ and emulate signal return trampolines executing on the stack
28991+ that would otherwise lead to task termination.
28992+
28993+ This solution is intended as a temporary one for users with
28994+ legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
28995+ Modula-3 runtime, etc) or executables linked to such, basically
28996+ everything that does not specify its own SA_RESTORER function in
28997+ normal executable memory like glibc 2.1+ does.
28998+
28999+ On parisc and ppc you MUST enable this option, otherwise your
29000+ system will not even boot.
29001+
29002+ NOTE: this feature cannot be disabled on a per executable basis
29003+ and since it *does* open up a loophole in the protection provided
29004+ by non-executable pages, the best solution is to not have any
29005+ files on your system that would require this option.
29006+
29007+config PAX_MPROTECT
29008+ bool "Restrict mprotect()"
29009+ depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
29010+ help
29011+ Enabling this option will prevent programs from
29012+ - changing the executable status of memory pages that were
29013+ not originally created as executable,
29014+ - making read-only executable pages writable again,
29015+ - creating executable pages from anonymous memory.
29016+
29017+ You should say Y here to complete the protection provided by
29018+ the enforcement of non-executable pages.
29019+
29020+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
29021+ this feature on a per file basis.
29022+
29023+config PAX_NOELFRELOCS
29024+ bool "Disallow ELF text relocations"
29025+ depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
29026+ help
29027+ Non-executable pages and mprotect() restrictions are effective
29028+ in preventing the introduction of new executable code into an
29029+ attacked task's address space. There remain only two venues
29030+ for this kind of attack: if the attacker can execute already
29031+ existing code in the attacked task then he can either have it
29032+ create and mmap() a file containing his code or have it mmap()
29033+ an already existing ELF library that does not have position
29034+ independent code in it and use mprotect() on it to make it
29035+ writable and copy his code there. While protecting against
29036+ the former approach is beyond PaX, the latter can be prevented
29037+ by having only PIC ELF libraries on one's system (which do not
29038+ need to relocate their code). If you are sure this is your case,
29039+ then enable this option otherwise be careful as you may not even
29040+ be able to boot or log on your system (for example, some PAM
29041+ modules are erroneously compiled as non-PIC by default).
29042+
29043+ NOTE: if you are using dynamic ELF executables (as suggested
29044+ when using ASLR) then you must have made sure that you linked
29045+ your files using the PIC version of crt1 (the et_dyn.tar.gz package
29046+ referenced there has already been updated to support this).
29047+
29048+config PAX_ETEXECRELOCS
29049+ bool "Allow ELF ET_EXEC text relocations"
29050+ depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
29051+ default y
29052+ help
29053+ On some architectures there are incorrectly created applications
29054+ that require text relocations and would not work without enabling
29055+ this option. If you are an alpha, ia64 or parisc user, you should
29056+ enable this option and disable it once you have made sure that
29057+ none of your applications need it.
29058+
29059+config PAX_EMUPLT
29060+ bool "Automatically emulate ELF PLT"
29061+ depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
29062+ default y
29063+ help
29064+ Enabling this option will have the kernel automatically detect
29065+ and emulate the Procedure Linkage Table entries in ELF files.
29066+ On some architectures such entries are in writable memory, and
29067+ become non-executable leading to task termination. Therefore
29068+ it is mandatory that you enable this option on alpha, parisc, ppc,
29069+ sparc and sparc64, otherwise your system would not even boot.
29070+
29071+ NOTE: this feature *does* open up a loophole in the protection
29072+ provided by the non-executable pages, therefore the proper
29073+ solution is to modify the toolchain to produce a PLT that does
29074+ not need to be writable.
29075+
29076+config PAX_DLRESOLVE
29077+ bool
29078+ depends on PAX_EMUPLT && (SPARC32 || SPARC64)
29079+ default y
29080+
29081+config PAX_SYSCALL
29082+ bool
29083+ depends on PAX_PAGEEXEC && PPC32
29084+ default y
29085+
29086+config PAX_KERNEXEC
29087+ bool "Enforce non-executable kernel pages"
29088+ depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK
29089+ help
29090+ This is the kernel land equivalent of PAGEEXEC and MPROTECT,
29091+ that is, enabling this option will make it harder to inject
29092+ and execute 'foreign' code in kernel memory itself.
29093+
29094+endmenu
29095+
29096+menu "Address Space Layout Randomization"
29097+ depends on PAX
29098+
29099+config PAX_ASLR
29100+ bool "Address Space Layout Randomization"
29101+ depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
29102+ help
29103+ Many if not most exploit techniques rely on the knowledge of
29104+ certain addresses in the attacked program. The following options
29105+ will allow the kernel to apply a certain amount of randomization
29106+ to specific parts of the program thereby forcing an attacker to
29107+ guess them in most cases. Any failed guess will most likely crash
29108+ the attacked program which allows the kernel to detect such attempts
29109+ and react on them. PaX itself provides no reaction mechanisms,
29110+ instead it is strongly encouraged that you make use of Nergal's
29111+ segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
29112+ (http://www.grsecurity.net/) built-in crash detection features or
29113+ develop one yourself.
29114+
29115+ By saying Y here you can choose to randomize the following areas:
29116+ - top of the task's kernel stack
29117+ - top of the task's userland stack
29118+ - base address for mmap() requests that do not specify one
29119+ (this includes all libraries)
29120+ - base address of the main executable
29121+
29122+ It is strongly recommended to say Y here as address space layout
29123+ randomization has negligible impact on performance yet it provides
29124+ a very effective protection.
29125+
29126+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control
29127+ this feature on a per file basis.
29128+
29129+config PAX_RANDKSTACK
29130+ bool "Randomize kernel stack base"
29131+ depends on PAX_ASLR && X86_TSC && X86_32
29132+ help
29133+ By saying Y here the kernel will randomize every task's kernel
29134+ stack on every system call. This will not only force an attacker
29135+ to guess it but also prevent him from making use of possible
29136+ leaked information about it.
29137+
29138+ Since the kernel stack is a rather scarce resource, randomization
29139+ may cause unexpected stack overflows, therefore you should very
29140+ carefully test your system. Note that once enabled in the kernel
29141+ configuration, this feature cannot be disabled on a per file basis.
29142+
29143+config PAX_RANDUSTACK
29144+ bool "Randomize user stack base"
29145+ depends on PAX_ASLR
29146+ help
29147+ By saying Y here the kernel will randomize every task's userland
29148+ stack. The randomization is done in two steps where the second
29149+ one may apply a big amount of shift to the top of the stack and
29150+ cause problems for programs that want to use lots of memory (more
29151+ than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
29152+ For this reason the second step can be controlled by 'chpax' or
29153+ 'paxctl' on a per file basis.
29154+
29155+config PAX_RANDMMAP
29156+ bool "Randomize mmap() base"
29157+ depends on PAX_ASLR
29158+ help
29159+ By saying Y here the kernel will use a randomized base address for
29160+ mmap() requests that do not specify one themselves. As a result
29161+ all dynamically loaded libraries will appear at random addresses
29162+ and therefore be harder to exploit by a technique where an attacker
29163+ attempts to execute library code for his purposes (e.g. spawn a
29164+ shell from an exploited program that is running at an elevated
29165+ privilege level).
29166+
29167+ Furthermore, if a program is relinked as a dynamic ELF file, its
29168+ base address will be randomized as well, completing the full
29169+ randomization of the address space layout. Attacking such programs
29170+ becomes a guess game. You can find an example of doing this at
29171+ http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
29172+ http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
29173+
29174+ NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
29175+ feature on a per file basis.
29176+
29177+endmenu
29178+
29179+menu "Miscellaneous hardening features"
29180+
29181+config PAX_MEMORY_SANITIZE
29182+ bool "Sanitize all freed memory"
29183+ help
29184+ By saying Y here the kernel will erase memory pages as soon as they
29185+ are freed. This in turn reduces the lifetime of data stored in the
29186+ pages, making it less likely that sensitive information such as
29187+ passwords, cryptographic secrets, etc stay in memory for too long.
29188+
29189+ This is especially useful for programs whose runtime is short, long
29190+ lived processes and the kernel itself benefit from this as long as
29191+ they operate on whole memory pages and ensure timely freeing of pages
29192+ that may hold sensitive information.
29193+
29194+ The tradeoff is performance impact, on a single CPU system kernel
29195+ compilation sees a 3% slowdown, other systems and workloads may vary
29196+ and you are advised to test this feature on your expected workload
29197+ before deploying it.
29198+
29199+ Note that this feature does not protect data stored in live pages,
29200+ e.g., process memory swapped to disk may stay there for a long time.
29201+
29202+config PAX_MEMORY_UDEREF
29203+ bool "Prevent invalid userland pointer dereference"
29204+ depends on X86_32 && !COMPAT_VDSO
29205+ help
29206+ By saying Y here the kernel will be prevented from dereferencing
29207+ userland pointers in contexts where the kernel expects only kernel
29208+ pointers. This is both a useful runtime debugging feature and a
29209+ security measure that prevents exploiting a class of kernel bugs.
29210+
29211+ The tradeoff is that some virtualization solutions may experience
29212+ a huge slowdown and therefore you should not enable this feature
29213+ for kernels meant to run in such environments. Whether a given VM
29214+ solution is affected or not is best determined by simply trying it
29215+ out, the performance impact will be obvious right on boot as this
29216+ mechanism engages from very early on. A good rule of thumb is that
29217+ VMs running on CPUs without hardware virtualization support (i.e.,
29218+ the majority of IA-32 CPUs) will likely experience the slowdown.
29219+
29220+endmenu
29221+
29222+endmenu
29223+
29224+source grsecurity/Kconfig
29225+
29226 config KEYS
29227 bool "Enable access key retention support"
29228 help
29229diff -urNp linux-2.6.19.1/sound/core/oss/pcm_oss.c linux-2.6.19.1/sound/core/oss/pcm_oss.c
29230--- linux-2.6.19.1/sound/core/oss/pcm_oss.c 2006-11-29 16:57:37.000000000 -0500
29231+++ linux-2.6.19.1/sound/core/oss/pcm_oss.c 2006-12-03 15:16:30.000000000 -0500
29232@@ -2853,8 +2853,8 @@ static void snd_pcm_oss_proc_done(struct
29233 }
29234 }
29235 #else /* !CONFIG_SND_VERBOSE_PROCFS */
29236-#define snd_pcm_oss_proc_init(pcm)
29237-#define snd_pcm_oss_proc_done(pcm)
29238+#define snd_pcm_oss_proc_init(pcm) do {} while (0)
29239+#define snd_pcm_oss_proc_done(pcm) do {} while (0)
29240 #endif /* CONFIG_SND_VERBOSE_PROCFS */
29241
29242 /*
29243diff -urNp linux-2.6.19.1/sound/core/seq/seq_lock.h linux-2.6.19.1/sound/core/seq/seq_lock.h
29244--- linux-2.6.19.1/sound/core/seq/seq_lock.h 2006-11-29 16:57:37.000000000 -0500
29245+++ linux-2.6.19.1/sound/core/seq/seq_lock.h 2006-12-03 15:16:30.000000000 -0500
29246@@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
29247 #else /* SMP || CONFIG_SND_DEBUG */
29248
29249 typedef spinlock_t snd_use_lock_t; /* dummy */
29250-#define snd_use_lock_init(lockp) /**/
29251-#define snd_use_lock_use(lockp) /**/
29252-#define snd_use_lock_free(lockp) /**/
29253-#define snd_use_lock_sync(lockp) /**/
29254+#define snd_use_lock_init(lockp) do {} while (0)
29255+#define snd_use_lock_use(lockp) do {} while (0)
29256+#define snd_use_lock_free(lockp) do {} while (0)
29257+#define snd_use_lock_sync(lockp) do {} while (0)
29258
29259 #endif /* SMP || CONFIG_SND_DEBUG */
29260
This page took 3.352492 seconds and 4 git commands to generate.