]> git.pld-linux.org Git - packages/kernel.git/blob - grsecurity-2.1.10-2.6.20.3.patch
- use CUBIC by default:
[packages/kernel.git] / grsecurity-2.1.10-2.6.20.3.patch
1 diff -urNp linux-2.6.20.3/arch/alpha/kernel/module.c linux-2.6.20.3/arch/alpha/kernel/module.c
2 --- linux-2.6.20.3/arch/alpha/kernel/module.c   2007-03-13 14:27:08.000000000 -0400
3 +++ linux-2.6.20.3/arch/alpha/kernel/module.c   2007-03-23 08:10:05.000000000 -0400
4 @@ -177,7 +177,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, 
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++) {
13 diff -urNp linux-2.6.20.3/arch/alpha/kernel/osf_sys.c linux-2.6.20.3/arch/alpha/kernel/osf_sys.c
14 --- linux-2.6.20.3/arch/alpha/kernel/osf_sys.c  2007-03-13 14:27:08.000000000 -0400
15 +++ linux-2.6.20.3/arch/alpha/kernel/osf_sys.c  2007-03-23 08:10:05.000000000 -0400
16 @@ -1277,6 +1277,10 @@ arch_get_unmapped_area(struct file *filp
17            merely specific addresses, but regions of memory -- perhaps
18            this feature should be incorporated into all ports?  */
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  
38 diff -urNp linux-2.6.20.3/arch/alpha/kernel/ptrace.c linux-2.6.20.3/arch/alpha/kernel/ptrace.c
39 --- linux-2.6.20.3/arch/alpha/kernel/ptrace.c   2007-03-13 14:27:08.000000000 -0400
40 +++ linux-2.6.20.3/arch/alpha/kernel/ptrace.c   2007-03-23 08:11:18.000000000 -0400
41 @@ -16,6 +16,7 @@
42  #include <linux/security.h>
43  #include <linux/signal.h>
44  #include <linux/vs_base.h>
45 +#include <linux/grsecurity.h>
46  
47  #include <asm/uaccess.h>
48  #include <asm/pgtable.h>
49 @@ -289,6 +290,9 @@ do_sys_ptrace(long request, long pid, lo
50                 goto out;
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;
59 diff -urNp linux-2.6.20.3/arch/alpha/mm/fault.c linux-2.6.20.3/arch/alpha/mm/fault.c
60 --- linux-2.6.20.3/arch/alpha/mm/fault.c        2007-03-13 14:27:08.000000000 -0400
61 +++ linux-2.6.20.3/arch/alpha/mm/fault.c        2007-03-23 08:10:05.000000000 -0400
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)))
226 diff -urNp linux-2.6.20.3/arch/arm/mm/mmap.c linux-2.6.20.3/arch/arm/mm/mmap.c
227 --- linux-2.6.20.3/arch/arm/mm/mmap.c   2007-03-13 14:27:08.000000000 -0400
228 +++ linux-2.6.20.3/arch/arm/mm/mmap.c   2007-03-23 08:10:05.000000000 -0400
229 @@ -61,6 +61,10 @@ arch_get_unmapped_area(struct file *filp
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                         }
260 diff -urNp linux-2.6.20.3/arch/i386/boot/setup.S linux-2.6.20.3/arch/i386/boot/setup.S
261 --- linux-2.6.20.3/arch/i386/boot/setup.S       2007-03-13 14:27:08.000000000 -0400
262 +++ linux-2.6.20.3/arch/i386/boot/setup.S       2007-03-23 08:10:05.000000000 -0400
263 @@ -869,11 +869,13 @@ startup_32:
264         movl %eax, %gs
265         movl %eax, %ss
266  
267 +       movl 0x00000000, %ecx
268         xorl %eax, %eax
269  1:     incl %eax                               # check that A20 really IS enabled
270         movl %eax, 0x00000000                   # loop forever if it isn't
271         cmpl %eax, 0x00100000
272         je 1b
273 +       movl %ecx, 0x00000000
274  
275         # Jump to the 32bit entry point
276         jmpl *(code32_start - start + (DELTA_INITSEG << 4))(%esi)
277 diff -urNp linux-2.6.20.3/arch/i386/Kconfig linux-2.6.20.3/arch/i386/Kconfig
278 --- linux-2.6.20.3/arch/i386/Kconfig    2007-03-13 14:27:08.000000000 -0400
279 +++ linux-2.6.20.3/arch/i386/Kconfig    2007-03-23 08:11:18.000000000 -0400
280 @@ -864,7 +864,7 @@ config HOTPLUG_CPU
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 @@ -1060,7 +1060,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 @@ -1092,7 +1092,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
307 diff -urNp linux-2.6.20.3/arch/i386/Kconfig.cpu linux-2.6.20.3/arch/i386/Kconfig.cpu
308 --- linux-2.6.20.3/arch/i386/Kconfig.cpu        2007-03-13 14:27:08.000000000 -0400
309 +++ linux-2.6.20.3/arch/i386/Kconfig.cpu        2007-03-23 08:10:05.000000000 -0400
310 @@ -267,7 +267,7 @@ config X86_PPRO_FENCE
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 @@ -297,7 +297,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
328 diff -urNp linux-2.6.20.3/arch/i386/Kconfig.debug linux-2.6.20.3/arch/i386/Kconfig.debug
329 --- linux-2.6.20.3/arch/i386/Kconfig.debug      2007-03-13 14:27:08.000000000 -0400
330 +++ linux-2.6.20.3/arch/i386/Kconfig.debug      2007-03-23 08:10:05.000000000 -0400
331 @@ -48,7 +48,7 @@ config DEBUG_PAGEALLOC
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
340 diff -urNp linux-2.6.20.3/arch/i386/kernel/acpi/boot.c linux-2.6.20.3/arch/i386/kernel/acpi/boot.c
341 --- linux-2.6.20.3/arch/i386/kernel/acpi/boot.c 2007-03-13 14:27:08.000000000 -0400
342 +++ linux-2.6.20.3/arch/i386/kernel/acpi/boot.c 2007-03-23 08:10:05.000000000 -0400
343 @@ -1152,7 +1152,7 @@ static struct dmi_system_id __initdata a
344                      DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
345                      },
346          },
347 -       {}
348 +       { NULL, NULL, {{0, NULL}}, NULL}
349  };
350  
351  #endif                         /* __i386__ */
352 diff -urNp linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c
353 --- linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c        2007-03-13 14:27:08.000000000 -0400
354 +++ linux-2.6.20.3/arch/i386/kernel/acpi/sleep.c        2007-03-23 08:10:05.000000000 -0400
355 @@ -94,7 +94,7 @@ static __initdata struct dmi_system_id a
356                      DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),
357                      },
358          },
359 -       {}
360 +       { NULL, NULL, {{0, NULL}}, NULL}
361  };
362  
363  static int __init acpisleep_dmi_init(void)
364 diff -urNp linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S
365 --- linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S       2007-03-13 14:27:08.000000000 -0400
366 +++ linux-2.6.20.3/arch/i386/kernel/acpi/wakeup.S       2007-03-23 08:10:05.000000000 -0400
367 @@ -205,13 +205,11 @@ wakeup_pmode_return:
368         # and restore the stack ... but you need gdt for this to work
369         movl    saved_context_esp, %esp
370  
371 -       movl    %cs:saved_magic, %eax
372 -       cmpl    $0x12345678, %eax
373 +       cmpl    $0x12345678, saved_magic
374         jne     bogus_magic
375  
376         # jump to place where we left off
377 -       movl    saved_eip,%eax
378 -       jmp     *%eax
379 +       jmp     *(saved_eip)
380  
381  bogus_magic:
382         movw    $0x0e00 + 'B', 0xb8018
383 diff -urNp linux-2.6.20.3/arch/i386/kernel/alternative.c linux-2.6.20.3/arch/i386/kernel/alternative.c
384 --- linux-2.6.20.3/arch/i386/kernel/alternative.c       2007-03-13 14:27:08.000000000 -0400
385 +++ linux-2.6.20.3/arch/i386/kernel/alternative.c       2007-03-23 08:10:05.000000000 -0400
386 @@ -4,6 +4,7 @@
387  #include <linux/list.h>
388  #include <asm/alternative.h>
389  #include <asm/sections.h>
390 +#include <asm/desc.h>
391  
392  static int no_replacement    = 0;
393  static int smp_alt_once      = 0;
394 @@ -156,12 +157,18 @@ void apply_alternatives(struct alt_instr
395         u8 *instr;
396         int diff;
397  
398 +#ifdef CONFIG_PAX_KERNEXEC
399 +       unsigned long cr0;
400 +
401 +       pax_open_kernel(cr0);
402 +#endif
403 +
404         DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end);
405         for (a = start; a < end; a++) {
406                 BUG_ON(a->replacementlen > a->instrlen);
407                 if (!boot_cpu_has(a->cpuid))
408                         continue;
409 -               instr = a->instr;
410 +               instr = a->instr + __KERNEL_TEXT_OFFSET;
411  #ifdef CONFIG_X86_64
412                 /* vsyscall code is not mapped yet. resolve it manually. */
413                 if (instr >= (u8 *)VSYSCALL_START && instr < (u8*)VSYSCALL_END) {
414 @@ -174,6 +181,11 @@ void apply_alternatives(struct alt_instr
415                 diff = a->instrlen - a->replacementlen;
416                 nop_out(instr + a->replacementlen, diff);
417         }
418 +
419 +#ifdef CONFIG_PAX_KERNEXEC
420 +       pax_close_kernel(cr0);
421 +#endif
422 +
423  }
424  
425  #ifdef CONFIG_SMP
426 @@ -182,49 +194,95 @@ static void alternatives_smp_save(struct
427  {
428         struct alt_instr *a;
429  
430 +#ifdef CONFIG_PAX_KERNEXEC
431 +       unsigned long cr0;
432 +
433 +       pax_open_kernel(cr0);
434 +#endif
435 +
436         DPRINTK("%s: alt table %p-%p\n", __FUNCTION__, start, end);
437         for (a = start; a < end; a++) {
438                 memcpy(a->replacement + a->replacementlen,
439 -                      a->instr,
440 +                      a->instr + __KERNEL_TEXT_OFFSET,
441                        a->instrlen);
442         }
443 +
444 +#ifdef CONFIG_PAX_KERNEXEC
445 +       pax_close_kernel(cr0);
446 +#endif
447 +
448  }
449  
450  static void alternatives_smp_apply(struct alt_instr *start, struct alt_instr *end)
451  {
452         struct alt_instr *a;
453  
454 +#ifdef CONFIG_PAX_KERNEXEC
455 +       unsigned long cr0;
456 +
457 +       pax_open_kernel(cr0);
458 +#endif
459 +
460         for (a = start; a < end; a++) {
461 -               memcpy(a->instr,
462 +               memcpy(a->instr + __KERNEL_TEXT_OFFSET,
463                        a->replacement + a->replacementlen,
464                        a->instrlen);
465         }
466 +
467 +#ifdef CONFIG_PAX_KERNEXEC
468 +       pax_close_kernel(cr0);
469 +#endif
470 +
471  }
472  
473  static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end)
474  {
475 -       u8 **ptr;
476 +       u8 *ptr;
477  
478 -       for (ptr = start; ptr < end; ptr++) {
479 -               if (*ptr < text)
480 +#ifdef CONFIG_PAX_KERNEXEC
481 +       unsigned long cr0;
482 +
483 +       pax_open_kernel(cr0);
484 +#endif
485 +
486 +       for (; start < end; start++) {
487 +               ptr = *start + __KERNEL_TEXT_OFFSET;
488 +               if (ptr < text)
489                         continue;
490 -               if (*ptr > text_end)
491 +               if (ptr > text_end)
492                         continue;
493 -               **ptr = 0xf0; /* lock prefix */
494 +               *ptr = 0xf0; /* lock prefix */
495         };
496 +
497 +#ifdef CONFIG_PAX_KERNEXEC
498 +       pax_close_kernel(cr0);
499 +#endif
500 +
501  }
502  
503  static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end)
504  {
505 -       u8 **ptr;
506 +       u8 *ptr;
507 +
508 +#ifdef CONFIG_PAX_KERNEXEC
509 +       unsigned long cr0;
510 +
511 +       pax_open_kernel(cr0);
512 +#endif
513  
514 -       for (ptr = start; ptr < end; ptr++) {
515 -               if (*ptr < text)
516 +       for (; start < end; start++) {
517 +               ptr = *start + __KERNEL_TEXT_OFFSET;
518 +               if (ptr < text)
519                         continue;
520 -               if (*ptr > text_end)
521 +               if (ptr > text_end)
522                         continue;
523 -               nop_out(*ptr, 1);
524 +               nop_out(ptr, 1);
525         };
526 +
527 +#ifdef CONFIG_PAX_KERNEXEC
528 +       pax_close_kernel(cr0);
529 +#endif
530 +
531  }
532  
533  struct smp_alt_module {
534 @@ -354,10 +412,17 @@ void apply_paravirt(struct paravirt_patc
535  {
536         struct paravirt_patch *p;
537  
538 +#ifdef CONFIG_PAX_KERNEXEC
539 +       unsigned long cr0;
540 +
541 +       pax_open_kernel(cr0);
542 +#endif
543 +
544         for (p = start; p < end; p++) {
545                 unsigned int used;
546 +               u8 *instr = p->instr + __KERNEL_TEXT_OFFSET;
547  
548 -               used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr,
549 +               used = paravirt_ops.patch(p->instrtype, p->clobbers, instr,
550                                           p->len);
551  #ifdef CONFIG_DEBUG_PARAVIRT
552                 {
553 @@ -365,17 +430,20 @@ void apply_paravirt(struct paravirt_patc
554                 /* Deliberately clobber regs using "not %reg" to find bugs. */
555                 for (i = 0; i < 3; i++) {
556                         if (p->len - used >= 2 && (p->clobbers & (1 << i))) {
557 -                               memcpy(p->instr + used, "\xf7\xd0", 2);
558 -                               p->instr[used+1] |= i;
559 -                               used += 2;
560 +                               instr[used++] = 0xf7;
561 +                               instr[used++] = 0xd0 | i;
562                         }
563                 }
564                 }
565  #endif
566                 /* Pad the rest with nops */
567 -               nop_out(p->instr + used, p->len - used);
568 +               nop_out(instr + used, p->len - used);
569         }
570  
571 +#ifdef CONFIG_PAX_KERNEXEC
572 +       pax_close_kernel(cr0);
573 +#endif
574 +
575         /* Sync to be conservative, in case we patched following instructions */
576         sync_core();
577  }
578 diff -urNp linux-2.6.20.3/arch/i386/kernel/apic.c linux-2.6.20.3/arch/i386/kernel/apic.c
579 --- linux-2.6.20.3/arch/i386/kernel/apic.c      2007-03-13 14:27:08.000000000 -0400
580 +++ linux-2.6.20.3/arch/i386/kernel/apic.c      2007-03-23 08:10:05.000000000 -0400
581 @@ -1211,7 +1211,7 @@ inline void smp_local_timer_interrupt(vo
582  {
583         profile_tick(CPU_PROFILING);
584  #ifdef CONFIG_SMP
585 -       update_process_times(user_mode_vm(get_irq_regs()));
586 +       update_process_times(user_mode(get_irq_regs()));
587  #endif
588  
589         /*
590 diff -urNp linux-2.6.20.3/arch/i386/kernel/apm.c linux-2.6.20.3/arch/i386/kernel/apm.c
591 --- linux-2.6.20.3/arch/i386/kernel/apm.c       2007-03-13 14:27:08.000000000 -0400
592 +++ linux-2.6.20.3/arch/i386/kernel/apm.c       2007-03-23 08:10:05.000000000 -0400
593 @@ -236,7 +236,7 @@
594  #include "io_ports.h"
595  
596  extern unsigned long get_cmos_time(void);
597 -extern void machine_real_restart(unsigned char *, int);
598 +extern void machine_real_restart(const unsigned char *, unsigned int);
599  
600  #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
601  extern int (*console_blank_hook)(int);
602 @@ -609,9 +609,18 @@ static u8 apm_bios_call(u32 func, u32 eb
603         struct desc_struct      save_desc_40;
604         struct desc_struct      *gdt;
605  
606 +#ifdef CONFIG_PAX_KERNEXEC
607 +       unsigned long           cr0;
608 +#endif
609 +
610         cpus = apm_save_cpus();
611         
612         cpu = get_cpu();
613 +
614 +#ifdef CONFIG_PAX_KERNEXEC
615 +       pax_open_kernel(cr0);
616 +#endif
617 +
618         gdt = get_cpu_gdt_table(cpu);
619         save_desc_40 = gdt[0x40 / 8];
620         gdt[0x40 / 8] = bad_bios_desc;
621 @@ -622,6 +631,11 @@ static u8 apm_bios_call(u32 func, u32 eb
622         APM_DO_RESTORE_SEGS;
623         apm_irq_restore(flags);
624         gdt[0x40 / 8] = save_desc_40;
625 +
626 +#ifdef CONFIG_PAX_KERNEXEC
627 +       pax_close_kernel(cr0);
628 +#endif
629 +
630         put_cpu();
631         apm_restore_cpus(cpus);
632         
633 @@ -652,9 +666,18 @@ static u8 apm_bios_call_simple(u32 func,
634         struct desc_struct      save_desc_40;
635         struct desc_struct      *gdt;
636  
637 +#ifdef CONFIG_PAX_KERNEXEC
638 +       unsigned long           cr0;
639 +#endif
640 +
641         cpus = apm_save_cpus();
642         
643         cpu = get_cpu();
644 +
645 +#ifdef CONFIG_PAX_KERNEXEC
646 +       pax_open_kernel(cr0);
647 +#endif
648 +
649         gdt = get_cpu_gdt_table(cpu);
650         save_desc_40 = gdt[0x40 / 8];
651         gdt[0x40 / 8] = bad_bios_desc;
652 @@ -665,6 +688,11 @@ static u8 apm_bios_call_simple(u32 func,
653         APM_DO_RESTORE_SEGS;
654         apm_irq_restore(flags);
655         gdt[0x40 / 8] = save_desc_40;
656 +
657 +#ifdef CONFIG_PAX_KERNEXEC
658 +       pax_close_kernel(cr0);
659 +#endif
660 +
661         put_cpu();
662         apm_restore_cpus(cpus);
663         return error;
664 @@ -932,7 +960,7 @@ recalc:
665   
666  static void apm_power_off(void)
667  {
668 -       unsigned char   po_bios_call[] = {
669 +       const unsigned char     po_bios_call[] = {
670                 0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
671                 0x8e, 0xd0,             /* movw  ax,ss       */
672                 0xbc, 0x00, 0xf0,       /* movw  $0xf000,sp  */
673 @@ -1906,7 +1934,10 @@ static struct file_operations apm_bios_f
674  static struct miscdevice apm_device = {
675         APM_MINOR_DEV,
676         "apm_bios",
677 -       &apm_bios_fops
678 +       &apm_bios_fops,
679 +       {NULL, NULL},
680 +       NULL,
681 +       NULL
682  };
683  
684  
685 @@ -2016,210 +2047,210 @@ static struct dmi_system_id __initdata a
686                 print_if_true,
687                 KERN_WARNING "IBM T23 - BIOS 1.03b+ and controller firmware 1.02+ may be needed for Linux APM.",
688                 {       DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
689 -                       DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), },
690 +                       DMI_MATCH(DMI_BIOS_VERSION, "1AET38WW (1.01b)"), }, NULL
691         },
692         {       /* Handle problems with APM on the C600 */
693                 broken_ps2_resume, "Dell Latitude C600",
694                 {       DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
695 -                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), },
696 +                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C600"), }, NULL
697         },
698         {       /* Allow interrupts during suspend on Dell Latitude laptops*/
699                 set_apm_ints, "Dell Latitude",
700                 {       DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
701 -                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }
702 +                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude C510"), }, NULL
703         },
704         {       /* APM crashes */
705                 apm_is_horked, "Dell Inspiron 2500",
706                 {       DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
707                         DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
708                         DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
709 -                       DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
710 +                       DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
711         },
712         {       /* Allow interrupts during suspend on Dell Inspiron laptops*/
713                 set_apm_ints, "Dell Inspiron", {
714                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
715 -                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), },
716 +                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 4000"), }, NULL
717         },
718         {       /* Handle problems with APM on Inspiron 5000e */
719                 broken_apm_power, "Dell Inspiron 5000e",
720                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
721                         DMI_MATCH(DMI_BIOS_VERSION, "A04"),
722 -                       DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), },
723 +                       DMI_MATCH(DMI_BIOS_DATE, "08/24/2000"), }, NULL
724         },
725         {       /* Handle problems with APM on Inspiron 2500 */
726                 broken_apm_power, "Dell Inspiron 2500",
727                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
728                         DMI_MATCH(DMI_BIOS_VERSION, "A12"),
729 -                       DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), },
730 +                       DMI_MATCH(DMI_BIOS_DATE, "02/04/2002"), }, NULL
731         },
732         {       /* APM crashes */
733                 apm_is_horked, "Dell Dimension 4100",
734                 {       DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
735                         DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"),
736                         DMI_MATCH(DMI_BIOS_VENDOR,"Intel Corp."),
737 -                       DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
738 +                       DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
739         },
740         {       /* Allow interrupts during suspend on Compaq Laptops*/
741                 set_apm_ints, "Compaq 12XL125",
742                 {       DMI_MATCH(DMI_SYS_VENDOR, "Compaq"),
743                         DMI_MATCH(DMI_PRODUCT_NAME, "Compaq PC"),
744                         DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
745 -                       DMI_MATCH(DMI_BIOS_VERSION,"4.06"), },
746 +                       DMI_MATCH(DMI_BIOS_VERSION,"4.06"), }, NULL
747         },
748         {       /* Allow interrupts during APM or the clock goes slow */
749                 set_apm_ints, "ASUSTeK",
750                 {       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
751 -                       DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), },
752 +                       DMI_MATCH(DMI_PRODUCT_NAME, "L8400K series Notebook PC"), }, NULL
753         },
754         {       /* APM blows on shutdown */
755                 apm_is_horked, "ABIT KX7-333[R]",
756                 {       DMI_MATCH(DMI_BOARD_VENDOR, "ABIT"),
757 -                       DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), },
758 +                       DMI_MATCH(DMI_BOARD_NAME, "VT8367-8233A (KX7-333[R])"), }, NULL
759         },
760         {       /* APM crashes */
761                 apm_is_horked, "Trigem Delhi3",
762                 {       DMI_MATCH(DMI_SYS_VENDOR, "TriGem Computer, Inc"),
763 -                       DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), },
764 +                       DMI_MATCH(DMI_PRODUCT_NAME, "Delhi3"), }, NULL
765         },
766         {       /* APM crashes */
767                 apm_is_horked, "Fujitsu-Siemens",
768                 {       DMI_MATCH(DMI_BIOS_VENDOR, "hoenix/FUJITSU SIEMENS"),
769 -                       DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), },
770 +                       DMI_MATCH(DMI_BIOS_VERSION, "Version1.01"), }, NULL
771         },
772         {       /* APM crashes */
773                 apm_is_horked_d850md, "Intel D850MD",
774                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
775 -                       DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), },
776 +                       DMI_MATCH(DMI_BIOS_VERSION, "MV85010A.86A.0016.P07.0201251536"), }, NULL
777         },
778         {       /* APM crashes */
779                 apm_is_horked, "Intel D810EMO",
780                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
781 -                       DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), },
782 +                       DMI_MATCH(DMI_BIOS_VERSION, "MO81010A.86A.0008.P04.0004170800"), }, NULL
783         },
784         {       /* APM crashes */
785                 apm_is_horked, "Dell XPS-Z",
786                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Intel Corp."),
787                         DMI_MATCH(DMI_BIOS_VERSION, "A11"),
788 -                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), },
789 +                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS-Z"), }, NULL
790         },
791         {       /* APM crashes */
792                 apm_is_horked, "Sharp PC-PJ/AX",
793                 {       DMI_MATCH(DMI_SYS_VENDOR, "SHARP"),
794                         DMI_MATCH(DMI_PRODUCT_NAME, "PC-PJ/AX"),
795                         DMI_MATCH(DMI_BIOS_VENDOR,"SystemSoft"),
796 -                       DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), },
797 +                       DMI_MATCH(DMI_BIOS_VERSION,"Version R2.08"), }, NULL
798         },
799         {       /* APM crashes */
800                 apm_is_horked, "Dell Inspiron 2500",
801                 {       DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
802                         DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 2500"),
803                         DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
804 -                       DMI_MATCH(DMI_BIOS_VERSION,"A11"), },
805 +                       DMI_MATCH(DMI_BIOS_VERSION,"A11"), }, NULL
806         },
807         {       /* APM idle hangs */
808                 apm_likes_to_melt, "Jabil AMD",
809                 {       DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
810 -                       DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), },
811 +                       DMI_MATCH(DMI_BIOS_VERSION, "0AASNP06"), }, NULL
812         },
813         {       /* APM idle hangs */
814                 apm_likes_to_melt, "AMI Bios",
815                 {       DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."),
816 -                       DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), },
817 +                       DMI_MATCH(DMI_BIOS_VERSION, "0AASNP05"), }, NULL
818         },
819         {       /* Handle problems with APM on Sony Vaio PCG-N505X(DE) */
820                 swab_apm_power_in_minutes, "Sony VAIO",
821                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
822                         DMI_MATCH(DMI_BIOS_VERSION, "R0206H"),
823 -                       DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), },
824 +                       DMI_MATCH(DMI_BIOS_DATE, "08/23/99"), }, NULL
825         },
826         {       /* Handle problems with APM on Sony Vaio PCG-N505VX */
827                 swab_apm_power_in_minutes, "Sony VAIO",
828                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
829                         DMI_MATCH(DMI_BIOS_VERSION, "W2K06H0"),
830 -                       DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), },
831 +                       DMI_MATCH(DMI_BIOS_DATE, "02/03/00"), }, NULL
832         },
833         {       /* Handle problems with APM on Sony Vaio PCG-XG29 */
834                 swab_apm_power_in_minutes, "Sony VAIO",
835                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
836                         DMI_MATCH(DMI_BIOS_VERSION, "R0117A0"),
837 -                       DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), },
838 +                       DMI_MATCH(DMI_BIOS_DATE, "04/25/00"), }, NULL
839         },
840         {       /* Handle problems with APM on Sony Vaio PCG-Z600NE */
841                 swab_apm_power_in_minutes, "Sony VAIO",
842                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
843                         DMI_MATCH(DMI_BIOS_VERSION, "R0121Z1"),
844 -                       DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), },
845 +                       DMI_MATCH(DMI_BIOS_DATE, "05/11/00"), }, NULL
846         },
847         {       /* Handle problems with APM on Sony Vaio PCG-Z600NE */
848                 swab_apm_power_in_minutes, "Sony VAIO",
849                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
850                         DMI_MATCH(DMI_BIOS_VERSION, "WME01Z1"),
851 -                       DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), },
852 +                       DMI_MATCH(DMI_BIOS_DATE, "08/11/00"), }, NULL
853         },
854         {       /* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
855                 swab_apm_power_in_minutes, "Sony VAIO",
856                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
857                         DMI_MATCH(DMI_BIOS_VERSION, "R0206Z3"),
858 -                       DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), },
859 +                       DMI_MATCH(DMI_BIOS_DATE, "12/25/00"), }, NULL
860         },
861         {       /* Handle problems with APM on Sony Vaio PCG-Z505LS */
862                 swab_apm_power_in_minutes, "Sony VAIO",
863                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
864                         DMI_MATCH(DMI_BIOS_VERSION, "R0203D0"),
865 -                       DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), },
866 +                       DMI_MATCH(DMI_BIOS_DATE, "05/12/00"), }, NULL
867         },
868         {       /* Handle problems with APM on Sony Vaio PCG-Z505LS */
869                 swab_apm_power_in_minutes, "Sony VAIO",
870                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
871                         DMI_MATCH(DMI_BIOS_VERSION, "R0203Z3"),
872 -                       DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), },
873 +                       DMI_MATCH(DMI_BIOS_DATE, "08/25/00"), }, NULL
874         },
875         {       /* Handle problems with APM on Sony Vaio PCG-Z505LS (with updated BIOS) */
876                 swab_apm_power_in_minutes, "Sony VAIO",
877                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
878                         DMI_MATCH(DMI_BIOS_VERSION, "R0209Z3"),
879 -                       DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), },
880 +                       DMI_MATCH(DMI_BIOS_DATE, "05/12/01"), }, NULL
881         },
882         {       /* Handle problems with APM on Sony Vaio PCG-F104K */
883                 swab_apm_power_in_minutes, "Sony VAIO",
884                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
885                         DMI_MATCH(DMI_BIOS_VERSION, "R0204K2"),
886 -                       DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), },
887 +                       DMI_MATCH(DMI_BIOS_DATE, "08/28/00"), }, NULL
888         },
889  
890         {       /* Handle problems with APM on Sony Vaio PCG-C1VN/C1VE */
891                 swab_apm_power_in_minutes, "Sony VAIO",
892                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
893                         DMI_MATCH(DMI_BIOS_VERSION, "R0208P1"),
894 -                       DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), },
895 +                       DMI_MATCH(DMI_BIOS_DATE, "11/09/00"), }, NULL
896         },
897         {       /* Handle problems with APM on Sony Vaio PCG-C1VE */
898                 swab_apm_power_in_minutes, "Sony VAIO",
899                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
900                         DMI_MATCH(DMI_BIOS_VERSION, "R0204P1"),
901 -                       DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), },
902 +                       DMI_MATCH(DMI_BIOS_DATE, "09/12/00"), }, NULL
903         },
904         {       /* Handle problems with APM on Sony Vaio PCG-C1VE */
905                 swab_apm_power_in_minutes, "Sony VAIO",
906                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
907                         DMI_MATCH(DMI_BIOS_VERSION, "WXPO1Z3"),
908 -                       DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), },
909 +                       DMI_MATCH(DMI_BIOS_DATE, "10/26/01"), }, NULL
910         },
911         {       /* broken PM poweroff bios */
912                 set_realmode_power_off, "Award Software v4.60 PGMA",
913                 {       DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
914                         DMI_MATCH(DMI_BIOS_VERSION, "4.60 PGMA"),
915 -                       DMI_MATCH(DMI_BIOS_DATE, "134526184"), },
916 +                       DMI_MATCH(DMI_BIOS_DATE, "134526184"), }, NULL
917         },
918  
919         /* Generic per vendor APM settings  */
920  
921         {       /* Allow interrupts during suspend on IBM laptops */
922                 set_apm_ints, "IBM",
923 -               {       DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
924 +               {       DMI_MATCH(DMI_SYS_VENDOR, "IBM"), }, NULL
925         },
926  
927 -       { }
928 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
929  };
930  
931  /*
932 diff -urNp linux-2.6.20.3/arch/i386/kernel/asm-offsets.c linux-2.6.20.3/arch/i386/kernel/asm-offsets.c
933 --- linux-2.6.20.3/arch/i386/kernel/asm-offsets.c       2007-03-13 14:27:08.000000000 -0400
934 +++ linux-2.6.20.3/arch/i386/kernel/asm-offsets.c       2007-03-23 08:10:05.000000000 -0400
935 @@ -16,6 +16,7 @@
936  #include <asm/thread_info.h>
937  #include <asm/elf.h>
938  #include <asm/pda.h>
939 +#include <asm/pgtable.h>
940  
941  #define DEFINE(sym, val) \
942          asm volatile("\n->" #sym " %0 " #val : : "i" (val))
943 @@ -52,6 +53,7 @@ void foo(void)
944         OFFSET(TI_exec_domain, thread_info, exec_domain);
945         OFFSET(TI_flags, thread_info, flags);
946         OFFSET(TI_status, thread_info, status);
947 +       OFFSET(TI_cpu, thread_info, cpu);
948         OFFSET(TI_preempt_count, thread_info, preempt_count);
949         OFFSET(TI_addr_limit, thread_info, addr_limit);
950         OFFSET(TI_restart_block, thread_info, restart_block);
951 @@ -94,12 +96,14 @@ void foo(void)
952                  sizeof(struct tss_struct));
953  
954         DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
955 +       DEFINE(PTRS_PER_PTE_asm, PTRS_PER_PTE);
956         DEFINE(VDSO_PRELINK, VDSO_PRELINK);
957  
958         OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
959  
960         BLANK();
961 -       OFFSET(PDA_cpu, i386_pda, cpu_number);
962 +       DEFINE(PDA_size, sizeof __cpu_pda[0]);
963 +       OFFSET(PDA_cpu, i386_pda, cpu_number);
964         OFFSET(PDA_pcurrent, i386_pda, pcurrent);
965  
966  #ifdef CONFIG_PARAVIRT
967 @@ -110,5 +114,6 @@ void foo(void)
968         OFFSET(PARAVIRT_irq_enable_sysexit, paravirt_ops, irq_enable_sysexit);
969         OFFSET(PARAVIRT_iret, paravirt_ops, iret);
970         OFFSET(PARAVIRT_read_cr0, paravirt_ops, read_cr0);
971 +       OFFSET(PARAVIRT_write_cr0, paravirt_ops, write_cr0);
972  #endif
973  }
974 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/common.c linux-2.6.20.3/arch/i386/kernel/cpu/common.c
975 --- linux-2.6.20.3/arch/i386/kernel/cpu/common.c        2007-03-13 14:27:08.000000000 -0400
976 +++ linux-2.6.20.3/arch/i386/kernel/cpu/common.c        2007-03-23 08:10:05.000000000 -0400
977 @@ -4,7 +4,6 @@
978  #include <linux/smp.h>
979  #include <linux/module.h>
980  #include <linux/percpu.h>
981 -#include <linux/bootmem.h>
982  #include <asm/semaphore.h>
983  #include <asm/processor.h>
984  #include <asm/i387.h>
985 @@ -22,16 +21,17 @@
986  
987  #include "cpu.h"
988  
989 -DEFINE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
990 -EXPORT_PER_CPU_SYMBOL(cpu_gdt_descr);
991 -
992 -struct i386_pda *_cpu_pda[NR_CPUS] __read_mostly;
993  EXPORT_SYMBOL(_cpu_pda);
994  
995  static int cachesize_override __cpuinitdata = -1;
996  static int disable_x86_fxsr __cpuinitdata;
997  static int disable_x86_serial_nr __cpuinitdata = 1;
998 +
999 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC)
1000 +static int disable_x86_sep __cpuinitdata = 1;
1001 +#else
1002  static int disable_x86_sep __cpuinitdata;
1003 +#endif
1004  
1005  struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
1006  
1007 @@ -609,52 +609,6 @@ struct pt_regs * __devinit idle_regs(str
1008         return regs;
1009  }
1010  
1011 -static __cpuinit int alloc_gdt(int cpu)
1012 -{
1013 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
1014 -       struct desc_struct *gdt;
1015 -       struct i386_pda *pda;
1016 -
1017 -       gdt = (struct desc_struct *)cpu_gdt_descr->address;
1018 -       pda = cpu_pda(cpu);
1019 -
1020 -       /*
1021 -        * This is a horrible hack to allocate the GDT.  The problem
1022 -        * is that cpu_init() is called really early for the boot CPU
1023 -        * (and hence needs bootmem) but much later for the secondary
1024 -        * CPUs, when bootmem will have gone away
1025 -        */
1026 -       if (NODE_DATA(0)->bdata->node_bootmem_map) {
1027 -               BUG_ON(gdt != NULL || pda != NULL);
1028 -
1029 -               gdt = alloc_bootmem_pages(PAGE_SIZE);
1030 -               pda = alloc_bootmem(sizeof(*pda));
1031 -               /* alloc_bootmem(_pages) panics on failure, so no check */
1032 -
1033 -               memset(gdt, 0, PAGE_SIZE);
1034 -               memset(pda, 0, sizeof(*pda));
1035 -       } else {
1036 -               /* GDT and PDA might already have been allocated if
1037 -                  this is a CPU hotplug re-insertion. */
1038 -               if (gdt == NULL)
1039 -                       gdt = (struct desc_struct *)get_zeroed_page(GFP_KERNEL);
1040 -
1041 -               if (pda == NULL)
1042 -                       pda = kmalloc_node(sizeof(*pda), GFP_KERNEL, cpu_to_node(cpu));
1043 -
1044 -               if (unlikely(!gdt || !pda)) {
1045 -                       free_pages((unsigned long)gdt, 0);
1046 -                       kfree(pda);
1047 -                       return 0;
1048 -               }
1049 -       }
1050 -
1051 -       cpu_gdt_descr->address = (unsigned long)gdt;
1052 -       cpu_pda(cpu) = pda;
1053 -
1054 -       return 1;
1055 -}
1056 -
1057  /* Initial PDA used by boot CPU */
1058  struct i386_pda boot_pda = {
1059         ._pda = &boot_pda,
1060 @@ -672,59 +626,43 @@ static inline void set_kernel_gs(void)
1061  
1062  /* Initialize the CPU's GDT and PDA.  The boot CPU does this for
1063     itself, but secondaries find this done for them. */
1064 -__cpuinit int init_gdt(int cpu, struct task_struct *idle)
1065 +__cpuinit void init_gdt(int cpu, struct task_struct *idle)
1066  {
1067 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
1068 -       struct desc_struct *gdt;
1069 -       struct i386_pda *pda;
1070 -
1071 -       /* For non-boot CPUs, the GDT and PDA should already have been
1072 -          allocated. */
1073 -       if (!alloc_gdt(cpu)) {
1074 -               printk(KERN_CRIT "CPU%d failed to allocate GDT or PDA\n", cpu);
1075 -               return 0;
1076 -       }
1077 +       struct desc_struct *gdt = get_cpu_gdt_table(cpu);
1078 +       struct i386_pda *pda = __cpu_pda + cpu;
1079  
1080 -       gdt = (struct desc_struct *)cpu_gdt_descr->address;
1081 -       pda = cpu_pda(cpu);
1082 -
1083 -       BUG_ON(gdt == NULL || pda == NULL);
1084 +       cpu_gdt_descr[cpu].address = gdt;
1085  
1086         /*
1087          * Initialize the per-CPU GDT with the boot GDT,
1088          * and set up the GDT descriptor:
1089          */
1090 -       memcpy(gdt, cpu_gdt_table, GDT_SIZE);
1091 -       cpu_gdt_descr->size = GDT_SIZE - 1;
1092 +       if (cpu)
1093 +               memcpy(gdt, cpu_gdt_table, GDT_SIZE);
1094 +       cpu_gdt_descr[cpu].size = GDT_SIZE - 1;
1095  
1096         pack_descriptor((u32 *)&gdt[GDT_ENTRY_PDA].a,
1097                         (u32 *)&gdt[GDT_ENTRY_PDA].b,
1098                         (unsigned long)pda, sizeof(*pda) - 1,
1099 -                       0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */
1100 +                       0x80 | DESCTYPE_S | 0x3, 0); /* present read-write data segment */
1101  
1102 -       memset(pda, 0, sizeof(*pda));
1103 -       pda->_pda = pda;
1104 -       pda->cpu_number = cpu;
1105         pda->pcurrent = idle;
1106 -
1107 -       return 1;
1108 +       pda->irq_regs = NULL;
1109  }
1110  
1111  void __cpuinit cpu_set_gdt(int cpu)
1112  {
1113 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
1114 -
1115         /* Reinit these anyway, even if they've already been done (on
1116            the boot CPU, this will transition from the boot gdt+pda to
1117            the real ones). */
1118 -       load_gdt(cpu_gdt_descr);
1119 +       load_gdt(&cpu_gdt_descr[cpu]);
1120         set_kernel_gs();
1121  }
1122  
1123  /* Common CPU init for both boot and secondary CPUs */
1124  static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)
1125  {
1126 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
1127 +       struct tss_struct * t = init_tss + cpu;
1128         struct thread_struct *thread = &curr->thread;
1129  
1130         if (cpu_test_and_set(cpu, cpu_initialized)) {
1131 @@ -805,12 +743,7 @@ void __cpuinit cpu_init(void)
1132  
1133         /* Set up the real GDT and PDA, so we can transition from the
1134            boot versions. */
1135 -       if (!init_gdt(cpu, curr)) {
1136 -               /* failed to allocate something; not much we can do... */
1137 -               for (;;)
1138 -                       local_irq_enable();
1139 -       }
1140 -
1141 +       init_gdt(cpu, curr);
1142         cpu_set_gdt(cpu);
1143         _cpu_init(cpu, curr);
1144  }
1145 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
1146 --- linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c  2007-03-13 14:27:08.000000000 -0400
1147 +++ linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c  2007-03-23 08:10:05.000000000 -0400
1148 @@ -563,7 +563,7 @@ static struct dmi_system_id sw_any_bug_d
1149                         DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1150                 },
1151         },
1152 -       { }
1153 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1154  };
1155  #endif
1156  
1157 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
1158 --- linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c    2007-03-13 14:27:08.000000000 -0400
1159 +++ linux-2.6.20.3/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c    2007-03-23 08:10:05.000000000 -0400
1160 @@ -229,7 +229,7 @@ static struct cpu_model models[] =
1161         { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
1162         { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
1163  
1164 -       { NULL, }
1165 +       { NULL, NULL, 0, NULL}
1166  };
1167  #undef _BANIAS
1168  #undef BANIAS
1169 @@ -404,7 +404,7 @@ static struct dmi_system_id sw_any_bug_d
1170                         DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
1171                 },
1172         },
1173 -       { }
1174 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
1175  };
1176  #endif
1177  
1178 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c
1179 --- linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c 2007-03-13 14:27:08.000000000 -0400
1180 +++ linux-2.6.20.3/arch/i386/kernel/cpu/cyrix.c 2007-03-23 08:10:05.000000000 -0400
1181 @@ -187,7 +187,7 @@ static void __cpuinit geode_configure(vo
1182  static struct pci_device_id __cpuinitdata cyrix_55x0[] = {
1183         { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510) },
1184         { PCI_DEVICE(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520) },
1185 -       { },
1186 +       { PCI_DEVICE(0, 0) },
1187  };
1188  #endif
1189  
1190 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c
1191 --- linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c    2007-03-13 14:27:08.000000000 -0400
1192 +++ linux-2.6.20.3/arch/i386/kernel/cpu/mcheck/therm_throt.c    2007-03-23 08:10:05.000000000 -0400
1193 @@ -148,7 +148,7 @@ static __cpuinit int thermal_throttle_cp
1194         return NOTIFY_OK;
1195  }
1196  
1197 -static struct notifier_block thermal_throttle_cpu_notifier =
1198 +static __cpuinitdata struct notifier_block thermal_throttle_cpu_notifier =
1199  {
1200         .notifier_call = thermal_throttle_cpu_callback,
1201  };
1202 diff -urNp linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c
1203 --- linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c  2007-03-13 14:27:08.000000000 -0400
1204 +++ linux-2.6.20.3/arch/i386/kernel/cpu/mtrr/generic.c  2007-03-23 08:10:05.000000000 -0400
1205 @@ -21,7 +21,7 @@ struct mtrr_state {
1206  };
1207  
1208  static unsigned long smp_changes_mask;
1209 -static struct mtrr_state mtrr_state = {};
1210 +static struct mtrr_state mtrr_state;
1211  
1212  #undef MODULE_PARAM_PREFIX
1213  #define MODULE_PARAM_PREFIX "mtrr."
1214 diff -urNp linux-2.6.20.3/arch/i386/kernel/crash.c linux-2.6.20.3/arch/i386/kernel/crash.c
1215 --- linux-2.6.20.3/arch/i386/kernel/crash.c     2007-03-13 14:27:08.000000000 -0400
1216 +++ linux-2.6.20.3/arch/i386/kernel/crash.c     2007-03-23 08:10:05.000000000 -0400
1217 @@ -55,7 +55,7 @@ static int crash_nmi_callback(struct not
1218                 return NOTIFY_STOP;
1219         local_irq_disable();
1220  
1221 -       if (!user_mode_vm(regs)) {
1222 +       if (!user_mode(regs)) {
1223                 crash_fixup_ss_esp(&fixed_regs, regs);
1224                 regs = &fixed_regs;
1225         }
1226 diff -urNp linux-2.6.20.3/arch/i386/kernel/doublefault.c linux-2.6.20.3/arch/i386/kernel/doublefault.c
1227 --- linux-2.6.20.3/arch/i386/kernel/doublefault.c       2007-03-13 14:27:08.000000000 -0400
1228 +++ linux-2.6.20.3/arch/i386/kernel/doublefault.c       2007-03-23 08:10:05.000000000 -0400
1229 @@ -11,17 +11,17 @@
1230  
1231  #define DOUBLEFAULT_STACKSIZE (1024)
1232  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
1233 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
1234 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
1235  
1236  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + 0x1000000)
1237  
1238  static void doublefault_fn(void)
1239  {
1240 -       struct Xgt_desc_struct gdt_desc = {0, 0};
1241 +       struct Xgt_desc_struct gdt_desc = {0, NULL, 0};
1242         unsigned long gdt, tss;
1243  
1244         store_gdt(&gdt_desc);
1245 -       gdt = gdt_desc.address;
1246 +       gdt = (unsigned long)gdt_desc.address;
1247  
1248         printk("double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
1249  
1250 @@ -57,10 +57,10 @@ struct tss_struct doublefault_tss __cach
1251         .eip            = (unsigned long) doublefault_fn,
1252         .eflags         = X86_EFLAGS_SF | 0x2,  /* 0x2 bit is always set */
1253         .esp            = STACK_START,
1254 -       .es             = __USER_DS,
1255 +       .es             = __KERNEL_DS,
1256         .cs             = __KERNEL_CS,
1257         .ss             = __KERNEL_DS,
1258 -       .ds             = __USER_DS,
1259 +       .ds             = __KERNEL_DS,
1260  
1261         .__cr3          = __pa(swapper_pg_dir)
1262  };
1263 diff -urNp linux-2.6.20.3/arch/i386/kernel/efi.c linux-2.6.20.3/arch/i386/kernel/efi.c
1264 --- linux-2.6.20.3/arch/i386/kernel/efi.c       2007-03-13 14:27:08.000000000 -0400
1265 +++ linux-2.6.20.3/arch/i386/kernel/efi.c       2007-03-23 08:10:05.000000000 -0400
1266 @@ -63,82 +63,43 @@ extern void * boot_ioremap(unsigned long
1267  
1268  static unsigned long efi_rt_eflags;
1269  static DEFINE_SPINLOCK(efi_rt_lock);
1270 -static pgd_t efi_bak_pg_dir_pointer[2];
1271 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS] __attribute__ ((aligned (4096)));
1272  
1273  static void efi_call_phys_prelog(void) __acquires(efi_rt_lock)
1274  {
1275 -       unsigned long cr4;
1276 -       unsigned long temp;
1277 -       struct Xgt_desc_struct *cpu_gdt_descr;
1278 -
1279         spin_lock(&efi_rt_lock);
1280         local_irq_save(efi_rt_eflags);
1281  
1282 -       cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
1283 -
1284 -       /*
1285 -        * If I don't have PSE, I should just duplicate two entries in page
1286 -        * directory. If I have PSE, I just need to duplicate one entry in
1287 -        * page directory.
1288 -        */
1289 -       cr4 = read_cr4();
1290 -
1291 -       if (cr4 & X86_CR4_PSE) {
1292 -               efi_bak_pg_dir_pointer[0].pgd =
1293 -                   swapper_pg_dir[pgd_index(0)].pgd;
1294 -               swapper_pg_dir[0].pgd =
1295 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1296 -       } else {
1297 -               efi_bak_pg_dir_pointer[0].pgd =
1298 -                   swapper_pg_dir[pgd_index(0)].pgd;
1299 -               efi_bak_pg_dir_pointer[1].pgd =
1300 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
1301 -               swapper_pg_dir[pgd_index(0)].pgd =
1302 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
1303 -               temp = PAGE_OFFSET + 0x400000;
1304 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
1305 -                   swapper_pg_dir[pgd_index(temp)].pgd;
1306 -       }
1307 +       clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
1308 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
1309 +                       min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
1310  
1311         /*
1312          * After the lock is released, the original page table is restored.
1313          */
1314 -       local_flush_tlb();
1315 +       __flush_tlb_all();
1316  
1317 -       cpu_gdt_descr->address = __pa(cpu_gdt_descr->address);
1318 -       load_gdt(cpu_gdt_descr);
1319 +       cpu_gdt_descr[0].address = __pa(cpu_gdt_descr[0].address);
1320 +       load_gdt((struct Xgt_desc_struct *) __pa(&cpu_gdt_descr[0]));
1321  }
1322  
1323  static void efi_call_phys_epilog(void) __releases(efi_rt_lock)
1324  {
1325 -       unsigned long cr4;
1326 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, 0);
1327 -
1328 -       cpu_gdt_descr->address = (unsigned long)__va(cpu_gdt_descr->address);
1329 -       load_gdt(cpu_gdt_descr);
1330 -
1331 -       cr4 = read_cr4();
1332 +       cpu_gdt_descr[0].address = (unsigned long) __va(cpu_gdt_descr[0].address);
1333 +       load_gdt(&cpu_gdt_descr[0]);
1334  
1335 -       if (cr4 & X86_CR4_PSE) {
1336 -               swapper_pg_dir[pgd_index(0)].pgd =
1337 -                   efi_bak_pg_dir_pointer[0].pgd;
1338 -       } else {
1339 -               swapper_pg_dir[pgd_index(0)].pgd =
1340 -                   efi_bak_pg_dir_pointer[0].pgd;
1341 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
1342 -                   efi_bak_pg_dir_pointer[1].pgd;
1343 -       }
1344 +       clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
1345  
1346         /*
1347          * After the lock is released, the original page table is restored.
1348          */
1349 -       local_flush_tlb();
1350 +       __flush_tlb_all();
1351  
1352         local_irq_restore(efi_rt_eflags);
1353         spin_unlock(&efi_rt_lock);
1354  }
1355  
1356 -static efi_status_t
1357 +static efi_status_t __init
1358  phys_efi_set_virtual_address_map(unsigned long memory_map_size,
1359                                  unsigned long descriptor_size,
1360                                  u32 descriptor_version,
1361 @@ -154,7 +115,7 @@ phys_efi_set_virtual_address_map(unsigne
1362         return status;
1363  }
1364  
1365 -static efi_status_t
1366 +static efi_status_t __init
1367  phys_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
1368  {
1369         efi_status_t status;
1370 diff -urNp linux-2.6.20.3/arch/i386/kernel/efi_stub.S linux-2.6.20.3/arch/i386/kernel/efi_stub.S
1371 --- linux-2.6.20.3/arch/i386/kernel/efi_stub.S  2007-03-13 14:27:08.000000000 -0400
1372 +++ linux-2.6.20.3/arch/i386/kernel/efi_stub.S  2007-03-23 08:10:05.000000000 -0400
1373 @@ -6,6 +6,7 @@
1374   */
1375  
1376  #include <linux/linkage.h>
1377 +#include <linux/init.h>
1378  #include <asm/page.h>
1379  
1380  /*
1381 @@ -20,7 +21,7 @@
1382   * service functions will comply with gcc calling convention, too.
1383   */
1384  
1385 -.text
1386 +__INIT
1387  ENTRY(efi_call_phys)
1388         /*
1389          * 0. The function can only be called in Linux kernel. So CS has been
1390 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
1391          * The mapping of lower virtual memory has been created in prelog and
1392          * epilog.
1393          */
1394 -       movl    $1f, %edx
1395 -       subl    $__PAGE_OFFSET, %edx
1396 -       jmp     *%edx
1397 +       jmp     1f-__PAGE_OFFSET
1398  1:
1399  
1400         /*
1401 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
1402          * parameter 2, ..., param n. To make things easy, we save the return
1403          * address of efi_call_phys in a global variable.
1404          */
1405 -       popl    %edx
1406 -       movl    %edx, saved_return_addr
1407 -       /* get the function pointer into ECX*/
1408 -       popl    %ecx
1409 -       movl    %ecx, efi_rt_function_ptr
1410 -       movl    $2f, %edx
1411 -       subl    $__PAGE_OFFSET, %edx
1412 -       pushl   %edx
1413 +       popl    (saved_return_addr)
1414 +       popl    (efi_rt_function_ptr)
1415  
1416         /*
1417          * 3. Clear PG bit in %CR0.
1418 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
1419         /*
1420          * 5. Call the physical function.
1421          */
1422 -       jmp     *%ecx
1423 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
1424  
1425 -2:
1426         /*
1427          * 6. After EFI runtime service returns, control will return to
1428          * following instruction. We'd better readjust stack pointer first.
1429 @@ -85,37 +77,29 @@ ENTRY(efi_call_phys)
1430         /*
1431          * 7. Restore PG bit
1432          */
1433 -       movl    %cr0, %edx
1434 -       orl     $0x80000000, %edx
1435 -       movl    %edx, %cr0
1436 -       jmp     1f
1437 -1:
1438         /*
1439          * 8. Now restore the virtual mode from flat mode by
1440          * adding EIP with PAGE_OFFSET.
1441          */
1442 -       movl    $1f, %edx
1443 -       jmp     *%edx
1444 +       movl    %cr0, %edx
1445 +       orl     $0x80000000, %edx
1446 +       movl    %edx, %cr0
1447 +       jmp     1f+__PAGE_OFFSET
1448  1:
1449  
1450         /*
1451          * 9. Balance the stack. And because EAX contain the return value,
1452          * we'd better not clobber it.
1453          */
1454 -       leal    efi_rt_function_ptr, %edx
1455 -       movl    (%edx), %ecx
1456 -       pushl   %ecx
1457 +       pushl   (efi_rt_function_ptr)
1458  
1459         /*
1460 -        * 10. Push the saved return address onto the stack and return.
1461 +        * 10. Return to the saved return address.
1462          */
1463 -       leal    saved_return_addr, %edx
1464 -       movl    (%edx), %ecx
1465 -       pushl   %ecx
1466 -       ret
1467 +       jmpl    *(saved_return_addr)
1468  .previous
1469  
1470 -.data
1471 +__INITDATA
1472  saved_return_addr:
1473         .long 0
1474  efi_rt_function_ptr:
1475 diff -urNp linux-2.6.20.3/arch/i386/kernel/entry.S linux-2.6.20.3/arch/i386/kernel/entry.S
1476 --- linux-2.6.20.3/arch/i386/kernel/entry.S     2007-03-13 14:27:08.000000000 -0400
1477 +++ linux-2.6.20.3/arch/i386/kernel/entry.S     2007-03-23 08:10:05.000000000 -0400
1478 @@ -49,7 +49,6 @@
1479  #include <asm/smp.h>
1480  #include <asm/page.h>
1481  #include <asm/desc.h>
1482 -#include <asm/percpu.h>
1483  #include <asm/dwarf2.h>
1484  #include "irq_vectors.h"
1485  
1486 @@ -97,7 +96,7 @@ VM_MASK               = 0x00020000
1487  #define resume_userspace_sig   resume_userspace
1488  #endif
1489  
1490 -#define SAVE_ALL \
1491 +#define __SAVE_ALL(_DS) \
1492         cld; \
1493         pushl %gs; \
1494         CFI_ADJUST_CFA_OFFSET 4;\
1495 @@ -129,12 +128,26 @@ VM_MASK           = 0x00020000
1496         pushl %ebx; \
1497         CFI_ADJUST_CFA_OFFSET 4;\
1498         CFI_REL_OFFSET ebx, 0;\
1499 -       movl $(__USER_DS), %edx; \
1500 +       movl $(_DS), %edx; \
1501         movl %edx, %ds; \
1502         movl %edx, %es; \
1503         movl $(__KERNEL_PDA), %edx; \
1504         movl %edx, %gs
1505  
1506 +#ifdef CONFIG_PAX_KERNEXEC
1507 +#define SAVE_ALL \
1508 +       __SAVE_ALL(__KERNEL_DS); \
1509 +       GET_CR0_INTO_EDX; \
1510 +       movl %edx, %esi; \
1511 +       orl $0x10000, %edx; \
1512 +       xorl %edx, %esi; \
1513 +       SET_CR0_FROM_EDX
1514 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
1515 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
1516 +#else
1517 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
1518 +#endif
1519 +
1520  #define RESTORE_INT_REGS \
1521         popl %ebx;      \
1522         CFI_ADJUST_CFA_OFFSET -4;\
1523 @@ -247,7 +260,17 @@ check_userspace:
1524         movb PT_CS(%esp), %al
1525         andl $(VM_MASK | SEGMENT_RPL_MASK), %eax
1526         cmpl $USER_RPL, %eax
1527 +
1528 +#ifdef CONFIG_PAX_KERNEXEC
1529 +       jae resume_userspace
1530 +
1531 +       GET_CR0_INTO_EDX
1532 +       xorl %esi, %edx
1533 +       SET_CR0_FROM_EDX
1534 +       jmp resume_kernel
1535 +#else
1536         jb resume_kernel                # not returning to v8086 or userspace
1537 +#endif
1538  
1539  ENTRY(resume_userspace)
1540         DISABLE_INTERRUPTS(CLBR_ANY)    # make sure we don't miss an interrupt
1541 @@ -305,10 +328,9 @@ sysenter_past_esp:
1542  #ifndef CONFIG_COMPAT_VDSO
1543         /*
1544          * Push current_thread_info()->sysenter_return to the stack.
1545 -        * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
1546 -        * pushed above; +8 corresponds to copy_thread's esp0 setting.
1547          */
1548 -       pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
1549 +       GET_THREAD_INFO(%ebp)
1550 +       pushl TI_sysenter_return(%ebp)
1551  #else
1552         pushl $SYSENTER_RETURN
1553  #endif
1554 @@ -319,9 +341,20 @@ sysenter_past_esp:
1555   * Load the potential sixth argument from user stack.
1556   * Careful about security.
1557   */
1558 +       movl 12(%esp),%ebp
1559 +
1560 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1561 +       pushl $(__USER_DS)
1562 +       CFI_ADJUST_CFA_OFFSET 4
1563 +       pop %ds
1564 +       CFI_ADJUST_CFA_OFFSET -4
1565 +1:     movl %ds:(%ebp),%ebp
1566 +#else
1567         cmpl $__PAGE_OFFSET-3,%ebp
1568         jae syscall_fault
1569  1:     movl (%ebp),%ebp
1570 +#endif
1571 +
1572  .section __ex_table,"a"
1573         .align 4
1574         .long 1b,syscall_fault
1575 @@ -344,20 +377,37 @@ sysenter_past_esp:
1576         movl TI_flags(%ebp), %ecx
1577         testw $_TIF_ALLWORK_MASK, %cx
1578         jne syscall_exit_work
1579 +
1580 +#ifdef CONFIG_PAX_RANDKSTACK
1581 +       pushl %eax
1582 +       CFI_ADJUST_CFA_OFFSET 4
1583 +       call pax_randomize_kstack
1584 +       popl %eax
1585 +       CFI_ADJUST_CFA_OFFSET -4
1586 +#endif
1587 +
1588  /* if something modifies registers it must also disable sysexit */
1589         movl PT_EIP(%esp), %edx
1590         movl PT_OLDESP(%esp), %ecx
1591         xorl %ebp,%ebp
1592         TRACE_IRQS_ON
1593  1:     mov  PT_GS(%esp), %gs
1594 +2:     mov  PT_DS(%esp), %ds
1595 +3:     mov  PT_ES(%esp), %es
1596         ENABLE_INTERRUPTS_SYSEXIT
1597         CFI_ENDPROC
1598  .pushsection .fixup,"ax"
1599 -2:     movl $0,PT_GS(%esp)
1600 +4:     movl $0,PT_GS(%esp)
1601         jmp 1b
1602 +5:     movl $0,PT_DS(%esp)
1603 +       jmp 2b
1604 +6:     movl $0,PT_ES(%esp)
1605 +       jmp 3b
1606  .section __ex_table,"a"
1607         .align 4
1608 -       .long 1b,2b
1609 +       .long 1b,4b
1610 +       .long 2b,5b
1611 +       .long 3b,6b
1612  .popsection
1613  
1614         # system call handler stub
1615 @@ -389,6 +439,10 @@ syscall_exit:
1616         testw $_TIF_ALLWORK_MASK, %cx   # current->work
1617         jne syscall_exit_work
1618  
1619 +#ifdef CONFIG_PAX_RANDKSTACK
1620 +       call pax_randomize_kstack
1621 +#endif
1622 +
1623  restore_all:
1624         movl PT_EFLAGS(%esp), %eax      # mix EFLAGS, SS and CS
1625         # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
1626 @@ -551,8 +605,7 @@ syscall_badsys:
1627  #define FIXUP_ESPFIX_STACK \
1628         /* since we are on a wrong stack, we cant make it a C code :( */ \
1629         movl %gs:PDA_cpu, %ebx; \
1630 -       PER_CPU(cpu_gdt_descr, %ebx); \
1631 -       movl GDS_address(%ebx), %ebx; \
1632 +       movl GDS_address+cpu_gdt_descr(,%ebx,8), %ebx; \
1633         GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
1634         addl %esp, %eax; \
1635         pushl $__KERNEL_DS; \
1636 @@ -577,7 +630,7 @@ syscall_badsys:
1637   * Build the entry stubs and pointer table with
1638   * some assembler magic.
1639   */
1640 -.data
1641 +.section .rodata,"a",@progbits
1642  ENTRY(interrupt)
1643  .text
1644  
1645 @@ -592,7 +645,7 @@ ENTRY(irq_entries_start)
1646  1:     pushl $~(vector)
1647         CFI_ADJUST_CFA_OFFSET 4
1648         jmp common_interrupt
1649 -.data
1650 +.section .rodata,"a",@progbits
1651         .long 1b
1652  .text
1653  vector=vector+1
1654 @@ -670,12 +723,21 @@ error_code:
1655         popl %ecx
1656         CFI_ADJUST_CFA_OFFSET -4
1657         /*CFI_REGISTER es, ecx*/
1658 +
1659 +#ifdef CONFIG_PAX_KERNEXEC
1660 +       GET_CR0_INTO_EDX
1661 +       movl %edx, %esi
1662 +       orl $0x10000, %edx
1663 +       xorl %edx, %esi
1664 +       SET_CR0_FROM_EDX
1665 +#endif
1666 +
1667         movl PT_GS(%esp), %edi          # get the function address
1668         movl PT_ORIG_EAX(%esp), %edx    # get the error code
1669         movl $-1, PT_ORIG_EAX(%esp)     # no syscall to restart
1670         mov  %ecx, PT_GS(%esp)
1671         /*CFI_REL_OFFSET gs, ES*/
1672 -       movl $(__USER_DS), %ecx
1673 +       movl $(__KERNEL_DS), %ecx
1674         movl %ecx, %ds
1675         movl %ecx, %es
1676         movl %esp,%eax                  # pt_regs pointer
1677 @@ -806,6 +868,13 @@ nmi_stack_correct:
1678         xorl %edx,%edx          # zero error code
1679         movl %esp,%eax          # pt_regs pointer
1680         call do_nmi
1681 +
1682 +#ifdef CONFIG_PAX_KERNEXEC
1683 +       GET_CR0_INTO_EDX
1684 +       xorl %esi, %edx
1685 +       SET_CR0_FROM_EDX
1686 +#endif
1687 +
1688         jmp restore_nocheck_notrace
1689         CFI_ENDPROC
1690  
1691 @@ -846,6 +915,13 @@ nmi_espfix_stack:
1692         FIXUP_ESPFIX_STACK              # %eax == %esp
1693         xorl %edx,%edx                  # zero error code
1694         call do_nmi
1695 +
1696 +#ifdef CONFIG_PAX_KERNEXEC
1697 +       GET_CR0_INTO_EDX
1698 +       xorl %esi, %edx
1699 +       SET_CR0_FROM_EDX
1700 +#endif
1701 +
1702         RESTORE_REGS
1703         lss 12+4(%esp), %esp            # back to espfix stack
1704         CFI_ADJUST_CFA_OFFSET -24
1705 @@ -996,7 +1072,6 @@ ENTRY(kernel_thread_helper)
1706         CFI_ENDPROC
1707  ENDPROC(kernel_thread_helper)
1708  
1709 -.section .rodata,"a"
1710  #include "syscall_table.S"
1711  
1712  syscall_table_size=(.-sys_call_table)
1713 diff -urNp linux-2.6.20.3/arch/i386/kernel/head.S linux-2.6.20.3/arch/i386/kernel/head.S
1714 --- linux-2.6.20.3/arch/i386/kernel/head.S      2007-03-13 14:27:08.000000000 -0400
1715 +++ linux-2.6.20.3/arch/i386/kernel/head.S      2007-03-23 08:10:05.000000000 -0400
1716 @@ -45,6 +45,16 @@
1717   */
1718  #define INIT_MAP_BEYOND_END    (128*1024)
1719  
1720 +#ifdef CONFIG_PAX_KERNEXEC
1721 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
1722 +.fill 4096,1,0xcc
1723 +#endif
1724 +
1725 +/*
1726 + * Real beginning of normal "text" segment
1727 + */
1728 +ENTRY(stext)
1729 +ENTRY(_stext)
1730  
1731  /*
1732   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
1733 @@ -72,6 +82,45 @@ ENTRY(startup_32)
1734         movl %eax,%fs
1735         movl %eax,%gs
1736  
1737 +       /* get the PDA pointer */
1738 +       movl $boot_pda, %eax
1739 +
1740 +       /* slot the PDA address into the GDT */
1741 +       mov %ax, (cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PDA+0+2)             /* base & 0x0000ffff */
1742 +       shr $16, %eax
1743 +       mov %al, (cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PDA+4+0)             /* base & 0x00ff0000 */
1744 +       mov %ah, (cpu_gdt_table - __PAGE_OFFSET + __KERNEL_PDA+4+3)             /* base & 0xff000000 */
1745 +
1746 +#ifdef CONFIG_PAX_MEMORY_UDEREF
1747 +       /* check for VMware */
1748 +       movl $0x564d5868,%eax
1749 +       xorl %ebx,%ebx
1750 +       movl $0xa,%ecx
1751 +       movl $0x5658,%edx
1752 +       in (%dx),%eax
1753 +       cmpl $0x564d5868,%ebx
1754 +       jz 1f
1755 +
1756 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax
1757 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_KERNEL_DS * 8 + 4)
1758 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c0f300),%eax
1759 +       movl %eax,(cpu_gdt_table - __PAGE_OFFSET + GDT_ENTRY_DEFAULT_USER_DS * 8 + 4)
1760 +1:
1761 +#endif
1762 +
1763 +#ifdef CONFIG_PAX_KERNEXEC
1764 +       movl $ __KERNEL_TEXT_OFFSET,%eax
1765 +       movw %ax,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 2)
1766 +       rorl $16,%eax
1767 +       movb %al,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 4)
1768 +       movb %ah,(cpu_gdt_table - __PAGE_OFFSET + __KERNEL_CS + 7)
1769 +
1770 +       movb %al,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 4)
1771 +       movb %ah,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 7)
1772 +       rorl $16,%eax
1773 +       movw %ax,(boot_gdt_table - __PAGE_OFFSET + __BOOT_CS + 2)
1774 +#endif
1775 +
1776  /*
1777   * Clear BSS first so that there are no surprises...
1778   * No need to cld as DF is already clear from cld above...
1779 @@ -119,24 +168,42 @@ ENTRY(startup_32)
1780   * Warning: don't use %esi or the stack in this code.  However, %esp
1781   * can be used as a GPR if you really need it...
1782   */
1783 -page_pde_offset = (__PAGE_OFFSET >> 20);
1784 -
1785 +#ifdef CONFIG_X86_PAE
1786 +page_pde_offset = ((__PAGE_OFFSET >> 21) * (4096 / PTRS_PER_PTE_asm));
1787 +#else
1788 +page_pde_offset = ((__PAGE_OFFSET >> 22) * (4096 / PTRS_PER_PTE_asm));
1789 +#endif
1790         movl $(pg0 - __PAGE_OFFSET), %edi
1791 +#ifdef CONFIG_X86_PAE
1792 +       movl $(swapper_pm_dir - __PAGE_OFFSET), %edx
1793 +#else
1794         movl $(swapper_pg_dir - __PAGE_OFFSET), %edx
1795 -       movl $0x007, %eax                       /* 0x007 = PRESENT+RW+USER */
1796 +#endif
1797 +       movl $0x063, %eax                       /* 0x063 = DIRTY+ACCESSED+PRESENT+RW */
1798  10:
1799 -       leal 0x007(%edi),%ecx                   /* Create PDE entry */
1800 +       leal 0x063(%edi),%ecx                   /* Create PDE entry */
1801         movl %ecx,(%edx)                        /* Store identity PDE entry */
1802         movl %ecx,page_pde_offset(%edx)         /* Store kernel PDE entry */
1803 +#ifdef CONFIG_X86_PAE
1804 +       movl $0,4(%edx)
1805 +       movl $0,page_pde_offset+4(%edx)
1806 +       addl $8,%edx
1807 +       movl $512, %ecx
1808 +#else
1809         addl $4,%edx
1810         movl $1024, %ecx
1811 +#endif
1812  11:
1813         stosl
1814 +#ifdef CONFIG_X86_PAE
1815 +       movl $0,(%edi)
1816 +       addl $4,%edi
1817 +#endif
1818         addl $0x1000,%eax
1819         loop 11b
1820         /* End condition: we must map up to and including INIT_MAP_BEYOND_END */
1821 -       /* bytes beyond the end of our own page tables; the +0x007 is the attribute bits */
1822 -       leal (INIT_MAP_BEYOND_END+0x007)(%edi),%ebp
1823 +       /* bytes beyond the end of our own page tables; the +0x063 is the attribute bits */
1824 +       leal (INIT_MAP_BEYOND_END+0x063)(%edi),%ebp
1825         cmpl %ebp,%eax
1826         jb 10b
1827         movl %edi,(init_pg_tables_end - __PAGE_OFFSET)
1828 @@ -159,6 +226,11 @@ ENTRY(startup_32_smp)
1829         movl %eax,%fs
1830         movl %eax,%gs
1831  
1832 +       /* This is a secondary processor (AP) */
1833 +       xorl %ebx,%ebx
1834 +       incl %ebx
1835 +#endif /* CONFIG_SMP */
1836 +
1837  /*
1838   *     New page tables may be in 4Mbyte page mode and may
1839   *     be using the global pages. 
1840 @@ -174,26 +246,27 @@ ENTRY(startup_32_smp)
1841   *     not yet offset PAGE_OFFSET..
1842   */
1843  #define cr4_bits mmu_cr4_features-__PAGE_OFFSET
1844 +3:
1845         movl cr4_bits,%edx
1846         andl %edx,%edx
1847 -       jz 6f
1848 +       jz 5f
1849         movl %cr4,%eax          # Turn on paging options (PSE,PAE,..)
1850         orl %edx,%eax
1851         movl %eax,%cr4
1852  
1853 -       btl $5, %eax            # check if PAE is enabled
1854 -       jnc 6f
1855 +#ifdef CONFIG_X86_PAE
1856 +       movl %ebx,%edi
1857  
1858         /* Check if extended functions are implemented */
1859         movl $0x80000000, %eax
1860         cpuid
1861         cmpl $0x80000000, %eax
1862 -       jbe 6f
1863 +       jbe 4f
1864         mov $0x80000001, %eax
1865         cpuid
1866         /* Execute Disable bit supported? */
1867         btl $20, %edx
1868 -       jnc 6f
1869 +       jnc 4f
1870  
1871         /* Setup EFER (Extended Feature Enable Register) */
1872         movl $0xc0000080, %ecx
1873 @@ -202,14 +275,13 @@ ENTRY(startup_32_smp)
1874         btsl $11, %eax
1875         /* Make changes effective */
1876         wrmsr
1877 +       btsl $63,__supported_pte_mask-__PAGE_OFFSET
1878 +       movl $1,nx_enabled-__PAGE_OFFSET
1879  
1880 -6:
1881 -       /* This is a secondary processor (AP) */
1882 -       xorl %ebx,%ebx
1883 -       incl %ebx
1884 -
1885 -3:
1886 -#endif /* CONFIG_SMP */
1887 +4:
1888 +       movl %edi,%ebx
1889 +#endif
1890 +5:
1891  
1892  /*
1893   * Enable paging
1894 @@ -234,9 +306,7 @@ ENTRY(startup_32_smp)
1895  
1896  #ifdef CONFIG_SMP
1897         andl %ebx,%ebx
1898 -       jz  1f                          /* Initial CPU cleans BSS */
1899 -       jmp checkCPUtype
1900 -1:
1901 +       jnz checkCPUtype        /* Initial CPU cleans BSS */
1902  #endif /* CONFIG_SMP */
1903  
1904  /*
1905 @@ -308,14 +378,13 @@ is386:    movl $2,%ecx            # set MP
1906         movl %eax,%cr0
1907  
1908         call check_x87
1909 -       call setup_pda
1910 -       lgdt cpu_gdt_descr
1911 +       GET_THREAD_INFO(%ecx)
1912 +       movl TI_cpu(%ecx),%ecx
1913 +       lgdt cpu_gdt_descr(,%ecx,8)
1914         lidt idt_descr
1915         ljmp $(__KERNEL_CS),$1f
1916  1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
1917         movl %eax,%ss                   # after changing gdt.
1918 -
1919 -       movl $(__USER_DS),%eax          # DS/ES contains default USER segment
1920         movl %eax,%ds
1921         movl %eax,%es
1922  
1923 @@ -356,23 +425,6 @@ check_x87:
1924         ret
1925  
1926  /*
1927 - * Point the GDT at this CPU's PDA.  On boot this will be
1928 - * cpu_gdt_table and boot_pda; for secondary CPUs, these will be
1929 - * that CPU's GDT and PDA.
1930 - */
1931 -setup_pda:
1932 -       /* get the PDA pointer */
1933 -       movl start_pda, %eax
1934 -
1935 -       /* slot the PDA address into the GDT */
1936 -       mov cpu_gdt_descr+2, %ecx
1937 -       mov %ax, (__KERNEL_PDA+0+2)(%ecx)               /* base & 0x0000ffff */
1938 -       shr $16, %eax
1939 -       mov %al, (__KERNEL_PDA+4+0)(%ecx)               /* base & 0x00ff0000 */
1940 -       mov %ah, (__KERNEL_PDA+4+3)(%ecx)               /* base & 0xff000000 */
1941 -       ret
1942 -
1943 -/*
1944   *  setup_idt
1945   *
1946   *  sets up a idt with 256 entries pointing to
1947 @@ -460,8 +512,8 @@ hlt_loop:
1948  /* This is the default interrupt "handler" :-) */
1949         ALIGN
1950  ignore_int:
1951 -       cld
1952  #ifdef CONFIG_PRINTK
1953 +       cld
1954         pushl %eax
1955         pushl %ecx
1956         pushl %edx
1957 @@ -495,7 +547,7 @@ ignore_int:
1958  #ifdef CONFIG_PARAVIRT
1959  startup_paravirt:
1960         cld
1961 -       movl $(init_thread_union+THREAD_SIZE),%esp
1962 +       movl $(init_thread_union+THREAD_SIZE-8),%esp
1963  
1964         /* We take pains to preserve all the regs. */
1965         pushl   %edx
1966 @@ -519,30 +571,63 @@ startup_paravirt:
1967         jmp     1b
1968  #endif
1969  
1970 -/*
1971 - * Real beginning of normal "text" segment
1972 - */
1973 -ENTRY(stext)
1974 -ENTRY(_stext)
1975 -
1976 -/*
1977 - * BSS section
1978 - */
1979 -.section ".bss.page_aligned","w"
1980 +.section .swapper_pg_dir,"a",@progbits
1981  ENTRY(swapper_pg_dir)
1982 +#ifdef CONFIG_X86_PAE
1983 +       .long swapper_pm_dir-__PAGE_OFFSET+1
1984 +       .long 0
1985 +       .long swapper_pm_dir+512*8-__PAGE_OFFSET+1
1986 +       .long 0
1987 +       .long swapper_pm_dir+512*16-__PAGE_OFFSET+1
1988 +       .long 0
1989 +       .long swapper_pm_dir+512*24-__PAGE_OFFSET+1
1990 +       .long 0
1991 +#else
1992         .fill 1024,4,0
1993 +#endif
1994 +
1995 +#ifdef CONFIG_X86_PAE
1996 +.section .swapper_pm_dir,"a",@progbits
1997 +ENTRY(swapper_pm_dir)
1998 +       .fill 512,8,0
1999 +       .fill 512,8,0
2000 +       .fill 512,8,0
2001 +       .fill 512,8,0
2002 +#endif
2003 +
2004 +.section .empty_zero_page,"a",@progbits
2005  ENTRY(empty_zero_page)
2006         .fill 4096,1,0
2007  
2008  /*
2009 - * This starts the data section.
2010 - */
2011 -.data
2012 -ENTRY(start_pda)
2013 -       .long boot_pda
2014 + * The IDT has to be page-aligned to simplify the Pentium
2015 + * F0 0F bug workaround.. We have a special link segment
2016 + * for this.
2017 + */
2018 +.section .idt,"a",@progbits
2019 +ENTRY(idt_table)
2020 +       .fill 256,8,0
2021 +
2022 +.section .rodata,"a",@progbits
2023 +cpu=0
2024 +ENTRY(_cpu_pda)
2025 +.rept NR_CPUS
2026 +       .long __cpu_pda + cpu*PDA_size
2027 +cpu=cpu+1
2028 +.endr
2029 +
2030 +cpu=0
2031 +ENTRY(__cpu_pda)
2032 +.rept NR_CPUS
2033 +1:     .long 1b
2034 +       .long cpu
2035 +       .long 0
2036 +       .long 0
2037 +cpu=cpu+1
2038 +.endr
2039  
2040  ENTRY(stack_start)
2041 -       .long init_thread_union+THREAD_SIZE
2042 +       .long init_thread_union+THREAD_SIZE-8
2043         .long __BOOT_DS
2044  
2045  ready: .byte 0
2046 @@ -585,6 +670,8 @@ ENTRY(cpu_gdt_descr)
2047         .word GDT_ENTRIES*8-1
2048         .long cpu_gdt_table
2049  
2050 +       .fill NR_CPUS*8-6,1,0           # space for the other GDT descriptors
2051 +
2052  /*
2053   * The boot_gdt_table must mirror the equivalent in setup.S and is
2054   * used only for booting.
2055 @@ -592,13 +679,13 @@ ENTRY(cpu_gdt_descr)
2056         .align L1_CACHE_BYTES
2057  ENTRY(boot_gdt_table)
2058         .fill GDT_ENTRY_BOOT_CS,8,0
2059 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
2060 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
2061 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
2062 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
2063  
2064  /*
2065   * The Global Descriptor Table contains 28 quadwords, per-CPU.
2066   */
2067 -       .align L1_CACHE_BYTES
2068 +       .align PAGE_SIZE_asm
2069  ENTRY(cpu_gdt_table)
2070         .quad 0x0000000000000000        /* NULL descriptor */
2071         .quad 0x0000000000000000        /* 0x0b reserved */
2072 @@ -613,10 +700,10 @@ ENTRY(cpu_gdt_table)
2073         .quad 0x0000000000000000        /* 0x53 reserved */
2074         .quad 0x0000000000000000        /* 0x5b reserved */
2075  
2076 -       .quad 0x00cf9a000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
2077 -       .quad 0x00cf92000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
2078 -       .quad 0x00cffa000000ffff        /* 0x73 user 4GB code at 0x00000000 */
2079 -       .quad 0x00cff2000000ffff        /* 0x7b user 4GB data at 0x00000000 */
2080 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
2081 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
2082 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
2083 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
2084  
2085         .quad 0x0000000000000000        /* 0x80 TSS descriptor */
2086         .quad 0x0000000000000000        /* 0x88 LDT descriptor */
2087 @@ -626,24 +713,30 @@ ENTRY(cpu_gdt_table)
2088          * They code segments and data segments have fixed 64k limits,
2089          * the transfer segment sizes are set at run time.
2090          */
2091 -       .quad 0x00409a000000ffff        /* 0x90 32-bit code */
2092 -       .quad 0x00009a000000ffff        /* 0x98 16-bit code */
2093 -       .quad 0x000092000000ffff        /* 0xa0 16-bit data */
2094 -       .quad 0x0000920000000000        /* 0xa8 16-bit data */
2095 -       .quad 0x0000920000000000        /* 0xb0 16-bit data */
2096 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
2097 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
2098 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
2099 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
2100 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
2101  
2102         /*
2103          * The APM segments have byte granularity and their bases
2104          * are set at run time.  All have 64k limits.
2105          */
2106 -       .quad 0x00409a000000ffff        /* 0xb8 APM CS    code */
2107 -       .quad 0x00009a000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
2108 -       .quad 0x004092000000ffff        /* 0xc8 APM DS    data */
2109 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
2110 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
2111 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
2112  
2113 -       .quad 0x00c0920000000000        /* 0xd0 - ESPFIX SS */
2114 -       .quad 0x00cf92000000ffff        /* 0xd8 - PDA */
2115 +       .quad 0x00c0930000000000        /* 0xd0 - ESPFIX SS */
2116 +       .quad 0x00c093000000ffff        /* 0xd8 - PDA */
2117         .quad 0x0000000000000000        /* 0xe0 - unused */
2118         .quad 0x0000000000000000        /* 0xe8 - unused */
2119         .quad 0x0000000000000000        /* 0xf0 - unused */
2120         .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
2121  
2122 +       /* Be sure this is zeroed to avoid false validations in Xen */
2123 +       .fill PAGE_SIZE_asm / 8 - GDT_ENTRIES,8,0
2124 +
2125 +#ifdef CONFIG_SMP
2126 +       .fill (NR_CPUS-1) * (PAGE_SIZE_asm / 8),8,0 /* other CPU's GDT */
2127 +#endif
2128 diff -urNp linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c
2129 --- linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c        2007-03-13 14:27:08.000000000 -0400
2130 +++ linux-2.6.20.3/arch/i386/kernel/i386_ksyms.c        2007-03-23 08:10:05.000000000 -0400
2131 @@ -2,12 +2,16 @@
2132  #include <asm/checksum.h>
2133  #include <asm/desc.h>
2134  
2135 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
2136 +
2137  EXPORT_SYMBOL(__down_failed);
2138  EXPORT_SYMBOL(__down_failed_interruptible);
2139  EXPORT_SYMBOL(__down_failed_trylock);
2140  EXPORT_SYMBOL(__up_wakeup);
2141  /* Networking helper routines. */
2142  EXPORT_SYMBOL(csum_partial_copy_generic);
2143 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
2144 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
2145  
2146  EXPORT_SYMBOL(__get_user_1);
2147  EXPORT_SYMBOL(__get_user_2);
2148 diff -urNp linux-2.6.20.3/arch/i386/kernel/i8259.c linux-2.6.20.3/arch/i386/kernel/i8259.c
2149 --- linux-2.6.20.3/arch/i386/kernel/i8259.c     2007-03-13 14:27:08.000000000 -0400
2150 +++ linux-2.6.20.3/arch/i386/kernel/i8259.c     2007-03-23 08:10:06.000000000 -0400
2151 @@ -350,7 +350,7 @@ static irqreturn_t math_error_irq(int cp
2152   * New motherboards sometimes make IRQ 13 be a PCI interrupt,
2153   * so allow interrupt sharing.
2154   */
2155 -static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL };
2156 +static struct irqaction fpu_irq = { math_error_irq, 0, CPU_MASK_NONE, "fpu", NULL, NULL, 0, NULL };
2157  
2158  void __init init_ISA_irqs (void)
2159  {
2160 diff -urNp linux-2.6.20.3/arch/i386/kernel/init_task.c linux-2.6.20.3/arch/i386/kernel/init_task.c
2161 --- linux-2.6.20.3/arch/i386/kernel/init_task.c 2007-03-13 14:27:08.000000000 -0400
2162 +++ linux-2.6.20.3/arch/i386/kernel/init_task.c 2007-03-23 08:10:06.000000000 -0400
2163 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
2164   * per-CPU TSS segments. Threads are completely 'soft' on Linux,
2165   * no more per-task TSS's.
2166   */ 
2167 -DEFINE_PER_CPU(struct tss_struct, init_tss) ____cacheline_internodealigned_in_smp = INIT_TSS;
2168 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
2169  
2170 diff -urNp linux-2.6.20.3/arch/i386/kernel/io_apic.c linux-2.6.20.3/arch/i386/kernel/io_apic.c
2171 --- linux-2.6.20.3/arch/i386/kernel/io_apic.c   2007-03-13 14:27:08.000000000 -0400
2172 +++ linux-2.6.20.3/arch/i386/kernel/io_apic.c   2007-03-23 08:10:06.000000000 -0400
2173 @@ -357,8 +357,8 @@ static void set_ioapic_affinity_irq(unsi
2174  #  define TDprintk(x...) do { printk("<%ld:%s:%d>: ", jiffies, __FILE__, __LINE__); printk(x); } while (0)
2175  #  define Dprintk(x...) do { TDprintk(x); } while (0)
2176  # else
2177 -#  define TDprintk(x...) 
2178 -#  define Dprintk(x...) 
2179 +#  define TDprintk(x...) do {} while (0)
2180 +#  define Dprintk(x...) do {} while (0)
2181  # endif
2182  
2183  #define IRQBALANCE_CHECK_ARCH -999
2184 diff -urNp linux-2.6.20.3/arch/i386/kernel/ioport.c linux-2.6.20.3/arch/i386/kernel/ioport.c
2185 --- linux-2.6.20.3/arch/i386/kernel/ioport.c    2007-03-13 14:27:08.000000000 -0400
2186 +++ linux-2.6.20.3/arch/i386/kernel/ioport.c    2007-03-23 08:11:18.000000000 -0400
2187 @@ -16,6 +16,7 @@
2188  #include <linux/stddef.h>
2189  #include <linux/slab.h>
2190  #include <linux/thread_info.h>
2191 +#include <linux/grsecurity.h>
2192  
2193  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
2194  static void set_bitmap(unsigned long *bitmap, unsigned int base, unsigned int extent, int new_value)
2195 @@ -64,9 +65,16 @@ asmlinkage long sys_ioperm(unsigned long
2196  
2197         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
2198                 return -EINVAL;
2199 +#ifdef CONFIG_GRKERNSEC_IO
2200 +       if (turn_on) {
2201 +               gr_handle_ioperm();
2202 +#else
2203         if (turn_on && !capable(CAP_SYS_RAWIO))
2204 +#endif
2205                 return -EPERM;
2206 -
2207 +#ifdef CONFIG_GRKERNSEC_IO
2208 +       }
2209 +#endif
2210         /*
2211          * If it's the first ioperm() call in this thread's lifetime, set the
2212          * IO bitmap up. ioperm() is much less timing critical than clone(),
2213 @@ -89,7 +97,7 @@ asmlinkage long sys_ioperm(unsigned long
2214          * because the ->io_bitmap_max value must match the bitmap
2215          * contents:
2216          */
2217 -       tss = &per_cpu(init_tss, get_cpu());
2218 +       tss = init_tss + get_cpu();
2219  
2220         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
2221  
2222 @@ -143,8 +151,13 @@ asmlinkage long sys_iopl(unsigned long u
2223                 return -EINVAL;
2224         /* Trying to gain more privileges? */
2225         if (level > old) {
2226 +#ifdef CONFIG_GRKERNSEC_IO
2227 +               gr_handle_iopl();
2228 +               return -EPERM;
2229 +#else
2230                 if (!capable(CAP_SYS_RAWIO))
2231                         return -EPERM;
2232 +#endif
2233         }
2234         t->iopl = level << 12;
2235         regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
2236 diff -urNp linux-2.6.20.3/arch/i386/kernel/irq.c linux-2.6.20.3/arch/i386/kernel/irq.c
2237 --- linux-2.6.20.3/arch/i386/kernel/irq.c       2007-03-13 14:27:08.000000000 -0400
2238 +++ linux-2.6.20.3/arch/i386/kernel/irq.c       2007-03-23 08:10:06.000000000 -0400
2239 @@ -100,7 +100,7 @@ fastcall unsigned int do_IRQ(struct pt_r
2240                 int arg1, arg2, ebx;
2241  
2242                 /* build the stack frame on the IRQ stack */
2243 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2244 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2245                 irqctx->tinfo.task = curctx->tinfo.task;
2246                 irqctx->tinfo.previous_esp = current_stack_pointer;
2247  
2248 @@ -137,10 +137,10 @@ fastcall unsigned int do_IRQ(struct pt_r
2249   * gcc's 3.0 and earlier don't handle that correctly.
2250   */
2251  static char softirq_stack[NR_CPUS * THREAD_SIZE]
2252 -               __attribute__((__aligned__(THREAD_SIZE)));
2253 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2254  
2255  static char hardirq_stack[NR_CPUS * THREAD_SIZE]
2256 -               __attribute__((__aligned__(THREAD_SIZE)));
2257 +               __attribute__((__aligned__(THREAD_SIZE), __section__(".bss.page_aligned")));
2258  
2259  /*
2260   * allocate per-cpu stacks for hardirq and for softirq processing
2261 @@ -200,7 +200,7 @@ asmlinkage void do_softirq(void)
2262                 irqctx->tinfo.previous_esp = current_stack_pointer;
2263  
2264                 /* build the stack frame on the softirq stack */
2265 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
2266 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx)) - 2;
2267  
2268                 asm volatile(
2269                         "       xchgl   %%ebx,%%esp     \n"
2270 diff -urNp linux-2.6.20.3/arch/i386/kernel/kprobes.c linux-2.6.20.3/arch/i386/kernel/kprobes.c
2271 --- linux-2.6.20.3/arch/i386/kernel/kprobes.c   2007-03-13 14:27:08.000000000 -0400
2272 +++ linux-2.6.20.3/arch/i386/kernel/kprobes.c   2007-03-23 08:10:06.000000000 -0400
2273 @@ -661,7 +661,7 @@ int __kprobes kprobe_exceptions_notify(s
2274         struct die_args *args = (struct die_args *)data;
2275         int ret = NOTIFY_DONE;
2276  
2277 -       if (args->regs && user_mode_vm(args->regs))
2278 +       if (args->regs && user_mode(args->regs))
2279                 return ret;
2280  
2281         switch (val) {
2282 diff -urNp linux-2.6.20.3/arch/i386/kernel/ldt.c linux-2.6.20.3/arch/i386/kernel/ldt.c
2283 --- linux-2.6.20.3/arch/i386/kernel/ldt.c       2007-03-13 14:27:08.000000000 -0400
2284 +++ linux-2.6.20.3/arch/i386/kernel/ldt.c       2007-03-23 08:10:06.000000000 -0400
2285 @@ -103,6 +103,22 @@ int init_new_context(struct task_struct 
2286                 retval = copy_ldt(&mm->context, &old_mm->context);
2287                 up(&old_mm->context.sem);
2288         }
2289 +
2290 +       if (tsk == current) {
2291 +               mm->context.vdso = ~0UL;
2292 +
2293 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
2294 +               mm->context.user_cs_base = 0UL;
2295 +               mm->context.user_cs_limit = ~0UL;
2296 +
2297 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
2298 +               cpus_clear(mm->context.cpu_user_cs_mask);
2299 +#endif
2300 +
2301 +#endif
2302 +
2303 +       }
2304 +
2305         return retval;
2306  }
2307  
2308 @@ -213,6 +229,13 @@ static int write_ldt(void __user * ptr, 
2309                 }
2310         }
2311  
2312 +#ifdef CONFIG_PAX_SEGMEXEC
2313 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
2314 +               error = -EINVAL;
2315 +               goto out_unlock;
2316 +       }
2317 +#endif
2318 +
2319         entry_1 = LDT_entry_a(&ldt_info);
2320         entry_2 = LDT_entry_b(&ldt_info);
2321         if (oldmode)
2322 diff -urNp linux-2.6.20.3/arch/i386/kernel/machine_kexec.c linux-2.6.20.3/arch/i386/kernel/machine_kexec.c
2323 --- linux-2.6.20.3/arch/i386/kernel/machine_kexec.c     2007-03-13 14:27:08.000000000 -0400
2324 +++ linux-2.6.20.3/arch/i386/kernel/machine_kexec.c     2007-03-23 08:10:06.000000000 -0400
2325 @@ -29,25 +29,25 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
2326  static u32 kexec_pte0[1024] PAGE_ALIGNED;
2327  static u32 kexec_pte1[1024] PAGE_ALIGNED;
2328  
2329 -static void set_idt(void *newidt, __u16 limit)
2330 +static void set_idt(struct desc_struct *newidt, __u16 limit)
2331  {
2332         struct Xgt_desc_struct curidt;
2333  
2334         /* ia32 supports unaliged loads & stores */
2335         curidt.size    = limit;
2336 -       curidt.address = (unsigned long)newidt;
2337 +       curidt.address = newidt;
2338  
2339         load_idt(&curidt);
2340  };
2341  
2342  
2343 -static void set_gdt(void *newgdt, __u16 limit)
2344 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
2345  {
2346         struct Xgt_desc_struct curgdt;
2347  
2348         /* ia32 supports unaligned loads & stores */
2349         curgdt.size    = limit;
2350 -       curgdt.address = (unsigned long)newgdt;
2351 +       curgdt.address = newgdt;
2352  
2353         load_gdt(&curgdt);
2354  };
2355 diff -urNp linux-2.6.20.3/arch/i386/kernel/module.c linux-2.6.20.3/arch/i386/kernel/module.c
2356 --- linux-2.6.20.3/arch/i386/kernel/module.c    2007-03-13 14:27:08.000000000 -0400
2357 +++ linux-2.6.20.3/arch/i386/kernel/module.c    2007-03-23 08:10:06.000000000 -0400
2358 @@ -23,6 +23,8 @@
2359  #include <linux/kernel.h>
2360  #include <linux/bug.h>
2361  
2362 +#include <asm/desc.h>
2363 +
2364  #if 0
2365  #define DEBUGP printk
2366  #else
2367 @@ -33,9 +35,30 @@ void *module_alloc(unsigned long size)
2368  {
2369         if (size == 0)
2370                 return NULL;
2371 +
2372 +#ifdef CONFIG_PAX_KERNEXEC
2373 +       return vmalloc(size);
2374 +#else
2375         return vmalloc_exec(size);
2376 +#endif
2377 +
2378  }
2379  
2380 +#ifdef CONFIG_PAX_KERNEXEC
2381 +void *module_alloc_exec(unsigned long size)
2382 +{
2383 +       struct vm_struct *area;
2384 +
2385 +       if (size == 0)
2386 +               return NULL;
2387 +
2388 +       area = __get_vm_area(size, 0, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
2389 +       if (area)
2390 +               return area->addr;
2391 +
2392 +       return NULL;
2393 +}
2394 +#endif
2395  
2396  /* Free memory returned from module_alloc */
2397  void module_free(struct module *mod, void *module_region)
2398 @@ -45,6 +68,45 @@ void module_free(struct module *mod, voi
2399             table entries. */
2400  }
2401  
2402 +#ifdef CONFIG_PAX_KERNEXEC
2403 +void module_free_exec(struct module *mod, void *module_region)
2404 +{
2405 +       struct vm_struct **p, *tmp;
2406 +
2407 +       if (!module_region)
2408 +               return;
2409 +
2410 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
2411 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
2412 +               WARN_ON(1);
2413 +               return;
2414 +       }
2415 +
2416 +       write_lock(&vmlist_lock);
2417 +       for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next)
2418 +                if (tmp->addr == module_region)
2419 +                       break;
2420 +
2421 +       if (tmp) {
2422 +               unsigned long cr0;
2423 +
2424 +               pax_open_kernel(cr0);
2425 +               memset(tmp->addr, 0xCC, tmp->size);
2426 +               pax_close_kernel(cr0);
2427 +
2428 +               *p = tmp->next;
2429 +               kfree(tmp);
2430 +       }
2431 +       write_unlock(&vmlist_lock);
2432 +
2433 +       if (!tmp) {
2434 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
2435 +                               module_region);
2436 +               WARN_ON(1);
2437 +       }
2438 +}
2439 +#endif
2440 +
2441  /* We don't need anything special. */
2442  int module_frob_arch_sections(Elf_Ehdr *hdr,
2443                               Elf_Shdr *sechdrs,
2444 @@ -63,14 +125,16 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2445         unsigned int i;
2446         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
2447         Elf32_Sym *sym;
2448 -       uint32_t *location;
2449 +       uint32_t *plocation, location;
2450  
2451         DEBUGP("Applying relocate section %u to %u\n", relsec,
2452                sechdrs[relsec].sh_info);
2453         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
2454                 /* This is where to make the change */
2455 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
2456 -                       + rel[i].r_offset;
2457 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
2458 +               location = (uint32_t)plocation;
2459 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
2460 +                       plocation = (void *)plocation + __KERNEL_TEXT_OFFSET;
2461                 /* This is the symbol it is referring to.  Note that all
2462                    undefined symbols have been resolved.  */
2463                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
2464 @@ -79,11 +143,11 @@ int apply_relocate(Elf32_Shdr *sechdrs,
2465                 switch (ELF32_R_TYPE(rel[i].r_info)) {
2466                 case R_386_32:
2467                         /* We add the value into the location given */
2468 -                       *location += sym->st_value;
2469 +                       *plocation += sym->st_value;
2470                         break;
2471                 case R_386_PC32:
2472                         /* Add the value, subtract its postition */
2473 -                       *location += sym->st_value - (uint32_t)location;
2474 +                       *plocation += sym->st_value - location;
2475                         break;
2476                 default:
2477                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
2478 diff -urNp linux-2.6.20.3/arch/i386/kernel/paravirt.c linux-2.6.20.3/arch/i386/kernel/paravirt.c
2479 --- linux-2.6.20.3/arch/i386/kernel/paravirt.c  2007-03-13 14:27:08.000000000 -0400
2480 +++ linux-2.6.20.3/arch/i386/kernel/paravirt.c  2007-03-23 08:10:06.000000000 -0400
2481 @@ -88,7 +88,7 @@ static unsigned native_patch(u8 type, u1
2482         if (len < insn_len)
2483                 return len;
2484  
2485 -       memcpy(insns, native_insns[type].start, insn_len);
2486 +       memcpy(insns, native_insns[type].start + __KERNEL_TEXT_OFFSET, insn_len);
2487         return insn_len;
2488  }
2489  
2490 @@ -336,16 +336,40 @@ static fastcall unsigned long native_sto
2491  
2492  static fastcall void native_load_tls(struct thread_struct *t, unsigned int cpu)
2493  {
2494 +
2495 +#ifdef CONFIG_PAX_KERNEXEC
2496 +       unsigned long cr0;
2497 +
2498 +       pax_open_kernel(cr0);
2499 +#endif
2500 +
2501  #define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
2502         C(0); C(1); C(2);
2503  #undef C
2504 +
2505 +#ifdef CONFIG_PAX_KERNEXEC
2506 +       pax_close_kernel(cr0);
2507 +#endif
2508 +
2509  }
2510  
2511  static inline void native_write_dt_entry(void *dt, int entry, u32 entry_low, u32 entry_high)
2512  {
2513         u32 *lp = (u32 *)((char *)dt + entry*8);
2514 +
2515 +#ifdef CONFIG_PAX_KERNEXEC
2516 +       unsigned long cr0;
2517 +
2518 +       pax_open_kernel(cr0);
2519 +#endif
2520 +
2521         lp[0] = entry_low;
2522         lp[1] = entry_high;
2523 +
2524 +#ifdef CONFIG_PAX_KERNEXEC
2525 +       pax_close_kernel(cr0);
2526 +#endif
2527 +
2528  }
2529  
2530  static fastcall void native_write_ldt_entry(void *dt, int entrynum, u32 low, u32 high)
2531 @@ -485,7 +509,7 @@ core_initcall(print_banner);
2532  /* We simply declare start_kernel to be the paravirt probe of last resort. */
2533  paravirt_probe(start_kernel);
2534  
2535 -struct paravirt_ops paravirt_ops = {
2536 +const struct paravirt_ops paravirt_ops = {
2537         .name = "bare hardware",
2538         .paravirt_enabled = 0,
2539         .kernel_rpl = 0,
2540 diff -urNp linux-2.6.20.3/arch/i386/kernel/process.c linux-2.6.20.3/arch/i386/kernel/process.c
2541 --- linux-2.6.20.3/arch/i386/kernel/process.c   2007-03-13 14:27:08.000000000 -0400
2542 +++ linux-2.6.20.3/arch/i386/kernel/process.c   2007-03-23 08:10:06.000000000 -0400
2543 @@ -70,7 +70,7 @@ EXPORT_SYMBOL(boot_option_idle_override)
2544   */
2545  unsigned long thread_saved_pc(struct task_struct *tsk)
2546  {
2547 -       return ((unsigned long *)tsk->thread.esp)[3];
2548 +       return tsk->thread.eip;
2549  }
2550  
2551  /*
2552 @@ -298,7 +298,7 @@ void show_regs(struct pt_regs * regs)
2553                 0xffff & regs->xcs,regs->eip, smp_processor_id());
2554         print_symbol("EIP is at %s\n", regs->eip);
2555  
2556 -       if (user_mode_vm(regs))
2557 +       if (user_mode(regs))
2558                 printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp);
2559         printk(" EFLAGS: %08lx    %s  (%s %.*s)\n",
2560                regs->eflags, print_tainted(), init_utsname()->release,
2561 @@ -338,8 +338,8 @@ int kernel_thread(int (*fn)(void *), voi
2562         regs.ebx = (unsigned long) fn;
2563         regs.edx = (unsigned long) arg;
2564  
2565 -       regs.xds = __USER_DS;
2566 -       regs.xes = __USER_DS;
2567 +       regs.xds = __KERNEL_DS;
2568 +       regs.xes = __KERNEL_DS;
2569         regs.xgs = __KERNEL_PDA;
2570         regs.orig_eax = -1;
2571         regs.eip = (unsigned long) kernel_thread_helper;
2572 @@ -361,7 +361,7 @@ void exit_thread(void)
2573                 struct task_struct *tsk = current;
2574                 struct thread_struct *t = &tsk->thread;
2575                 int cpu = get_cpu();
2576 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
2577 +               struct tss_struct *tss = init_tss + cpu;
2578  
2579                 kfree(t->io_bitmap_ptr);
2580                 t->io_bitmap_ptr = NULL;
2581 @@ -382,6 +382,7 @@ void flush_thread(void)
2582  {
2583         struct task_struct *tsk = current;
2584  
2585 +       __asm__("mov %0,%%fs\n" : : "r" (0) : "memory");
2586         memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
2587         memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));        
2588         clear_tsk_thread_flag(tsk, TIF_DEBUG);
2589 @@ -415,7 +416,7 @@ int copy_thread(int nr, unsigned long cl
2590         struct task_struct *tsk;
2591         int err;
2592  
2593 -       childregs = task_pt_regs(p);
2594 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
2595         *childregs = *regs;
2596         childregs->eax = 0;
2597         childregs->esp = esp;
2598 @@ -457,6 +458,11 @@ int copy_thread(int nr, unsigned long cl
2599                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2600                         goto out;
2601  
2602 +#ifdef CONFIG_PAX_SEGMEXEC
2603 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2604 +                       goto out;
2605 +#endif
2606 +
2607                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
2608                 desc->a = LDT_entry_a(&info);
2609                 desc->b = LDT_entry_b(&info);
2610 @@ -636,7 +642,7 @@ struct task_struct fastcall * __switch_t
2611         struct thread_struct *prev = &prev_p->thread,
2612                                  *next = &next_p->thread;
2613         int cpu = smp_processor_id();
2614 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
2615 +       struct tss_struct *tss = init_tss + cpu;
2616  
2617         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
2618  
2619 @@ -664,6 +670,11 @@ struct task_struct fastcall * __switch_t
2620          */
2621         savesegment(fs, prev->fs);
2622  
2623 +#ifdef CONFIG_PAX_MEMORY_UDEREF
2624 +       if (!segment_eq(prev_p->thread_info->addr_limit, next_p->thread_info->addr_limit))
2625 +               __set_fs(next_p->thread_info->addr_limit, cpu);
2626 +#endif
2627 +
2628         /*
2629          * Load the per-thread Thread-Local Storage descriptor.
2630          */
2631 @@ -814,6 +825,12 @@ asmlinkage int sys_set_thread_area(struc
2632  
2633         if (copy_from_user(&info, u_info, sizeof(info)))
2634                 return -EFAULT;
2635 +
2636 +#ifdef CONFIG_PAX_SEGMEXEC
2637 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2638 +               return -EINVAL;
2639 +#endif
2640 +
2641         idx = info.entry_number;
2642  
2643         /*
2644 @@ -902,9 +919,28 @@ asmlinkage int sys_get_thread_area(struc
2645         return 0;
2646  }
2647  
2648 -unsigned long arch_align_stack(unsigned long sp)
2649 +#ifdef CONFIG_PAX_RANDKSTACK
2650 +asmlinkage void pax_randomize_kstack(void)
2651  {
2652 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
2653 -               sp -= get_random_int() % 8192;
2654 -       return sp & ~0xf;
2655 +       struct tss_struct *tss;
2656 +       unsigned long time;
2657 +
2658 +       if (!randomize_va_space)
2659 +               return;
2660 +
2661 +       tss = init_tss + smp_processor_id();
2662 +       rdtscl(time);
2663 +
2664 +       /* P4 seems to return a 0 LSB, ignore it */
2665 +#ifdef CONFIG_MPENTIUM4
2666 +       time &= 0x1EUL;
2667 +       time <<= 2;
2668 +#else
2669 +       time &= 0xFUL;
2670 +       time <<= 3;
2671 +#endif
2672 +
2673 +       tss->esp0 ^= time;
2674 +       current->thread.esp0 = tss->esp0;
2675  }
2676 +#endif
2677 diff -urNp linux-2.6.20.3/arch/i386/kernel/ptrace.c linux-2.6.20.3/arch/i386/kernel/ptrace.c
2678 --- linux-2.6.20.3/arch/i386/kernel/ptrace.c    2007-03-13 14:27:08.000000000 -0400
2679 +++ linux-2.6.20.3/arch/i386/kernel/ptrace.c    2007-03-23 08:11:18.000000000 -0400
2680 @@ -17,6 +17,7 @@
2681  #include <linux/audit.h>
2682  #include <linux/seccomp.h>
2683  #include <linux/signal.h>
2684 +#include <linux/grsecurity.h>
2685  
2686  #include <asm/uaccess.h>
2687  #include <asm/pgtable.h>
2688 @@ -162,15 +163,15 @@ static unsigned long convert_eip_to_line
2689          * and APM bios ones we just ignore here.
2690          */
2691         if (seg & LDT_SEGMENT) {
2692 -               u32 *desc;
2693 +               struct desc_struct *desc;
2694                 unsigned long base;
2695  
2696                 down(&child->mm->context.sem);
2697 -               desc = child->mm->context.ldt + (seg & ~7);
2698 -               base = (desc[0] >> 16) | ((desc[1] & 0xff) << 16) | (desc[1] & 0xff000000);
2699 +               desc = &child->mm->context.ldt[seg >> 3];
2700 +               base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
2701  
2702                 /* 16-bit code segment? */
2703 -               if (!((desc[1] >> 22) & 1))
2704 +               if (!((desc->b >> 22) & 1))
2705                         addr &= 0xffff;
2706                 addr += base;
2707                 up(&child->mm->context.sem);
2708 @@ -335,6 +336,11 @@ ptrace_set_thread_area(struct task_struc
2709         if (copy_from_user(&info, user_desc, sizeof(info)))
2710                 return -EFAULT;
2711  
2712 +#ifdef CONFIG_PAX_SEGMEXEC
2713 +       if ((child->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
2714 +               return -EINVAL;
2715 +#endif
2716 +
2717         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
2718                 return -EINVAL;
2719  
2720 @@ -425,6 +431,17 @@ long arch_ptrace(struct task_struct *chi
2721                           if(addr == (long) &dummy->u_debugreg[5]) break;
2722                           if(addr < (long) &dummy->u_debugreg[4] &&
2723                              ((unsigned long) data) >= TASK_SIZE-3) break;
2724 +
2725 +#ifdef CONFIG_GRKERNSEC
2726 +                         if(addr >= (long) &dummy->u_debugreg[0] &&
2727 +                            addr <= (long) &dummy->u_debugreg[3]){
2728 +                               long reg   = (addr - (long) &dummy->u_debugreg[0]) >> 2;
2729 +                               long type  = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3;
2730 +                               long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3;
2731 +                               if((type & 1) && (data & align))
2732 +                                       break;
2733 +                         }
2734 +#endif
2735                           
2736                           /* Sanity-check data. Take one half-byte at once with
2737                            * check = (val >> (16 + 4*i)) & 0xf. It contains the
2738 @@ -641,7 +658,7 @@ void send_sigtrap(struct task_struct *ts
2739         info.si_code = TRAP_BRKPT;
2740  
2741         /* User-mode eip? */
2742 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
2743 +       info.si_addr = user_mode(regs) ? (void __user *) regs->eip : NULL;
2744  
2745         /* Send us the fakey SIGTRAP */
2746         force_sig_info(SIGTRAP, &info, tsk);
2747 diff -urNp linux-2.6.20.3/arch/i386/kernel/reboot.c linux-2.6.20.3/arch/i386/kernel/reboot.c
2748 --- linux-2.6.20.3/arch/i386/kernel/reboot.c    2007-03-13 14:27:08.000000000 -0400
2749 +++ linux-2.6.20.3/arch/i386/kernel/reboot.c    2007-03-23 08:10:06.000000000 -0400
2750 @@ -25,7 +25,7 @@
2751  void (*pm_power_off)(void);
2752  EXPORT_SYMBOL(pm_power_off);
2753  
2754 -static int reboot_mode;
2755 +static unsigned short reboot_mode;
2756  static int reboot_thru_bios;
2757  
2758  #ifdef CONFIG_SMP
2759 @@ -120,7 +120,7 @@ static struct dmi_system_id __initdata r
2760                         DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
2761                 },
2762         },
2763 -       { }
2764 +       { NULL, NULL, {{0, NULL}}, NULL}
2765  };
2766  
2767  static int __init reboot_init(void)
2768 @@ -138,18 +138,18 @@ core_initcall(reboot_init);
2769     doesn't work with at least one type of 486 motherboard.  It is easy
2770     to stop this code working; hence the copious comments. */
2771  
2772 -static unsigned long long
2773 +static const struct desc_struct
2774  real_mode_gdt_entries [3] =
2775  {
2776 -       0x0000000000000000ULL,  /* Null descriptor */
2777 -       0x00009a000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
2778 -       0x000092000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
2779 +       {0x00000000, 0x00000000},       /* Null descriptor */
2780 +       {0x0000ffff, 0x00009b00},       /* 16-bit real-mode 64k code at 0x00000000 */
2781 +       {0x0100ffff, 0x00009300}        /* 16-bit real-mode 64k data at 0x00000100 */
2782  };
2783  
2784 -static struct Xgt_desc_struct
2785 -real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
2786 -real_mode_idt = { 0x3ff, 0 },
2787 -no_idt = { 0, 0 };
2788 +static const struct Xgt_desc_struct
2789 +real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries, 0 },
2790 +real_mode_idt = { 0x3ff, NULL, 0 },
2791 +no_idt = { 0, NULL, 0 };
2792  
2793  
2794  /* This is 16-bit protected mode code to disable paging and the cache,
2795 @@ -171,7 +171,7 @@ no_idt = { 0, 0 };
2796     More could be done here to set up the registers as if a CPU reset had
2797     occurred; hopefully real BIOSs don't assume much. */
2798  
2799 -static unsigned char real_mode_switch [] =
2800 +static const unsigned char real_mode_switch [] =
2801  {
2802         0x66, 0x0f, 0x20, 0xc0,                 /*    movl  %cr0,%eax        */
2803         0x66, 0x83, 0xe0, 0x11,                 /*    andl  $0x00000011,%eax */
2804 @@ -185,7 +185,7 @@ static unsigned char real_mode_switch []
2805         0x24, 0x10,                             /* f: andb  $0x10,al         */
2806         0x66, 0x0f, 0x22, 0xc0                  /*    movl  %eax,%cr0        */
2807  };
2808 -static unsigned char jump_to_bios [] =
2809 +static const unsigned char jump_to_bios [] =
2810  {
2811         0xea, 0x00, 0x00, 0xff, 0xff            /*    ljmp  $0xffff,$0x0000  */
2812  };
2813 @@ -195,10 +195,14 @@ static unsigned char jump_to_bios [] =
2814   * specified by the code and length parameters.
2815   * We assume that length will aways be less that 100!
2816   */
2817 -void machine_real_restart(unsigned char *code, int length)
2818 +void machine_real_restart(const unsigned char *code, unsigned int length)
2819  {
2820         unsigned long flags;
2821  
2822 +#ifdef CONFIG_PAX_KERNEXEC
2823 +       unsigned long cr0;
2824 +#endif
2825 +
2826         local_irq_disable();
2827  
2828         /* Write zero to CMOS register number 0x0f, which the BIOS POST
2829 @@ -219,8 +223,16 @@ void machine_real_restart(unsigned char 
2830            from the kernel segment.  This assumes the kernel segment starts at
2831            virtual address PAGE_OFFSET. */
2832  
2833 -       memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2834 -               sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
2835 +#ifdef CONFIG_PAX_KERNEXEC
2836 +       pax_open_kernel(cr0);
2837 +#endif
2838 +
2839 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
2840 +                       min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS));
2841 +
2842 +#ifdef CONFIG_PAX_KERNEXEC
2843 +       pax_close_kernel(cr0);
2844 +#endif
2845  
2846         /*
2847          * Use `swapper_pg_dir' as our page directory.
2848 @@ -233,7 +245,7 @@ void machine_real_restart(unsigned char 
2849            REBOOT.COM programs, and the previous reset routine did this
2850            too. */
2851  
2852 -       *((unsigned short *)0x472) = reboot_mode;
2853 +       __put_user(reboot_mode, (unsigned short __user *)0x472);
2854  
2855         /* For the switch to real mode, copy some code to low memory.  It has
2856            to be in the first 64k because it is running in 16-bit mode, and it
2857 @@ -241,9 +253,9 @@ void machine_real_restart(unsigned char 
2858            off paging.  Copy it near the end of the first page, out of the way
2859            of BIOS variables. */
2860  
2861 -       memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100),
2862 +       flags = __copy_to_user_inatomic((void __user *) (0x1000 - sizeof (real_mode_switch) - 100),
2863                 real_mode_switch, sizeof (real_mode_switch));
2864 -       memcpy ((void *) (0x1000 - 100), code, length);
2865 +       flags = __copy_to_user_inatomic((void __user *) (0x1000 - 100), code, length);
2866  
2867         /* Set up the IDT for real mode. */
2868  
2869 @@ -325,7 +337,7 @@ void machine_emergency_restart(void)
2870                         __asm__ __volatile__("int3");
2871                 }
2872                 /* rebooting needs to touch the page at absolute addr 0 */
2873 -               *((unsigned short *)__va(0x472)) = reboot_mode;
2874 +               __put_user(reboot_mode, (unsigned short __user *)0x472);
2875                 for (;;) {
2876                         mach_reboot_fixups(); /* for board specific fixups */
2877                         mach_reboot();
2878 diff -urNp linux-2.6.20.3/arch/i386/kernel/setup.c linux-2.6.20.3/arch/i386/kernel/setup.c
2879 --- linux-2.6.20.3/arch/i386/kernel/setup.c     2007-03-13 14:27:08.000000000 -0400
2880 +++ linux-2.6.20.3/arch/i386/kernel/setup.c     2007-03-23 08:10:06.000000000 -0400
2881 @@ -82,7 +82,11 @@ struct cpuinfo_x86 new_cpu_data __cpuini
2882  struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
2883  EXPORT_SYMBOL(boot_cpu_data);
2884  
2885 +#ifdef CONFIG_X86_PAE
2886 +unsigned long mmu_cr4_features = X86_CR4_PAE;
2887 +#else
2888  unsigned long mmu_cr4_features;
2889 +#endif
2890  
2891  /* for MCA, but anyone else can use it if they want */
2892  unsigned int machine_id;
2893 @@ -404,8 +408,8 @@ void __init setup_bootmem_allocator(void
2894          * the (very unlikely) case of us accidentally initializing the
2895          * bootmem allocator with an invalid RAM area.
2896          */
2897 -       reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) +
2898 -                        bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text));
2899 +       reserve_bootmem(LOAD_PHYSICAL_ADDR, (PFN_PHYS(min_low_pfn) +
2900 +                        bootmap_size + PAGE_SIZE-1) - LOAD_PHYSICAL_ADDR);
2901  
2902         /*
2903          * reserve physical page 0 - it's a special BIOS page on many boxes,
2904 @@ -559,14 +563,14 @@ void __init setup_arch(char **cmdline_p)
2905  
2906         if (!MOUNT_ROOT_RDONLY)
2907                 root_mountflags &= ~MS_RDONLY;
2908 -       init_mm.start_code = (unsigned long) _text;
2909 -       init_mm.end_code = (unsigned long) _etext;
2910 +       init_mm.start_code = (unsigned long) _text + __KERNEL_TEXT_OFFSET;
2911 +       init_mm.end_code = (unsigned long) _etext + __KERNEL_TEXT_OFFSET;
2912         init_mm.end_data = (unsigned long) _edata;
2913         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
2914  
2915 -       code_resource.start = virt_to_phys(_text);
2916 -       code_resource.end = virt_to_phys(_etext)-1;
2917 -       data_resource.start = virt_to_phys(_etext);
2918 +       code_resource.start = virt_to_phys(_text + __KERNEL_TEXT_OFFSET);
2919 +       code_resource.end = virt_to_phys(_etext + __KERNEL_TEXT_OFFSET)-1;
2920 +       data_resource.start = virt_to_phys(_data);
2921         data_resource.end = virt_to_phys(_edata)-1;
2922  
2923         parse_early_param();
2924 diff -urNp linux-2.6.20.3/arch/i386/kernel/signal.c linux-2.6.20.3/arch/i386/kernel/signal.c
2925 --- linux-2.6.20.3/arch/i386/kernel/signal.c    2007-03-13 14:27:08.000000000 -0400
2926 +++ linux-2.6.20.3/arch/i386/kernel/signal.c    2007-03-23 08:10:06.000000000 -0400
2927 @@ -351,9 +351,9 @@ static int setup_frame(int sig, struct k
2928         }
2929  
2930         if (current->binfmt->hasvdso)
2931 -               restorer = (void *)VDSO_SYM(&__kernel_sigreturn);
2932 +               restorer = (void __user *)VDSO_SYM(&__kernel_sigreturn);
2933         else
2934 -               restorer = (void *)&frame->retcode;
2935 +               restorer = (void __user *)&frame->retcode;
2936         if (ka->sa.sa_flags & SA_RESTORER)
2937                 restorer = ka->sa.sa_restorer;
2938  
2939 @@ -449,7 +449,8 @@ static int setup_rt_frame(int sig, struc
2940                 goto give_sigsegv;
2941  
2942         /* Set up to return from userspace.  */
2943 -       restorer = (void *)VDSO_SYM(&__kernel_rt_sigreturn);
2944 +
2945 +       restorer = (void __user *)VDSO_SYM(&__kernel_rt_sigreturn);
2946         if (ka->sa.sa_flags & SA_RESTORER)
2947                 restorer = ka->sa.sa_restorer;
2948         err |= __put_user(restorer, &frame->pretcode);
2949 @@ -582,7 +583,7 @@ static void fastcall do_signal(struct pt
2950          * before reaching here, so testing against kernel
2951          * CS suffices.
2952          */
2953 -       if (!user_mode(regs))
2954 +       if (!user_mode_novm(regs))
2955                 return;
2956  
2957         if (test_thread_flag(TIF_RESTORE_SIGMASK))
2958 diff -urNp linux-2.6.20.3/arch/i386/kernel/smpboot.c linux-2.6.20.3/arch/i386/kernel/smpboot.c
2959 --- linux-2.6.20.3/arch/i386/kernel/smpboot.c   2007-03-13 14:27:08.000000000 -0400
2960 +++ linux-2.6.20.3/arch/i386/kernel/smpboot.c   2007-03-23 08:10:06.000000000 -0400
2961 @@ -57,7 +57,6 @@
2962  #include <asm/desc.h>
2963  #include <asm/arch_hooks.h>
2964  #include <asm/nmi.h>
2965 -#include <asm/pda.h>
2966  #include <asm/genapic.h>
2967  
2968  #include <mach_apic.h>
2969 @@ -618,8 +617,6 @@ extern struct {
2970         void * esp;
2971         unsigned short ss;
2972  } stack_start;
2973 -extern struct i386_pda *start_pda;
2974 -extern struct Xgt_desc_struct cpu_gdt_descr;
2975  
2976  #ifdef CONFIG_NUMA
2977  
2978 @@ -961,10 +958,7 @@ static int __cpuinit do_boot_cpu(int api
2979         /* Pre-allocate and initialize the CPU's GDT and PDA so it
2980            doesn't have to do any memory allocation during the
2981            delicate CPU-bringup phase. */
2982 -       if (!init_gdt(cpu, idle)) {
2983 -               printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu);
2984 -               return -1;      /* ? */
2985 -       }
2986 +       init_gdt(cpu, idle);
2987  
2988         idle->thread.eip = (unsigned long) start_secondary;
2989         /* start_eip had better be page-aligned! */
2990 @@ -1090,7 +1084,6 @@ static int __cpuinit __smp_prepare_cpu(i
2991         DECLARE_COMPLETION_ONSTACK(done);
2992         struct warm_boot_cpu_info info;
2993         int     apicid, ret;
2994 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
2995  
2996         apicid = x86_cpu_to_apicid[cpu];
2997         if (apicid == BAD_APICID) {
2998 @@ -1098,18 +1091,6 @@ static int __cpuinit __smp_prepare_cpu(i
2999                 goto exit;
3000         }
3001  
3002 -       /*
3003 -        * the CPU isn't initialized at boot time, allocate gdt table here.
3004 -        * cpu_init will initialize it
3005 -        */
3006 -       if (!cpu_gdt_descr->address) {
3007 -               cpu_gdt_descr->address = get_zeroed_page(GFP_KERNEL);
3008 -               if (!cpu_gdt_descr->address)
3009 -                       printk(KERN_CRIT "CPU%d failed to allocate GDT\n", cpu);
3010 -                       ret = -ENOMEM;
3011 -                       goto exit;
3012 -       }
3013 -
3014         info.complete = &done;
3015         info.apicid = apicid;
3016         info.cpu = cpu;
3017 diff -urNp linux-2.6.20.3/arch/i386/kernel/smp.c linux-2.6.20.3/arch/i386/kernel/smp.c
3018 --- linux-2.6.20.3/arch/i386/kernel/smp.c       2007-03-13 14:27:08.000000000 -0400
3019 +++ linux-2.6.20.3/arch/i386/kernel/smp.c       2007-03-23 08:10:06.000000000 -0400
3020 @@ -104,7 +104,7 @@
3021   *     about nothing of note with C stepping upwards.
3022   */
3023  
3024 -DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, };
3025 +DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0, {0} };
3026  
3027  /*
3028   * the following functions deal with sending IPIs between CPUs.
3029 diff -urNp linux-2.6.20.3/arch/i386/kernel/syscall_table.S linux-2.6.20.3/arch/i386/kernel/syscall_table.S
3030 --- linux-2.6.20.3/arch/i386/kernel/syscall_table.S     2007-03-13 14:27:08.000000000 -0400
3031 +++ linux-2.6.20.3/arch/i386/kernel/syscall_table.S     2007-03-23 08:10:06.000000000 -0400
3032 @@ -1,3 +1,4 @@
3033 +.section .rodata,"a",@progbits
3034  ENTRY(sys_call_table)
3035         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
3036         .long sys_exit
3037 diff -urNp linux-2.6.20.3/arch/i386/kernel/sysenter.c linux-2.6.20.3/arch/i386/kernel/sysenter.c
3038 --- linux-2.6.20.3/arch/i386/kernel/sysenter.c  2007-03-13 14:27:08.000000000 -0400
3039 +++ linux-2.6.20.3/arch/i386/kernel/sysenter.c  2007-03-23 08:10:06.000000000 -0400
3040 @@ -49,7 +49,7 @@ extern asmlinkage void sysenter_entry(vo
3041  void enable_sep_cpu(void)
3042  {
3043         int cpu = get_cpu();
3044 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
3045 +       struct tss_struct *tss = init_tss + cpu;
3046  
3047         if (!boot_cpu_has(X86_FEATURE_SEP)) {
3048                 put_cpu();
3049 @@ -125,16 +125,36 @@ int arch_setup_additional_pages(struct l
3050         unsigned long addr;
3051         int ret;
3052  
3053 +#ifdef CONFIG_PAX_SEGMEXEC
3054 +       struct vm_area_struct *vma_m = NULL;
3055 +#endif
3056 +
3057 +       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3058 +       if (!vma)
3059 +               return -ENOMEM;
3060 +
3061 +#ifdef CONFIG_PAX_SEGMEXEC
3062 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
3063 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3064 +               if (!vma_m) {
3065 +                       kmem_cache_free(vm_area_cachep, vma);
3066 +                       return -ENOMEM;
3067 +               }
3068 +       }
3069 +#endif
3070 +
3071         down_write(&mm->mmap_sem);
3072 -       addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
3073 +       addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
3074         if (IS_ERR_VALUE(addr)) {
3075                 ret = addr;
3076 -               goto up_fail;
3077 -       }
3078  
3079 -       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
3080 -       if (!vma) {
3081 -               ret = -ENOMEM;
3082 +               kmem_cache_free(vm_area_cachep, vma);
3083 +
3084 +#ifdef CONFIG_PAX_SEGMEXEC
3085 +               if (vma_m)
3086 +                       kmem_cache_free(vm_area_cachep, vma_m);
3087 +#endif
3088 +
3089                 goto up_fail;
3090         }
3091  
3092 @@ -142,6 +162,12 @@ int arch_setup_additional_pages(struct l
3093         vma->vm_end = addr + PAGE_SIZE;
3094         /* MAYWRITE to allow gdb to COW and set breakpoints */
3095         vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
3096 +
3097 +#ifdef CONFIG_PAX_MPROTECT
3098 +       if (mm->pax_flags & MF_PAX_MPROTECT)
3099 +               vma->vm_flags &= ~VM_MAYWRITE;
3100 +#endif
3101 +
3102         /*
3103          * Make sure the vDSO gets into every core dump.
3104          * Dumping its contents makes post-mortem fully interpretable later
3105 @@ -151,17 +177,42 @@ int arch_setup_additional_pages(struct l
3106          */
3107         vma->vm_flags |= VM_ALWAYSDUMP;
3108         vma->vm_flags |= mm->def_flags;
3109 -       vma->vm_page_prot = protection_map[vma->vm_flags & 7];
3110 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
3111         vma->vm_ops = &syscall_vm_ops;
3112         vma->vm_mm = mm;
3113  
3114         ret = insert_vm_struct(mm, vma);
3115         if (unlikely(ret)) {
3116                 kmem_cache_free(vm_area_cachep, vma);
3117 +
3118 +#ifdef CONFIG_PAX_SEGMEXEC
3119 +               if (vma_m)
3120 +                       kmem_cache_free(vm_area_cachep, vma_m);
3121 +#endif
3122 +
3123                 goto up_fail;
3124         }
3125  
3126 -       current->mm->context.vdso = (void *)addr;
3127 +#ifdef CONFIG_PAX_SEGMEXEC
3128 +       if (vma_m) {
3129 +               *vma_m = *vma;
3130 +               vma_m->vm_start += SEGMEXEC_TASK_SIZE;
3131 +               vma_m->vm_end += SEGMEXEC_TASK_SIZE;
3132 +               ret = insert_vm_struct(mm, vma_m);
3133 +               if (unlikely(ret)) {
3134 +                       kmem_cache_free(vm_area_cachep, vma_m);
3135 +                       goto up_fail;
3136 +               }
3137 +               vma_m->vm_flags |= VM_MIRROR;
3138 +               vma->vm_flags |= VM_MIRROR;
3139 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
3140 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
3141 +               vma_m->vm_pgoff = vma->vm_pgoff;
3142 +               mm->total_vm++;
3143 +       }
3144 +#endif
3145 +
3146 +       current->mm->context.vdso = addr;
3147         current_thread_info()->sysenter_return =
3148                                     (void *)VDSO_SYM(&SYSENTER_RETURN);
3149         vx_vmpages_inc(mm);
3150 @@ -171,8 +222,17 @@ up_fail:
3151  
3152  const char *arch_vma_name(struct vm_area_struct *vma)
3153  {
3154 -       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
3155 +       if (vma->vm_start == vma->vm_mm->context.vdso)
3156                 return "[vdso]";
3157 +
3158 +#ifdef CONFIG_PAX_SEGMEXEC
3159 +       if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_MIRROR))
3160 +               return NULL;
3161 +
3162 +       if (vma->vm_start + vma->vm_mirror == vma->vm_mm->context.vdso)
3163 +               return "[vdso]";
3164 +#endif
3165 +
3166         return NULL;
3167  }
3168  
3169 diff -urNp linux-2.6.20.3/arch/i386/kernel/sys_i386.c linux-2.6.20.3/arch/i386/kernel/sys_i386.c
3170 --- linux-2.6.20.3/arch/i386/kernel/sys_i386.c  2007-03-13 14:27:08.000000000 -0400
3171 +++ linux-2.6.20.3/arch/i386/kernel/sys_i386.c  2007-03-23 08:10:06.000000000 -0400
3172 @@ -100,6 +100,191 @@ out:
3173         return err;
3174  }
3175  
3176 +unsigned long
3177 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
3178 +               unsigned long len, unsigned long pgoff, unsigned long flags)
3179 +{
3180 +       struct mm_struct *mm = current->mm;
3181 +       struct vm_area_struct *vma;
3182 +       unsigned long start_addr, task_size = TASK_SIZE;
3183 +
3184 +#ifdef CONFIG_PAX_SEGMEXEC
3185 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3186 +               task_size = SEGMEXEC_TASK_SIZE;
3187 +#endif
3188 +
3189 +       if (len > task_size)
3190 +               return -ENOMEM;
3191 +
3192 +#ifdef CONFIG_PAX_RANDMMAP
3193 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3194 +#endif
3195 +
3196 +       if (addr) {
3197 +               addr = PAGE_ALIGN(addr);
3198 +               vma = find_vma(mm, addr);
3199 +               if (task_size - len >= addr &&
3200 +                   (!vma || addr + len <= vma->vm_start))
3201 +                       return addr;
3202 +       }
3203 +       if (len > mm->cached_hole_size) {
3204 +               start_addr = addr = mm->free_area_cache;
3205 +       } else {
3206 +               start_addr = addr = mm->mmap_base;
3207 +               mm->cached_hole_size = 0;
3208 +       }
3209 +
3210 +#ifdef CONFIG_PAX_PAGEEXEC
3211 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
3212 +               start_addr = 0x00110000UL;
3213 +
3214 +#ifdef CONFIG_PAX_RANDMMAP
3215 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
3216 +                       start_addr += mm->delta_mmap & 0x03FFF000UL;
3217 +#endif
3218 +
3219 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
3220 +                       start_addr = addr = mm->mmap_base;
3221 +               else
3222 +                       addr = start_addr;
3223 +       }
3224 +#endif
3225 +
3226 +full_search:
3227 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
3228 +               /* At this point:  (!vma || addr < vma->vm_end). */
3229 +               if (task_size - len < addr) {
3230 +                       /*
3231 +                        * Start a new search - just in case we missed
3232 +                        * some holes.
3233 +                        */
3234 +                       if (start_addr != mm->mmap_base) {
3235 +                               start_addr = addr = mm->mmap_base;
3236 +                               mm->cached_hole_size = 0;
3237 +                               goto full_search;
3238 +                       }
3239 +                       return -ENOMEM;
3240 +               }
3241 +               if (!vma || addr + len <= vma->vm_start) {
3242 +                       /*
3243 +                        * Remember the place where we stopped the search:
3244 +                        */
3245 +                       mm->free_area_cache = addr + len;
3246 +                       return addr;
3247 +               }
3248 +               if (addr + mm->cached_hole_size < vma->vm_start)
3249 +                       mm->cached_hole_size = vma->vm_start - addr;
3250 +               addr = vma->vm_end;
3251 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
3252 +                       start_addr = addr = mm->mmap_base;
3253 +                       goto full_search;
3254 +               }
3255 +       }
3256 +}
3257 +
3258 +unsigned long
3259 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
3260 +                         const unsigned long len, const unsigned long pgoff,
3261 +                         const unsigned long flags)
3262 +{
3263 +       struct vm_area_struct *vma;
3264 +       struct mm_struct *mm = current->mm;
3265 +       unsigned long base = mm->mmap_base, addr = addr0, task_size = TASK_SIZE;
3266 +
3267 +#ifdef CONFIG_PAX_SEGMEXEC
3268 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
3269 +               task_size = SEGMEXEC_TASK_SIZE;
3270 +#endif
3271 +
3272 +       /* requested length too big for entire address space */
3273 +       if (len > task_size)
3274 +               return -ENOMEM;
3275 +
3276 +#ifdef CONFIG_PAX_PAGEEXEC
3277 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
3278 +               goto bottomup;
3279 +#endif
3280 +
3281 +#ifdef CONFIG_PAX_RANDMMAP
3282 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
3283 +#endif
3284 +
3285 +       /* requesting a specific address */
3286 +       if (addr) {
3287 +               addr = PAGE_ALIGN(addr);
3288 +               vma = find_vma(mm, addr);
3289 +               if (task_size - len >= addr &&
3290 +                               (!vma || addr + len <= vma->vm_start))
3291 +                       return addr;
3292 +       }
3293 +
3294 +       /* check if free_area_cache is useful for us */
3295 +       if (len <= mm->cached_hole_size) {
3296 +               mm->cached_hole_size = 0;
3297 +               mm->free_area_cache = mm->mmap_base;
3298 +       }
3299 +
3300 +       /* either no address requested or can't fit in requested address hole */
3301 +       addr = mm->free_area_cache;
3302 +
3303 +       /* make sure it can fit in the remaining address space */
3304 +       if (addr > len) {
3305 +               vma = find_vma(mm, addr-len);
3306 +               if (!vma || addr <= vma->vm_start)
3307 +                       /* remember the address as a hint for next time */
3308 +                       return (mm->free_area_cache = addr-len);
3309 +       }
3310 +
3311 +       if (mm->mmap_base < len)
3312 +               goto bottomup;
3313 +
3314 +       addr = mm->mmap_base-len;
3315 +
3316 +       do {
3317 +               /*
3318 +                * Lookup failure means no vma is above this address,
3319 +                * else if new region fits below vma->vm_start,
3320 +                * return with success:
3321 +                */
3322 +               vma = find_vma(mm, addr);
3323 +               if (!vma || addr+len <= vma->vm_start)
3324 +                       /* remember the address as a hint for next time */
3325 +                       return (mm->free_area_cache = addr);
3326 +
3327 +               /* remember the largest hole we saw so far */
3328 +               if (addr + mm->cached_hole_size < vma->vm_start)
3329 +                       mm->cached_hole_size = vma->vm_start - addr;
3330 +
3331 +               /* try just below the current vma->vm_start */
3332 +               addr = vma->vm_start-len;
3333 +       } while (len < vma->vm_start);
3334 +
3335 +bottomup:
3336 +       /*
3337 +        * A failed mmap() very likely causes application failure,
3338 +        * so fall back to the bottom-up function here. This scenario
3339 +        * can happen with large stack limits and large mmap()
3340 +        * allocations.
3341 +        */
3342 +       mm->mmap_base = TASK_UNMAPPED_BASE;
3343 +
3344 +#ifdef CONFIG_PAX_RANDMMAP
3345 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
3346 +               mm->mmap_base += mm->delta_mmap;
3347 +#endif
3348 +
3349 +       mm->free_area_cache = mm->mmap_base;
3350 +       mm->cached_hole_size = ~0UL;
3351 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
3352 +       /*
3353 +        * Restore the topdown base:
3354 +        */
3355 +       mm->mmap_base = base;
3356 +       mm->free_area_cache = base;
3357 +       mm->cached_hole_size = ~0UL;
3358 +
3359 +       return addr;
3360 +}
3361  
3362  struct sel_arg_struct {
3363         unsigned long n;
3364 diff -urNp linux-2.6.20.3/arch/i386/kernel/time.c linux-2.6.20.3/arch/i386/kernel/time.c
3365 --- linux-2.6.20.3/arch/i386/kernel/time.c      2007-03-13 14:27:08.000000000 -0400
3366 +++ linux-2.6.20.3/arch/i386/kernel/time.c      2007-03-23 08:10:06.000000000 -0400
3367 @@ -131,7 +131,7 @@ unsigned long profile_pc(struct pt_regs 
3368         unsigned long pc = instruction_pointer(regs);
3369  
3370  #ifdef CONFIG_SMP
3371 -       if (!user_mode_vm(regs) && in_lock_functions(pc)) {
3372 +       if (!user_mode(regs) && in_lock_functions(pc)) {
3373  #ifdef CONFIG_FRAME_POINTER
3374                 return *(unsigned long *)(regs->ebp + 4);
3375  #else
3376 @@ -340,7 +340,7 @@ static struct sys_device device_timer = 
3377         .cls    = &timer_sysclass,
3378  };
3379  
3380 -static int time_init_device(void)
3381 +static int __init time_init_device(void)
3382  {
3383         int error = sysdev_class_register(&timer_sysclass);
3384         if (!error)
3385 diff -urNp linux-2.6.20.3/arch/i386/kernel/traps.c linux-2.6.20.3/arch/i386/kernel/traps.c
3386 --- linux-2.6.20.3/arch/i386/kernel/traps.c     2007-03-13 14:27:08.000000000 -0400
3387 +++ linux-2.6.20.3/arch/i386/kernel/traps.c     2007-03-23 08:10:06.000000000 -0400
3388 @@ -31,6 +31,7 @@
3389  #include <linux/uaccess.h>
3390  #include <linux/nmi.h>
3391  #include <linux/bug.h>
3392 +#include <linux/binfmts.h>
3393  
3394  #ifdef CONFIG_EISA
3395  #include <linux/ioport.h>
3396 @@ -68,12 +69,7 @@ asmlinkage int system_call(void);
3397  /* Do we ignore FPU interrupts ? */
3398  char ignore_fpu_irq = 0;
3399  
3400 -/*
3401 - * The IDT has to be page-aligned to simplify the Pentium
3402 - * F0 0F bug workaround.. We have a special link segment
3403 - * for this.
3404 - */
3405 -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
3406 +extern struct desc_struct idt_table[256];
3407  
3408  asmlinkage void divide_error(void);
3409  asmlinkage void debug(void);
3410 @@ -140,7 +136,7 @@ static inline unsigned long print_contex
3411  #else
3412         while (valid_stack_ptr(tinfo, stack)) {
3413                 addr = *stack++;
3414 -               if (__kernel_text_address(addr))
3415 +               if (__kernel_text_address(addr + __KERNEL_TEXT_OFFSET))
3416                         ops->address(data, addr);
3417         }
3418  #endif
3419 @@ -297,7 +293,7 @@ void show_registers(struct pt_regs *regs
3420  
3421         esp = (unsigned long) (&regs->esp);
3422         savesegment(ss, ss);
3423 -       if (user_mode_vm(regs)) {
3424 +       if (user_mode(regs)) {
3425                 in_kernel = 0;
3426                 esp = regs->esp;
3427                 ss = regs->xss & 0xffff;
3428 @@ -313,8 +309,8 @@ void show_registers(struct pt_regs *regs
3429                 regs->eax, regs->ebx, regs->ecx, regs->edx);
3430         printk(KERN_EMERG "esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",
3431                 regs->esi, regs->edi, regs->ebp, esp);
3432 -       printk(KERN_EMERG "ds: %04x   es: %04x   ss: %04x\n",
3433 -               regs->xds & 0xffff, regs->xes & 0xffff, ss);
3434 +       printk(KERN_EMERG "ds: %04x   es: %04x   gs: %04x   ss: %04x\n",
3435 +               regs->xds & 0xffff, regs->xes & 0xffff, regs->xgs & 0xffff, ss);
3436         printk(KERN_EMERG "Process %.*s (pid: %d[#%u], ti=%p task=%p task.ti=%p)",
3437                 TASK_COMM_LEN, current->comm, current->pid, current->xid,
3438                 current_thread_info(), current, current->thread_info);
3439 @@ -332,11 +328,11 @@ void show_registers(struct pt_regs *regs
3440  
3441                 printk(KERN_EMERG "Code: ");
3442  
3443 -               eip = (u8 *)regs->eip - 43;
3444 +               eip = (u8 *)regs->eip - 43 + __KERNEL_TEXT_OFFSET;
3445                 if (eip < (u8 *)PAGE_OFFSET ||
3446                         probe_kernel_address(eip, c)) {
3447                         /* try starting at EIP */
3448 -                       eip = (u8 *)regs->eip;
3449 +                       eip = (u8 *)regs->eip + __KERNEL_TEXT_OFFSET;
3450                         code_bytes = 32;
3451                 }
3452                 for (i = 0; i < code_bytes; i++, eip++) {
3453 @@ -345,7 +341,7 @@ void show_registers(struct pt_regs *regs
3454                                 printk(" Bad EIP value.");
3455                                 break;
3456                         }
3457 -                       if (eip == (u8 *)regs->eip)
3458 +                       if (eip == (u8 *)regs->eip + __KERNEL_TEXT_OFFSET)
3459                                 printk("<%02x> ", c);
3460                         else
3461                                 printk("%02x ", c);
3462 @@ -358,6 +354,7 @@ int is_valid_bugaddr(unsigned long eip)
3463  {
3464         unsigned short ud2;
3465  
3466 +       eip += __KERNEL_TEXT_OFFSET;
3467         if (eip < PAGE_OFFSET)
3468                 return 0;
3469         if (probe_kernel_address((unsigned short *)eip, ud2))
3470 @@ -464,7 +461,7 @@ void die(const char * str, struct pt_reg
3471  
3472  static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err)
3473  {
3474 -       if (!user_mode_vm(regs))
3475 +       if (!user_mode(regs))
3476                 die(str, regs, err);
3477  }
3478  
3479 @@ -482,7 +479,7 @@ static void __kprobes do_trap(int trapnr
3480                 goto trap_signal;
3481         }
3482  
3483 -       if (!user_mode(regs))
3484 +       if (!user_mode_novm(regs))
3485                 goto kernel_trap;
3486  
3487         trap_signal: {
3488 @@ -570,7 +567,7 @@ fastcall void __kprobes do_general_prote
3489                                               long error_code)
3490  {
3491         int cpu = get_cpu();
3492 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
3493 +       struct tss_struct *tss = &init_tss[cpu];
3494         struct thread_struct *thread = &current->thread;
3495  
3496         /*
3497 @@ -606,9 +603,25 @@ fastcall void __kprobes do_general_prote
3498         if (regs->eflags & VM_MASK)
3499                 goto gp_in_vm86;
3500  
3501 -       if (!user_mode(regs))
3502 +       if (!user_mode_novm(regs))
3503                 goto gp_in_kernel;
3504  
3505 +#ifdef CONFIG_PAX_PAGEEXEC
3506 +       if (current->mm && (current->mm->pax_flags & MF_PAX_PAGEEXEC)) {
3507 +               struct mm_struct *mm = current->mm;
3508 +               unsigned long limit;
3509 +
3510 +               down_write(&mm->mmap_sem);
3511 +               limit = mm->context.user_cs_limit;
3512 +               if (limit < TASK_SIZE) {
3513 +                       track_exec_limit(mm, limit, TASK_SIZE, PROT_EXEC);
3514 +                       up_write(&mm->mmap_sem);
3515 +                       return;
3516 +               }
3517 +               up_write(&mm->mmap_sem);
3518 +       }
3519 +#endif
3520 +
3521         current->thread.error_code = error_code;
3522         current->thread.trap_no = 13;
3523         force_sig(SIGSEGV, current);
3524 @@ -624,6 +637,13 @@ gp_in_kernel:
3525                 if (notify_die(DIE_GPF, "general protection fault", regs,
3526                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
3527                         return;
3528 +
3529 +#ifdef CONFIG_PAX_KERNEXEC
3530 +               if ((regs->xcs & 0xFFFF) == __KERNEL_CS)
3531 +                       die("PAX: suspicious general protection fault", regs, error_code);
3532 +               else
3533 +#endif
3534 +
3535                 die("general protection fault", regs, error_code);
3536         }
3537  }
3538 @@ -705,7 +725,7 @@ void __kprobes die_nmi(struct pt_regs *r
3539         /* If we are in kernel we are probably nested up pretty bad
3540          * and might aswell get out now while we still can.
3541         */
3542 -       if (!user_mode_vm(regs)) {
3543 +       if (!user_mode(regs)) {
3544                 current->thread.trap_no = 2;
3545                 crash_kexec(regs);
3546         }
3547 @@ -837,7 +857,7 @@ fastcall void __kprobes do_debug(struct 
3548                  * check for kernel mode by just checking the CPL
3549                  * of CS.
3550                  */
3551 -               if (!user_mode(regs))
3552 +               if (!user_mode_novm(regs))
3553                         goto clear_TF_reenable;
3554         }
3555  
3556 @@ -1016,8 +1036,7 @@ fastcall unsigned long patch_espfix_desc
3557                                           unsigned long kesp)
3558  {
3559         int cpu = smp_processor_id();
3560 -       struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
3561 -       struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr->address;
3562 +       struct desc_struct *gdt = (struct desc_struct *)cpu_gdt_descr[cpu].address;
3563         unsigned long base = (kesp - uesp) & -THREAD_SIZE;
3564         unsigned long new_kesp = kesp - base;
3565         unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
3566 @@ -1076,7 +1095,7 @@ void __init trap_init_f00f_bug(void)
3567          * Update the IDT descriptor and reload the IDT so that
3568          * it uses the read-only mapped virtual address.
3569          */
3570 -       idt_descr.address = fix_to_virt(FIX_F00F_IDT);
3571 +       idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
3572         load_idt(&idt_descr);
3573  }
3574  #endif
3575 diff -urNp linux-2.6.20.3/arch/i386/kernel/tsc.c linux-2.6.20.3/arch/i386/kernel/tsc.c
3576 --- linux-2.6.20.3/arch/i386/kernel/tsc.c       2007-03-13 14:27:08.000000000 -0400
3577 +++ linux-2.6.20.3/arch/i386/kernel/tsc.c       2007-03-23 08:10:06.000000000 -0400
3578 @@ -383,7 +383,7 @@ static struct dmi_system_id __initdata b
3579                      DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
3580                      },
3581          },
3582 -        {}
3583 +       { NULL, NULL, {{0, NULL}}, NULL}
3584  };
3585  
3586  #define TSC_FREQ_CHECK_INTERVAL (10*MSEC_PER_SEC) /* 10sec in MS */
3587 diff -urNp linux-2.6.20.3/arch/i386/kernel/vm86.c linux-2.6.20.3/arch/i386/kernel/vm86.c
3588 --- linux-2.6.20.3/arch/i386/kernel/vm86.c      2007-03-13 14:27:08.000000000 -0400
3589 +++ linux-2.6.20.3/arch/i386/kernel/vm86.c      2007-03-23 08:10:06.000000000 -0400
3590 @@ -148,7 +148,7 @@ struct pt_regs * fastcall save_v86_state
3591                 do_exit(SIGSEGV);
3592         }
3593  
3594 -       tss = &per_cpu(init_tss, get_cpu());
3595 +       tss = init_tss + get_cpu();
3596         current->thread.esp0 = current->thread.saved_esp0;
3597         current->thread.sysenter_cs = __KERNEL_CS;
3598         load_esp0(tss, &current->thread);
3599 @@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
3600         savesegment(fs, tsk->thread.saved_fs);
3601         tsk->thread.saved_gs = info->regs32->xgs;
3602  
3603 -       tss = &per_cpu(init_tss, get_cpu());
3604 +       tss = init_tss + get_cpu();
3605         tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0;
3606         if (cpu_has_sep)
3607                 tsk->thread.sysenter_cs = 0;
3608 diff -urNp linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S
3609 --- linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S       2007-03-13 14:27:08.000000000 -0400
3610 +++ linux-2.6.20.3/arch/i386/kernel/vmlinux.lds.S       2007-03-23 08:10:06.000000000 -0400
3611 @@ -21,6 +21,13 @@
3612  #include <asm/page.h>
3613  #include <asm/cache.h>
3614  #include <asm/boot.h>
3615 +#include <asm/segment.h>
3616 +
3617 +#ifdef CONFIG_X86_PAE
3618 +#define PMD_SHIFT 21
3619 +#else
3620 +#define PMD_SHIFT 22
3621 +#endif
3622  
3623  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
3624  OUTPUT_ARCH(i386)
3625 @@ -30,85 +37,19 @@ _proxy_pda = 0;
3626  
3627  PHDRS {
3628         text PT_LOAD FLAGS(5);  /* R_E */
3629 -       data PT_LOAD FLAGS(7);  /* RWE */
3630 +       data PT_LOAD FLAGS(6);  /* RW_ */
3631         note PT_NOTE FLAGS(4);  /* R__ */
3632  }
3633  SECTIONS
3634  {
3635    . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
3636 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
3637 -  /* read-only */
3638 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
3639 -       _text = .;                      /* Text and read-only data */
3640 -       *(.text)
3641 -       SCHED_TEXT
3642 -       LOCK_TEXT
3643 -       KPROBES_TEXT
3644 -       *(.fixup)
3645 -       *(.gnu.warning)
3646 -       _etext = .;                     /* End of text section */
3647 -  } :text = 0x9090
3648 -
3649 -  . = ALIGN(16);               /* Exception table */
3650 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
3651 -       __start___ex_table = .;
3652 -        *(__ex_table)
3653 -       __stop___ex_table = .;
3654 -  }
3655 +  phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
3656  
3657 -  RODATA
3658 -
3659 -  BUG_TABLE
3660 -
3661 -  . = ALIGN(4);
3662 -  .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
3663 -       __tracedata_start = .;
3664 -       *(.tracedata)
3665 -       __tracedata_end = .;
3666 -  }
3667 -
3668 -  /* writeable */
3669 -  . = ALIGN(4096);
3670 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
3671 -       *(.data)
3672 -       CONSTRUCTORS
3673 -       } :data
3674 -
3675 -  .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) {
3676 -       __start_paravirtprobe = .;
3677 -       *(.paravirtprobe)
3678 -       __stop_paravirtprobe = .;
3679 -  }
3680 -
3681 -  . = ALIGN(4096);
3682 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
3683 -       __nosave_begin = .;
3684 -       *(.data.nosave)
3685 -       . = ALIGN(4096);
3686 -       __nosave_end = .;
3687 -  }
3688 -
3689 -  . = ALIGN(4096);
3690 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
3691 -       *(.data.idt)
3692 -  }
3693 -
3694 -  . = ALIGN(32);
3695 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3696 -       *(.data.cacheline_aligned)
3697 -  }
3698 -
3699 -  /* rarely changed data like cpu maps */
3700 -  . = ALIGN(32);
3701 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
3702 -       *(.data.read_mostly)
3703 -       _edata = .;             /* End of data section */
3704 -  }
3705 -
3706 -  . = ALIGN(THREAD_SIZE);      /* init_task */
3707 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3708 -       *(.data.init_task)
3709 -  }
3710 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
3711 +       BYTE(0xEA) /* jmp far */
3712 +       LONG(phys_startup_32)
3713 +       SHORT(__BOOT_CS)
3714 +       } :text = 0x9090
3715  
3716    /* might get freed after init */
3717    . = ALIGN(4096);
3718 @@ -137,14 +78,10 @@ SECTIONS
3719    . = ALIGN(4096);
3720  
3721    /* will be freed after init */
3722 -  . = ALIGN(4096);             /* Init code and data */
3723 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
3724 -       __init_begin = .;
3725 -       _sinittext = .;
3726 -       *(.init.text)
3727 -       _einittext = .;
3728 -  }
3729 -  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) { *(.init.data) }
3730 +  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
3731 +       __init_begin = .;
3732 +       *(.init.data)
3733 +       }
3734    . = ALIGN(16);
3735    .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
3736         __setup_start = .;
3737 @@ -177,9 +114,6 @@ SECTIONS
3738         *(.parainstructions)
3739         __stop_parainstructions = .;
3740    }
3741 -  /* .exit.text is discard at runtime, not link time, to deal with references
3742 -     from .altinstructions and .eh_frame */
3743 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) }
3744    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) { *(.exit.data) }
3745    . = ALIGN(4096);
3746    .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
3747 @@ -193,11 +127,131 @@ SECTIONS
3748         *(.data.percpu)
3749         __per_cpu_end = .;
3750    }
3751 +
3752 +  /* read-only */
3753 +
3754 +  . = ALIGN(4096);             /* Init code and data */
3755 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3756 +       _sinittext = .;
3757 +       *(.init.text)
3758 +       _einittext = .;
3759 +  }
3760 +
3761 +  /* .exit.text is discard at runtime, not link time, to deal with references
3762 +     from .altinstructions and .eh_frame */
3763 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) { *(.exit.text) }
3764 +
3765 +#ifdef CONFIG_PAX_KERNEXEC
3766 +  .text.align : AT(ADDR(.text.align) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3767 +       . = ALIGN(__KERNEL_TEXT_OFFSET - LOAD_OFFSET) - 1;
3768 +       BYTE(0)
3769 +  }
3770 +#else
3771    . = ALIGN(4096);
3772 +#endif
3773 +
3774    /* freed after init ends here */
3775 -       
3776 +
3777 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
3778 +       __init_end = . + __KERNEL_TEXT_OFFSET;
3779 +       _text = .;                      /* Text and read-only data */
3780 +       *(.text)
3781 +       SCHED_TEXT
3782 +       LOCK_TEXT
3783 +       KPROBES_TEXT
3784 +       *(.fixup)
3785 +       *(.gnu.warning)
3786 +       _etext = .;                     /* End of text section */
3787 +  } :text = 0x9090
3788 +
3789 +  . += __KERNEL_TEXT_OFFSET;
3790 +  . = ALIGN(16);               /* Exception table */
3791 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
3792 +       __start___ex_table = .;
3793 +        *(__ex_table)
3794 +       __stop___ex_table = .;
3795 +  }
3796 +
3797 +  . = ALIGN(4096);
3798 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
3799 +       *(.empty_zero_page)
3800 +
3801 +#ifdef CONFIG_X86_PAE
3802 +       *(.swapper_pm_dir)
3803 +#endif
3804 +
3805 +       *(.swapper_pg_dir)
3806 +       *(.idt)
3807 +       }
3808 +
3809 +  RODATA
3810 +
3811 +  BUG_TABLE
3812 +
3813 +  . = ALIGN(4);
3814 +  .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
3815 +       __tracedata_start = .;
3816 +       *(.tracedata)
3817 +       __tracedata_end = .;
3818 +  }
3819 +
3820 +#ifdef CONFIG_PAX_KERNEXEC
3821 +  . = ALIGN(4096);
3822 +
3823 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
3824 +       MODULES_VADDR = .;
3825 +       . += (4 * 1024 * 1024);
3826 +       . = ALIGN(1 << PMD_SHIFT) - 1;
3827 +       BYTE(0)
3828 +       MODULES_END = .;
3829 +  }
3830 +
3831 +#else
3832 +  . = ALIGN(32);
3833 +#endif
3834 +
3835 +  /* writeable */
3836 +  . = ALIGN(4096);
3837 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
3838 +       _data = .;
3839 +       *(.data)
3840 +       CONSTRUCTORS
3841 +       } :data
3842 +
3843 +  .paravirtprobe : AT(ADDR(.paravirtprobe) - LOAD_OFFSET) {
3844 +       __start_paravirtprobe = .;
3845 +       *(.paravirtprobe)
3846 +       __stop_paravirtprobe = .;
3847 +  }
3848 +
3849 +  . = ALIGN(4096);
3850 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
3851 +       __nosave_begin = .;
3852 +       *(.data.nosave)
3853 +       . = ALIGN(4096);
3854 +       __nosave_end = .;
3855 +  }
3856 +
3857 +  . = ALIGN(32);
3858 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
3859 +       *(.data.cacheline_aligned)
3860 +  }
3861 +
3862 +  /* rarely changed data like cpu maps */
3863 +  . = ALIGN(32);
3864 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
3865 +       *(.data.read_mostly)
3866 +       _edata = .;             /* End of data section */
3867 +  }
3868 +
3869 +  . = ALIGN(THREAD_SIZE);      /* init_task */
3870 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
3871 +       *(.data.init_task)
3872 +  }
3873 +
3874 +  . = ALIGN(4096);
3875 +
3876    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
3877 -       __init_end = .;
3878         __bss_start = .;                /* BSS */
3879         *(.bss.page_aligned)
3880         *(.bss)
3881 diff -urNp linux-2.6.20.3/arch/i386/lib/checksum.S linux-2.6.20.3/arch/i386/lib/checksum.S
3882 --- linux-2.6.20.3/arch/i386/lib/checksum.S     2007-03-13 14:27:08.000000000 -0400
3883 +++ linux-2.6.20.3/arch/i386/lib/checksum.S     2007-03-23 08:10:06.000000000 -0400
3884 @@ -26,7 +26,8 @@
3885   */
3886  
3887  #include <asm/errno.h>
3888 -                               
3889 +#include <asm/segment.h>
3890 +
3891  /*
3892   * computes a partial checksum, e.g. for TCP/UDP fragments
3893   */
3894 @@ -280,12 +281,23 @@ unsigned int csum_partial_copy_generic (
3895  
3896  .align 4
3897  .globl csum_partial_copy_generic
3898 -                               
3899 +.globl csum_partial_copy_generic_to_user
3900 +.globl csum_partial_copy_generic_from_user
3901 +
3902  #ifndef CONFIG_X86_USE_PPRO_CHECKSUM
3903  
3904  #define ARGBASE 16             
3905  #define FP             12
3906 -               
3907 +
3908 +csum_partial_copy_generic_to_user:
3909 +       pushl $(__USER_DS)
3910 +       popl %es
3911 +       jmp csum_partial_copy_generic
3912 +
3913 +csum_partial_copy_generic_from_user:
3914 +       pushl $(__USER_DS)
3915 +       popl %ds
3916 +
3917  csum_partial_copy_generic:
3918         subl  $4,%esp   
3919         pushl %edi
3920 @@ -304,7 +316,7 @@ csum_partial_copy_generic:
3921         jmp 4f
3922  SRC(1: movw (%esi), %bx        )
3923         addl $2, %esi
3924 -DST(   movw %bx, (%edi)        )
3925 +DST(   movw %bx, %es:(%edi)    )
3926         addl $2, %edi
3927         addw %bx, %ax   
3928         adcl $0, %eax
3929 @@ -316,30 +328,30 @@ DST(      movw %bx, (%edi)        )
3930  SRC(1: movl (%esi), %ebx       )
3931  SRC(   movl 4(%esi), %edx      )
3932         adcl %ebx, %eax
3933 -DST(   movl %ebx, (%edi)       )
3934 +DST(   movl %ebx, %es:(%edi)   )
3935         adcl %edx, %eax
3936 -DST(   movl %edx, 4(%edi)      )
3937 +DST(   movl %edx, %es:4(%edi)  )
3938  
3939  SRC(   movl 8(%esi), %ebx      )
3940  SRC(   movl 12(%esi), %edx     )
3941         adcl %ebx, %eax
3942 -DST(   movl %ebx, 8(%edi)      )
3943 +DST(   movl %ebx, %es:8(%edi)  )
3944         adcl %edx, %eax
3945 -DST(   movl %edx, 12(%edi)     )
3946 +DST(   movl %edx, %es:12(%edi) )
3947  
3948  SRC(   movl 16(%esi), %ebx     )
3949  SRC(   movl 20(%esi), %edx     )
3950         adcl %ebx, %eax
3951 -DST(   movl %ebx, 16(%edi)     )
3952 +DST(   movl %ebx, %es:16(%edi) )
3953         adcl %edx, %eax
3954 -DST(   movl %edx, 20(%edi)     )
3955 +DST(   movl %edx, %es:20(%edi) )
3956  
3957  SRC(   movl 24(%esi), %ebx     )
3958  SRC(   movl 28(%esi), %edx     )
3959         adcl %ebx, %eax
3960 -DST(   movl %ebx, 24(%edi)     )
3961 +DST(   movl %ebx, %es:24(%edi) )
3962         adcl %edx, %eax
3963 -DST(   movl %edx, 28(%edi)     )
3964 +DST(   movl %edx, %es:28(%edi) )
3965  
3966         lea 32(%esi), %esi
3967         lea 32(%edi), %edi
3968 @@ -353,7 +365,7 @@ DST(        movl %edx, 28(%edi)     )
3969         shrl $2, %edx                   # This clears CF
3970  SRC(3: movl (%esi), %ebx       )
3971         adcl %ebx, %eax
3972 -DST(   movl %ebx, (%edi)       )
3973 +DST(   movl %ebx, %es:(%edi)   )
3974         lea 4(%esi), %esi
3975         lea 4(%edi), %edi
3976         dec %edx
3977 @@ -365,12 +377,12 @@ DST(      movl %ebx, (%edi)       )
3978         jb 5f
3979  SRC(   movw (%esi), %cx        )
3980         leal 2(%esi), %esi
3981 -DST(   movw %cx, (%edi)        )
3982 +DST(   movw %cx, %es:(%edi)    )
3983         leal 2(%edi), %edi
3984         je 6f
3985         shll $16,%ecx
3986  SRC(5: movb (%esi), %cl        )
3987 -DST(   movb %cl, (%edi)        )
3988 +DST(   movb %cl, %es:(%edi)    )
3989  6:     addl %ecx, %eax
3990         adcl $0, %eax
3991  7:
3992 @@ -381,7 +393,7 @@ DST(        movb %cl, (%edi)        )
3993  
3994  6001:
3995         movl ARGBASE+20(%esp), %ebx     # src_err_ptr
3996 -       movl $-EFAULT, (%ebx)
3997 +       movl $-EFAULT, %ss:(%ebx)
3998  
3999         # zero the complete destination - computing the rest
4000         # is too much work 
4001 @@ -394,11 +406,15 @@ DST(      movb %cl, (%edi)        )
4002  
4003  6002:
4004         movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
4005 -       movl $-EFAULT,(%ebx)
4006 +       movl $-EFAULT,%ss:(%ebx)
4007         jmp 5000b
4008  
4009  .previous
4010  
4011 +       pushl %ss
4012 +       popl %ds
4013 +       pushl %ss
4014 +       popl %es
4015         popl %ebx
4016         popl %esi
4017         popl %edi
4018 @@ -410,17 +426,28 @@ DST(      movb %cl, (%edi)        )
4019  /* Version for PentiumII/PPro */
4020  
4021  #define ROUND1(x) \
4022 +       nop; nop; nop;                          \
4023         SRC(movl x(%esi), %ebx  )       ;       \
4024         addl %ebx, %eax                 ;       \
4025 -       DST(movl %ebx, x(%edi)  )       ; 
4026 +       DST(movl %ebx, %es:x(%edi));
4027  
4028  #define ROUND(x) \
4029 +       nop; nop; nop;                          \
4030         SRC(movl x(%esi), %ebx  )       ;       \
4031         adcl %ebx, %eax                 ;       \
4032 -       DST(movl %ebx, x(%edi)  )       ;
4033 +       DST(movl %ebx, %es:x(%edi));
4034  
4035  #define ARGBASE 12
4036 -               
4037 +
4038 +csum_partial_copy_generic_to_user:
4039 +       pushl $(__USER_DS)
4040 +       popl %es
4041 +       jmp csum_partial_copy_generic
4042 +
4043 +csum_partial_copy_generic_from_user:
4044 +       pushl $(__USER_DS)
4045 +       popl %ds
4046 +
4047  csum_partial_copy_generic:
4048         pushl %ebx
4049         pushl %edi
4050 @@ -439,7 +466,7 @@ csum_partial_copy_generic:
4051         subl %ebx, %edi  
4052         lea  -1(%esi),%edx
4053         andl $-32,%edx
4054 -       lea 3f(%ebx,%ebx), %ebx
4055 +       lea 3f(%ebx,%ebx,2), %ebx
4056         testl %esi, %esi 
4057         jmp *%ebx
4058  1:     addl $64,%esi
4059 @@ -460,19 +487,19 @@ csum_partial_copy_generic:
4060         jb 5f
4061  SRC(   movw (%esi), %dx         )
4062         leal 2(%esi), %esi
4063 -DST(   movw %dx, (%edi)         )
4064 +DST(   movw %dx, %es:(%edi)     )
4065         leal 2(%edi), %edi
4066         je 6f
4067         shll $16,%edx
4068  5:
4069  SRC(   movb (%esi), %dl         )
4070 -DST(   movb %dl, (%edi)         )
4071 +DST(   movb %dl, %es:(%edi)     )
4072  6:     addl %edx, %eax
4073         adcl $0, %eax
4074  7:
4075  .section .fixup, "ax"
4076  6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
4077 -       movl $-EFAULT, (%ebx)
4078 +       movl $-EFAULT, %ss:(%ebx)
4079         # zero the complete destination (computing the rest is too much work)
4080         movl ARGBASE+8(%esp),%edi       # dst
4081         movl ARGBASE+12(%esp),%ecx      # len
4082 @@ -480,10 +507,14 @@ DST(      movb %dl, (%edi)         )
4083         rep; stosb
4084         jmp 7b
4085  6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
4086 -       movl $-EFAULT, (%ebx)
4087 +       movl $-EFAULT, %ss:(%ebx)
4088         jmp  7b                 
4089  .previous                              
4090  
4091 +       pushl %ss
4092 +       popl %ds
4093 +       pushl %ss
4094 +       popl %es
4095         popl %esi
4096         popl %edi
4097         popl %ebx
4098 diff -urNp linux-2.6.20.3/arch/i386/lib/getuser.S linux-2.6.20.3/arch/i386/lib/getuser.S
4099 --- linux-2.6.20.3/arch/i386/lib/getuser.S      2007-03-13 14:27:08.000000000 -0400
4100 +++ linux-2.6.20.3/arch/i386/lib/getuser.S      2007-03-23 08:10:06.000000000 -0400
4101 @@ -9,6 +9,7 @@
4102   * return value.
4103   */
4104  #include <asm/thread_info.h>
4105 +#include <asm/segment.h>
4106  
4107  
4108  /*
4109 @@ -30,8 +31,12 @@ __get_user_1:
4110         GET_THREAD_INFO(%edx)
4111         cmpl TI_addr_limit(%edx),%eax
4112         jae bad_get_user
4113 +       pushl $(__USER_DS)
4114 +       popl %ds
4115  1:     movzbl (%eax),%edx
4116         xorl %eax,%eax
4117 +       pushl %ss
4118 +       pop %ds
4119         ret
4120  
4121  .align 4
4122 @@ -42,7 +47,11 @@ __get_user_2:
4123         GET_THREAD_INFO(%edx)
4124         cmpl TI_addr_limit(%edx),%eax
4125         jae bad_get_user
4126 +       pushl $(__USER_DS)
4127 +       popl %ds
4128  2:     movzwl -1(%eax),%edx
4129 +       pushl %ss
4130 +       pop %ds
4131         xorl %eax,%eax
4132         ret
4133  
4134 @@ -54,11 +63,17 @@ __get_user_4:
4135         GET_THREAD_INFO(%edx)
4136         cmpl TI_addr_limit(%edx),%eax
4137         jae bad_get_user
4138 +       pushl $(__USER_DS)
4139 +       popl %ds
4140  3:     movl -3(%eax),%edx
4141 +       pushl %ss
4142 +       pop %ds
4143         xorl %eax,%eax
4144         ret
4145  
4146  bad_get_user:
4147 +       pushl %ss
4148 +       pop %ds
4149         xorl %edx,%edx
4150         movl $-14,%eax
4151         ret
4152 diff -urNp linux-2.6.20.3/arch/i386/lib/mmx.c linux-2.6.20.3/arch/i386/lib/mmx.c
4153 --- linux-2.6.20.3/arch/i386/lib/mmx.c  2007-03-13 14:27:08.000000000 -0400
4154 +++ linux-2.6.20.3/arch/i386/lib/mmx.c  2007-03-23 09:32:49.000000000 -0400
4155 @@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void *
4156  {
4157         void *p;
4158         int i;
4159 +       unsigned long cr0;
4160  
4161         if (unlikely(in_interrupt()))
4162                 return __memcpy(to, from, len);
4163 @@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void *
4164         kernel_fpu_begin();
4165  
4166         __asm__ __volatile__ (
4167 -               "1: prefetch (%0)\n"            /* This set is 28 bytes */
4168 -               "   prefetch 64(%0)\n"
4169 -               "   prefetch 128(%0)\n"
4170 -               "   prefetch 192(%0)\n"
4171 -               "   prefetch 256(%0)\n"
4172 +               "1: prefetch (%1)\n"            /* This set is 28 bytes */
4173 +               "   prefetch 64(%1)\n"
4174 +               "   prefetch 128(%1)\n"
4175 +               "   prefetch 192(%1)\n"
4176 +               "   prefetch 256(%1)\n"
4177                 "2:  \n"
4178                 ".section .fixup, \"ax\"\n"
4179 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4180 +               "3:  \n"
4181 +
4182 +#ifdef CONFIG_PAX_KERNEXEC
4183 +               "   movl %%cr0, %0\n"
4184 +               "   movl %0, %%eax\n"
4185 +               "   andl $0xFFFEFFFF, %%eax\n"
4186 +               "   movl %%eax, %%cr0\n"
4187 +#endif
4188 +
4189 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4190 +
4191 +#ifdef CONFIG_PAX_KERNEXEC
4192 +               "   movl %0, %%cr0\n"
4193 +#endif
4194 +
4195                 "   jmp 2b\n"
4196                 ".previous\n"
4197                 ".section __ex_table,\"a\"\n"
4198                 "       .align 4\n"
4199                 "       .long 1b, 3b\n"
4200                 ".previous"
4201 -               : : "r" (from) );
4202 +               : "=&r" (cr0) : "r" (from) : "ax");
4203                 
4204         
4205         for(; i>5; i--)
4206         {
4207                 __asm__ __volatile__ (
4208 -               "1:  prefetch 320(%0)\n"
4209 -               "2:  movq (%0), %%mm0\n"
4210 -               "  movq 8(%0), %%mm1\n"
4211 -               "  movq 16(%0), %%mm2\n"
4212 -               "  movq 24(%0), %%mm3\n"
4213 -               "  movq %%mm0, (%1)\n"
4214 -               "  movq %%mm1, 8(%1)\n"
4215 -               "  movq %%mm2, 16(%1)\n"
4216 -               "  movq %%mm3, 24(%1)\n"
4217 -               "  movq 32(%0), %%mm0\n"
4218 -               "  movq 40(%0), %%mm1\n"
4219 -               "  movq 48(%0), %%mm2\n"
4220 -               "  movq 56(%0), %%mm3\n"
4221 -               "  movq %%mm0, 32(%1)\n"
4222 -               "  movq %%mm1, 40(%1)\n"
4223 -               "  movq %%mm2, 48(%1)\n"
4224 -               "  movq %%mm3, 56(%1)\n"
4225 +               "1:  prefetch 320(%1)\n"
4226 +               "2:  movq (%1), %%mm0\n"
4227 +               "  movq 8(%1), %%mm1\n"
4228 +               "  movq 16(%1), %%mm2\n"
4229 +               "  movq 24(%1), %%mm3\n"
4230 +               "  movq %%mm0, (%2)\n"
4231 +               "  movq %%mm1, 8(%2)\n"
4232 +               "  movq %%mm2, 16(%2)\n"
4233 +               "  movq %%mm3, 24(%2)\n"
4234 +               "  movq 32(%1), %%mm0\n"
4235 +               "  movq 40(%1), %%mm1\n"
4236 +               "  movq 48(%1), %%mm2\n"
4237 +               "  movq 56(%1), %%mm3\n"
4238 +               "  movq %%mm0, 32(%2)\n"
4239 +               "  movq %%mm1, 40(%2)\n"
4240 +               "  movq %%mm2, 48(%2)\n"
4241 +               "  movq %%mm3, 56(%2)\n"
4242                 ".section .fixup, \"ax\"\n"
4243 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4244 +               "3:\n"
4245 +
4246 +#ifdef CONFIG_PAX_KERNEXEC
4247 +               "   movl %%cr0, %0\n"
4248 +               "   movl %0, %%eax\n"
4249 +               "   andl $0xFFFEFFFF, %%eax\n"
4250 +               "   movl %%eax, %%cr0\n"
4251 +#endif
4252 +
4253 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4254 +
4255 +#ifdef CONFIG_PAX_KERNEXEC
4256 +               "   movl %0, %%cr0\n"
4257 +#endif
4258 +
4259                 "   jmp 2b\n"
4260                 ".previous\n"
4261                 ".section __ex_table,\"a\"\n"
4262                 "       .align 4\n"
4263                 "       .long 1b, 3b\n"
4264                 ".previous"
4265 -               : : "r" (from), "r" (to) : "memory");
4266 +               : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4267                 from+=64;
4268                 to+=64;
4269         }
4270 @@ -164,6 +193,7 @@ static void fast_clear_page(void *page)
4271  static void fast_copy_page(void *to, void *from)
4272  {
4273         int i;
4274 +       unsigned long cr0;
4275  
4276         kernel_fpu_begin();
4277  
4278 @@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi
4279          * but that is for later. -AV
4280          */
4281         __asm__ __volatile__ (
4282 -               "1: prefetch (%0)\n"
4283 -               "   prefetch 64(%0)\n"
4284 -               "   prefetch 128(%0)\n"
4285 -               "   prefetch 192(%0)\n"
4286 -               "   prefetch 256(%0)\n"
4287 +               "1: prefetch (%1)\n"
4288 +               "   prefetch 64(%1)\n"
4289 +               "   prefetch 128(%1)\n"
4290 +               "   prefetch 192(%1)\n"
4291 +               "   prefetch 256(%1)\n"
4292                 "2:  \n"
4293                 ".section .fixup, \"ax\"\n"
4294 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4295 +               "3:  \n"
4296 +
4297 +#ifdef CONFIG_PAX_KERNEXEC
4298 +               "   movl %%cr0, %0\n"
4299 +               "   movl %0, %%eax\n"
4300 +               "   andl $0xFFFEFFFF, %%eax\n"
4301 +               "   movl %%eax, %%cr0\n"
4302 +#endif
4303 +
4304 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4305 +
4306 +#ifdef CONFIG_PAX_KERNEXEC
4307 +               "   movl %0, %%cr0\n"
4308 +#endif
4309 +
4310                 "   jmp 2b\n"
4311                 ".previous\n"
4312                 ".section __ex_table,\"a\"\n"
4313                 "       .align 4\n"
4314                 "       .long 1b, 3b\n"
4315                 ".previous"
4316 -               : : "r" (from) );
4317 +               : "=&r" (cr0) : "r" (from) : "ax");
4318  
4319         for(i=0; i<(4096-320)/64; i++)
4320         {
4321                 __asm__ __volatile__ (
4322 -               "1: prefetch 320(%0)\n"
4323 -               "2: movq (%0), %%mm0\n"
4324 -               "   movntq %%mm0, (%1)\n"
4325 -               "   movq 8(%0), %%mm1\n"
4326 -               "   movntq %%mm1, 8(%1)\n"
4327 -               "   movq 16(%0), %%mm2\n"
4328 -               "   movntq %%mm2, 16(%1)\n"
4329 -               "   movq 24(%0), %%mm3\n"
4330 -               "   movntq %%mm3, 24(%1)\n"
4331 -               "   movq 32(%0), %%mm4\n"
4332 -               "   movntq %%mm4, 32(%1)\n"
4333 -               "   movq 40(%0), %%mm5\n"
4334 -               "   movntq %%mm5, 40(%1)\n"
4335 -               "   movq 48(%0), %%mm6\n"
4336 -               "   movntq %%mm6, 48(%1)\n"
4337 -               "   movq 56(%0), %%mm7\n"
4338 -               "   movntq %%mm7, 56(%1)\n"
4339 +               "1: prefetch 320(%1)\n"
4340 +               "2: movq (%1), %%mm0\n"
4341 +               "   movntq %%mm0, (%2)\n"
4342 +               "   movq 8(%1), %%mm1\n"
4343 +               "   movntq %%mm1, 8(%2)\n"
4344 +               "   movq 16(%1), %%mm2\n"
4345 +               "   movntq %%mm2, 16(%2)\n"
4346 +               "   movq 24(%1), %%mm3\n"
4347 +               "   movntq %%mm3, 24(%2)\n"
4348 +               "   movq 32(%1), %%mm4\n"
4349 +               "   movntq %%mm4, 32(%2)\n"
4350 +               "   movq 40(%1), %%mm5\n"
4351 +               "   movntq %%mm5, 40(%2)\n"
4352 +               "   movq 48(%1), %%mm6\n"
4353 +               "   movntq %%mm6, 48(%2)\n"
4354 +               "   movq 56(%1), %%mm7\n"
4355 +               "   movntq %%mm7, 56(%2)\n"
4356                 ".section .fixup, \"ax\"\n"
4357 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4358 +               "3:\n"
4359 +
4360 +#ifdef CONFIG_PAX_KERNEXEC
4361 +               "   movl %%cr0, %0\n"
4362 +               "   movl %0, %%eax\n"
4363 +               "   andl $0xFFFEFFFF, %%eax\n"
4364 +               "   movl %%eax, %%cr0\n"
4365 +#endif
4366 +
4367 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4368 +
4369 +#ifdef CONFIG_PAX_KERNEXEC
4370 +               "   movl %0, %%cr0\n"
4371 +#endif
4372 +
4373                 "   jmp 2b\n"
4374                 ".previous\n"
4375                 ".section __ex_table,\"a\"\n"
4376                 "       .align 4\n"
4377                 "       .long 1b, 3b\n"
4378                 ".previous"
4379 -               : : "r" (from), "r" (to) : "memory");
4380 +               : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4381                 from+=64;
4382                 to+=64;
4383         }
4384 @@ -296,56 +354,84 @@ static void fast_clear_page(void *page)
4385  static void fast_copy_page(void *to, void *from)
4386  {
4387         int i;
4388 -       
4389 -       
4390 +       unsigned long cr0;
4391 +
4392         kernel_fpu_begin();
4393  
4394         __asm__ __volatile__ (
4395 -               "1: prefetch (%0)\n"
4396 -               "   prefetch 64(%0)\n"
4397 -               "   prefetch 128(%0)\n"
4398 -               "   prefetch 192(%0)\n"
4399 -               "   prefetch 256(%0)\n"
4400 +               "1: prefetch (%1)\n"
4401 +               "   prefetch 64(%1)\n"
4402 +               "   prefetch 128(%1)\n"
4403 +               "   prefetch 192(%1)\n"
4404 +               "   prefetch 256(%1)\n"
4405                 "2:  \n"
4406                 ".section .fixup, \"ax\"\n"
4407 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4408 +               "3:  \n"
4409 +
4410 +#ifdef CONFIG_PAX_KERNEXEC
4411 +               "   movl %%cr0, %0\n"
4412 +               "   movl %0, %%eax\n"
4413 +               "   andl $0xFFFEFFFF, %%eax\n"
4414 +               "   movl %%eax, %%cr0\n"
4415 +#endif
4416 +
4417 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
4418 +
4419 +#ifdef CONFIG_PAX_KERNEXEC
4420 +               "   movl %0, %%cr0\n"
4421 +#endif
4422 +
4423                 "   jmp 2b\n"
4424                 ".previous\n"
4425                 ".section __ex_table,\"a\"\n"
4426                 "       .align 4\n"
4427                 "       .long 1b, 3b\n"
4428                 ".previous"
4429 -               : : "r" (from) );
4430 +               : "=&r" (cr0) : "r" (from) : "ax");
4431  
4432         for(i=0; i<4096/64; i++)
4433         {
4434                 __asm__ __volatile__ (
4435 -               "1: prefetch 320(%0)\n"
4436 -               "2: movq (%0), %%mm0\n"
4437 -               "   movq 8(%0), %%mm1\n"
4438 -               "   movq 16(%0), %%mm2\n"
4439 -               "   movq 24(%0), %%mm3\n"
4440 -               "   movq %%mm0, (%1)\n"
4441 -               "   movq %%mm1, 8(%1)\n"
4442 -               "   movq %%mm2, 16(%1)\n"
4443 -               "   movq %%mm3, 24(%1)\n"
4444 -               "   movq 32(%0), %%mm0\n"
4445 -               "   movq 40(%0), %%mm1\n"
4446 -               "   movq 48(%0), %%mm2\n"
4447 -               "   movq 56(%0), %%mm3\n"
4448 -               "   movq %%mm0, 32(%1)\n"
4449 -               "   movq %%mm1, 40(%1)\n"
4450 -               "   movq %%mm2, 48(%1)\n"
4451 -               "   movq %%mm3, 56(%1)\n"
4452 +               "1: prefetch 320(%1)\n"
4453 +               "2: movq (%1), %%mm0\n"
4454 +               "   movq 8(%1), %%mm1\n"
4455 +               "   movq 16(%1), %%mm2\n"
4456 +               "   movq 24(%1), %%mm3\n"
4457 +               "   movq %%mm0, (%2)\n"
4458 +               "   movq %%mm1, 8(%2)\n"
4459 +               "   movq %%mm2, 16(%2)\n"
4460 +               "   movq %%mm3, 24(%2)\n"
4461 +               "   movq 32(%1), %%mm0\n"
4462 +               "   movq 40(%1), %%mm1\n"
4463 +               "   movq 48(%1), %%mm2\n"
4464 +               "   movq 56(%1), %%mm3\n"
4465 +               "   movq %%mm0, 32(%2)\n"
4466 +               "   movq %%mm1, 40(%2)\n"
4467 +               "   movq %%mm2, 48(%2)\n"
4468 +               "   movq %%mm3, 56(%2)\n"
4469                 ".section .fixup, \"ax\"\n"
4470 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4471 +               "3:\n"
4472 +
4473 +#ifdef CONFIG_PAX_KERNEXEC
4474 +               "   movl %%cr0, %0\n"
4475 +               "   movl %0, %%eax\n"
4476 +               "   andl $0xFFFEFFFF, %%eax\n"
4477 +               "   movl %%eax, %%cr0\n"
4478 +#endif
4479 +
4480 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
4481 +
4482 +#ifdef CONFIG_PAX_KERNEXEC
4483 +               "   movl %0, %%cr0\n"
4484 +#endif
4485 +
4486                 "   jmp 2b\n"
4487                 ".previous\n"
4488                 ".section __ex_table,\"a\"\n"
4489                 "       .align 4\n"
4490                 "       .long 1b, 3b\n"
4491                 ".previous"
4492 -               : : "r" (from), "r" (to) : "memory");
4493 +               : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
4494                 from+=64;
4495                 to+=64;
4496         }
4497 diff -urNp linux-2.6.20.3/arch/i386/lib/putuser.S linux-2.6.20.3/arch/i386/lib/putuser.S
4498 --- linux-2.6.20.3/arch/i386/lib/putuser.S      2007-03-13 14:27:08.000000000 -0400
4499 +++ linux-2.6.20.3/arch/i386/lib/putuser.S      2007-03-23 08:10:06.000000000 -0400
4500 @@ -9,6 +9,7 @@
4501   * return value.
4502   */
4503  #include <asm/thread_info.h>
4504 +#include <asm/segment.h>
4505  
4506  
4507  /*
4508 @@ -33,7 +34,11 @@ __put_user_1:
4509         ENTER
4510         cmpl TI_addr_limit(%ebx),%ecx
4511         jae bad_put_user
4512 +       pushl $(__USER_DS)
4513 +       popl %ds
4514  1:     movb %al,(%ecx)
4515 +       pushl %ss
4516 +       popl %ds
4517         xorl %eax,%eax
4518         EXIT
4519  
4520 @@ -45,7 +50,11 @@ __put_user_2:
4521         subl $1,%ebx
4522         cmpl %ebx,%ecx
4523         jae bad_put_user
4524 +       pushl $(__USER_DS)
4525 +       popl %ds
4526  2:     movw %ax,(%ecx)
4527 +       pushl %ss
4528 +       popl %ds
4529         xorl %eax,%eax
4530         EXIT
4531  
4532 @@ -57,7 +66,11 @@ __put_user_4:
4533         subl $3,%ebx
4534         cmpl %ebx,%ecx
4535         jae bad_put_user
4536 +       pushl $(__USER_DS)
4537 +       popl %ds
4538  3:     movl %eax,(%ecx)
4539 +       pushl %ss
4540 +       popl %ds
4541         xorl %eax,%eax
4542         EXIT
4543  
4544 @@ -69,12 +82,18 @@ __put_user_8:
4545         subl $7,%ebx
4546         cmpl %ebx,%ecx
4547         jae bad_put_user
4548 +       pushl $(__USER_DS)
4549 +       popl %ds
4550  4:     movl %eax,(%ecx)
4551  5:     movl %edx,4(%ecx)
4552 +       pushl %ss
4553 +       popl %ds
4554         xorl %eax,%eax
4555         EXIT
4556  
4557  bad_put_user:
4558 +       pushl %ss
4559 +       popl %ds
4560         movl $-14,%eax
4561         EXIT
4562  
4563 diff -urNp linux-2.6.20.3/arch/i386/lib/usercopy.c linux-2.6.20.3/arch/i386/lib/usercopy.c
4564 --- linux-2.6.20.3/arch/i386/lib/usercopy.c     2007-03-13 14:27:08.000000000 -0400
4565 +++ linux-2.6.20.3/arch/i386/lib/usercopy.c     2007-03-23 08:10:06.000000000 -0400
4566 @@ -28,34 +28,41 @@ static inline int __movsl_is_ok(unsigned
4567   * Copy a null terminated string from userspace.
4568   */
4569  
4570 -#define __do_strncpy_from_user(dst,src,count,res)                         \
4571 -do {                                                                      \
4572 -       int __d0, __d1, __d2;                                              \
4573 -       might_sleep();                                                     \
4574 -       __asm__ __volatile__(                                              \
4575 -               "       testl %1,%1\n"                                     \
4576 -               "       jz 2f\n"                                           \
4577 -               "0:     lodsb\n"                                           \
4578 -               "       stosb\n"                                           \
4579 -               "       testb %%al,%%al\n"                                 \
4580 -               "       jz 1f\n"                                           \
4581 -               "       decl %1\n"                                         \
4582 -               "       jnz 0b\n"                                          \
4583 -               "1:     subl %1,%0\n"                                      \
4584 -               "2:\n"                                                     \
4585 -               ".section .fixup,\"ax\"\n"                                 \
4586 -               "3:     movl %5,%0\n"                                      \
4587 -               "       jmp 2b\n"                                          \
4588 -               ".previous\n"                                              \
4589 -               ".section __ex_table,\"a\"\n"                              \
4590 -               "       .align 4\n"                                        \
4591 -               "       .long 0b,3b\n"                                     \
4592 -               ".previous"                                                \
4593 -               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
4594 -                 "=&D" (__d2)                                             \
4595 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
4596 -               : "memory");                                               \
4597 -} while (0)
4598 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
4599 +{
4600 +       int __d0, __d1, __d2;
4601 +       long res = -EFAULT;
4602 +
4603 +       might_sleep();
4604 +       __asm__ __volatile__(
4605 +               "       movw %w10,%%ds\n"
4606 +               "       testl %1,%1\n"
4607 +               "       jz 2f\n"
4608 +               "0:     lodsb\n"
4609 +               "       stosb\n"
4610 +               "       testb %%al,%%al\n"
4611 +               "       jz 1f\n"
4612 +               "       decl %1\n"
4613 +               "       jnz 0b\n"
4614 +               "1:     subl %1,%0\n"
4615 +               "2:\n"
4616 +               "       pushl %%ss\n"
4617 +               "       popl %%ds\n"
4618 +               ".section .fixup,\"ax\"\n"
4619 +               "3:     movl %5,%0\n"
4620 +               "       jmp 2b\n"
4621 +               ".previous\n"
4622 +               ".section __ex_table,\"a\"\n"
4623 +               "       .align 4\n"
4624 +               "       .long 0b,3b\n"
4625 +               ".previous"
4626 +               : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),
4627 +                 "=&D" (__d2)
4628 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
4629 +                 "r"(__USER_DS)
4630 +               : "memory");
4631 +       return res;
4632 +}
4633  
4634  /**
4635   * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
4636 @@ -80,9 +87,7 @@ do {                                                                     \
4637  long
4638  __strncpy_from_user(char *dst, const char __user *src, long count)
4639  {
4640 -       long res;
4641 -       __do_strncpy_from_user(dst, src, count, res);
4642 -       return res;
4643 +       return __do_strncpy_from_user(dst, src, count);
4644  }
4645  EXPORT_SYMBOL(__strncpy_from_user);
4646  
4647 @@ -109,7 +114,7 @@ strncpy_from_user(char *dst, const char 
4648  {
4649         long res = -EFAULT;
4650         if (access_ok(VERIFY_READ, src, 1))
4651 -               __do_strncpy_from_user(dst, src, count, res);
4652 +               res = __do_strncpy_from_user(dst, src, count);
4653         return res;
4654  }
4655  EXPORT_SYMBOL(strncpy_from_user);
4656 @@ -118,27 +123,33 @@ EXPORT_SYMBOL(strncpy_from_user);
4657   * Zero Userspace
4658   */
4659  
4660 -#define __do_clear_user(addr,size)                                     \
4661 -do {                                                                   \
4662 -       int __d0;                                                       \
4663 -       might_sleep();                                                  \
4664 -       __asm__ __volatile__(                                           \
4665 -               "0:     rep; stosl\n"                                   \
4666 -               "       movl %2,%0\n"                                   \
4667 -               "1:     rep; stosb\n"                                   \
4668 -               "2:\n"                                                  \
4669 -               ".section .fixup,\"ax\"\n"                              \
4670 -               "3:     lea 0(%2,%0,4),%0\n"                            \
4671 -               "       jmp 2b\n"                                       \
4672 -               ".previous\n"                                           \
4673 -               ".section __ex_table,\"a\"\n"                           \
4674 -               "       .align 4\n"                                     \
4675 -               "       .long 0b,3b\n"                                  \
4676 -               "       .long 1b,2b\n"                                  \
4677 -               ".previous"                                             \
4678 -               : "=&c"(size), "=&D" (__d0)                             \
4679 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
4680 -} while (0)
4681 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
4682 +{
4683 +       int __d0;
4684 +
4685 +       might_sleep();
4686 +       __asm__ __volatile__(
4687 +               "       movw %w6,%%es\n"
4688 +               "0:     rep; stosl\n"
4689 +               "       movl %2,%0\n"
4690 +               "1:     rep; stosb\n"
4691 +               "2:\n"
4692 +               "       pushl %%ss\n"
4693 +               "       popl %%es\n"
4694 +               ".section .fixup,\"ax\"\n"
4695 +               "3:     lea 0(%2,%0,4),%0\n"
4696 +               "       jmp 2b\n"
4697 +               ".previous\n"
4698 +               ".section __ex_table,\"a\"\n"
4699 +               "       .align 4\n"
4700 +               "       .long 0b,3b\n"
4701 +               "       .long 1b,2b\n"
4702 +               ".previous"
4703 +               : "=&c"(size), "=&D" (__d0)
4704 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
4705 +                 "r"(__USER_DS));
4706 +       return size;
4707 +}
4708  
4709  /**
4710   * clear_user: - Zero a block of memory in user space.
4711 @@ -155,7 +166,7 @@ clear_user(void __user *to, unsigned lon
4712  {
4713         might_sleep();
4714         if (access_ok(VERIFY_WRITE, to, n))
4715 -               __do_clear_user(to, n);
4716 +               n = __do_clear_user(to, n);
4717         return n;
4718  }
4719  EXPORT_SYMBOL(clear_user);
4720 @@ -174,8 +185,7 @@ EXPORT_SYMBOL(clear_user);
4721  unsigned long
4722  __clear_user(void __user *to, unsigned long n)
4723  {
4724 -       __do_clear_user(to, n);
4725 -       return n;
4726 +       return __do_clear_user(to, n);
4727  }
4728  EXPORT_SYMBOL(__clear_user);
4729  
4730 @@ -198,14 +208,17 @@ long strnlen_user(const char __user *s, 
4731         might_sleep();
4732  
4733         __asm__ __volatile__(
4734 +               "       movw %w8,%%es\n"
4735                 "       testl %0, %0\n"
4736                 "       jz 3f\n"
4737 -               "       andl %0,%%ecx\n"
4738 +               "       movl %0,%%ecx\n"
4739                 "0:     repne; scasb\n"
4740                 "       setne %%al\n"
4741                 "       subl %%ecx,%0\n"
4742                 "       addl %0,%%eax\n"
4743                 "1:\n"
4744 +               "       pushl %%ss\n"
4745 +               "       popl %%es\n"
4746                 ".section .fixup,\"ax\"\n"
4747                 "2:     xorl %%eax,%%eax\n"
4748                 "       jmp 1b\n"
4749 @@ -217,7 +230,7 @@ long strnlen_user(const char __user *s, 
4750                 "       .long 0b,2b\n"
4751                 ".previous"
4752                 :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
4753 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
4754 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
4755                 :"cc");
4756         return res & mask;
4757  }
4758 @@ -225,10 +238,11 @@ EXPORT_SYMBOL(strnlen_user);
4759  
4760  #ifdef CONFIG_X86_INTEL_USERCOPY
4761  static unsigned long
4762 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
4763 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
4764  {
4765         int d0, d1;
4766         __asm__ __volatile__(
4767 +                      "       movw %w6, %%es\n"
4768                        "       .align 2,0x90\n"
4769                        "1:     movl 32(%4), %%eax\n"
4770                        "       cmpl $67, %0\n"
4771 @@ -237,36 +251,36 @@ __copy_user_intel(void __user *to, const
4772                        "       .align 2,0x90\n"
4773                        "3:     movl 0(%4), %%eax\n"
4774                        "4:     movl 4(%4), %%edx\n"
4775 -                      "5:     movl %%eax, 0(%3)\n"
4776 -                      "6:     movl %%edx, 4(%3)\n"
4777 +                      "5:     movl %%eax, %%es:0(%3)\n"
4778 +                      "6:     movl %%edx, %%es:4(%3)\n"
4779                        "7:     movl 8(%4), %%eax\n"
4780                        "8:     movl 12(%4),%%edx\n"
4781 -                      "9:     movl %%eax, 8(%3)\n"
4782 -                      "10:    movl %%edx, 12(%3)\n"
4783 +                      "9:     movl %%eax, %%es:8(%3)\n"
4784 +                      "10:    movl %%edx, %%es:12(%3)\n"
4785                        "11:    movl 16(%4), %%eax\n"
4786                        "12:    movl 20(%4), %%edx\n"
4787 -                      "13:    movl %%eax, 16(%3)\n"
4788 -                      "14:    movl %%edx, 20(%3)\n"
4789 +                      "13:    movl %%eax, %%es:16(%3)\n"
4790 +                      "14:    movl %%edx, %%es:20(%3)\n"
4791                        "15:    movl 24(%4), %%eax\n"
4792                        "16:    movl 28(%4), %%edx\n"
4793 -                      "17:    movl %%eax, 24(%3)\n"
4794 -                      "18:    movl %%edx, 28(%3)\n"
4795 +                      "17:    movl %%eax, %%es:24(%3)\n"
4796 +                      "18:    movl %%edx, %%es:28(%3)\n"
4797                        "19:    movl 32(%4), %%eax\n"
4798                        "20:    movl 36(%4), %%edx\n"
4799 -                      "21:    movl %%eax, 32(%3)\n"
4800 -                      "22:    movl %%edx, 36(%3)\n"
4801 +                      "21:    movl %%eax, %%es:32(%3)\n"
4802 +                      "22:    movl %%edx, %%es:36(%3)\n"
4803                        "23:    movl 40(%4), %%eax\n"
4804                        "24:    movl 44(%4), %%edx\n"
4805 -                      "25:    movl %%eax, 40(%3)\n"
4806 -                      "26:    movl %%edx, 44(%3)\n"
4807 +                      "25:    movl %%eax, %%es:40(%3)\n"
4808 +                      "26:    movl %%edx, %%es:44(%3)\n"
4809                        "27:    movl 48(%4), %%eax\n"
4810                        "28:    movl 52(%4), %%edx\n"
4811 -                      "29:    movl %%eax, 48(%3)\n"
4812 -                      "30:    movl %%edx, 52(%3)\n"
4813 +                      "29:    movl %%eax, %%es:48(%3)\n"
4814 +                      "30:    movl %%edx, %%es:52(%3)\n"
4815                        "31:    movl 56(%4), %%eax\n"
4816                        "32:    movl 60(%4), %%edx\n"
4817 -                      "33:    movl %%eax, 56(%3)\n"
4818 -                      "34:    movl %%edx, 60(%3)\n"
4819 +                      "33:    movl %%eax, %%es:56(%3)\n"
4820 +                      "34:    movl %%edx, %%es:60(%3)\n"
4821                        "       addl $-64, %0\n"
4822                        "       addl $64, %4\n"
4823                        "       addl $64, %3\n"
4824 @@ -280,6 +294,8 @@ __copy_user_intel(void __user *to, const
4825                        "36:    movl %%eax, %0\n"
4826                        "37:    rep; movsb\n"
4827                        "100:\n"
4828 +                      "       pushl %%ss\n"
4829 +                      "       popl %%es\n"
4830                        ".section .fixup,\"ax\"\n"
4831                        "101:   lea 0(%%eax,%0,4),%0\n"
4832                        "       jmp 100b\n"
4833 @@ -326,7 +342,117 @@ __copy_user_intel(void __user *to, const
4834                        "       .long 99b,101b\n"
4835                        ".previous"
4836                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
4837 -                      :  "1"(to), "2"(from), "0"(size)
4838 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4839 +                      : "eax", "edx", "memory");
4840 +       return size;
4841 +}
4842 +
4843 +static unsigned long
4844 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
4845 +{
4846 +       int d0, d1;
4847 +       __asm__ __volatile__(
4848 +                      "       movw %w6, %%ds\n"
4849 +                      "       .align 2,0x90\n"
4850 +                      "1:     movl 32(%4), %%eax\n"
4851 +                      "       cmpl $67, %0\n"
4852 +                      "       jbe 3f\n"
4853 +                      "2:     movl 64(%4), %%eax\n"
4854 +                      "       .align 2,0x90\n"
4855 +                      "3:     movl 0(%4), %%eax\n"
4856 +                      "4:     movl 4(%4), %%edx\n"
4857 +                      "5:     movl %%eax, %%es:0(%3)\n"
4858 +                      "6:     movl %%edx, %%es:4(%3)\n"
4859 +                      "7:     movl 8(%4), %%eax\n"
4860 +                      "8:     movl 12(%4),%%edx\n"
4861 +                      "9:     movl %%eax, %%es:8(%3)\n"
4862 +                      "10:    movl %%edx, %%es:12(%3)\n"
4863 +                      "11:    movl 16(%4), %%eax\n"
4864 +                      "12:    movl 20(%4), %%edx\n"
4865 +                      "13:    movl %%eax, %%es:16(%3)\n"
4866 +                      "14:    movl %%edx, %%es:20(%3)\n"
4867 +                      "15:    movl 24(%4), %%eax\n"
4868 +                      "16:    movl 28(%4), %%edx\n"
4869 +                      "17:    movl %%eax, %%es:24(%3)\n"
4870 +                      "18:    movl %%edx, %%es:28(%3)\n"
4871 +                      "19:    movl 32(%4), %%eax\n"
4872 +                      "20:    movl 36(%4), %%edx\n"
4873 +                      "21:    movl %%eax, %%es:32(%3)\n"
4874 +                      "22:    movl %%edx, %%es:36(%3)\n"
4875 +                      "23:    movl 40(%4), %%eax\n"
4876 +                      "24:    movl 44(%4), %%edx\n"
4877 +                      "25:    movl %%eax, %%es:40(%3)\n"
4878 +                      "26:    movl %%edx, %%es:44(%3)\n"
4879 +                      "27:    movl 48(%4), %%eax\n"
4880 +                      "28:    movl 52(%4), %%edx\n"
4881 +                      "29:    movl %%eax, %%es:48(%3)\n"
4882 +                      "30:    movl %%edx, %%es:52(%3)\n"
4883 +                      "31:    movl 56(%4), %%eax\n"
4884 +                      "32:    movl 60(%4), %%edx\n"
4885 +                      "33:    movl %%eax, %%es:56(%3)\n"
4886 +                      "34:    movl %%edx, %%es:60(%3)\n"
4887 +                      "       addl $-64, %0\n"
4888 +                      "       addl $64, %4\n"
4889 +                      "       addl $64, %3\n"
4890 +                      "       cmpl $63, %0\n"
4891 +                      "       ja  1b\n"
4892 +                      "35:    movl  %0, %%eax\n"
4893 +                      "       shrl  $2, %0\n"
4894 +                      "       andl  $3, %%eax\n"
4895 +                      "       cld\n"
4896 +                      "99:    rep; movsl\n"
4897 +                      "36:    movl %%eax, %0\n"
4898 +                      "37:    rep; movsb\n"
4899 +                      "100:\n"
4900 +                      "       pushl %%ss\n"
4901 +                      "       popl %%ds\n"
4902 +                      ".section .fixup,\"ax\"\n"
4903 +                      "101:   lea 0(%%eax,%0,4),%0\n"
4904 +                      "       jmp 100b\n"
4905 +                      ".previous\n"
4906 +                      ".section __ex_table,\"a\"\n"
4907 +                      "       .align 4\n"
4908 +                      "       .long 1b,100b\n"
4909 +                      "       .long 2b,100b\n"
4910 +                      "       .long 3b,100b\n"
4911 +                      "       .long 4b,100b\n"
4912 +                      "       .long 5b,100b\n"
4913 +                      "       .long 6b,100b\n"
4914 +                      "       .long 7b,100b\n"
4915 +                      "       .long 8b,100b\n"
4916 +                      "       .long 9b,100b\n"
4917 +                      "       .long 10b,100b\n"
4918 +                      "       .long 11b,100b\n"
4919 +                      "       .long 12b,100b\n"
4920 +                      "       .long 13b,100b\n"
4921 +                      "       .long 14b,100b\n"
4922 +                      "       .long 15b,100b\n"
4923 +                      "       .long 16b,100b\n"
4924 +                      "       .long 17b,100b\n"
4925 +                      "       .long 18b,100b\n"
4926 +                      "       .long 19b,100b\n"
4927 +                      "       .long 20b,100b\n"
4928 +                      "       .long 21b,100b\n"
4929 +                      "       .long 22b,100b\n"
4930 +                      "       .long 23b,100b\n"
4931 +                      "       .long 24b,100b\n"
4932 +                      "       .long 25b,100b\n"
4933 +                      "       .long 26b,100b\n"
4934 +                      "       .long 27b,100b\n"
4935 +                      "       .long 28b,100b\n"
4936 +                      "       .long 29b,100b\n"
4937 +                      "       .long 30b,100b\n"
4938 +                      "       .long 31b,100b\n"
4939 +                      "       .long 32b,100b\n"
4940 +                      "       .long 33b,100b\n"
4941 +                      "       .long 34b,100b\n"
4942 +                      "       .long 35b,100b\n"
4943 +                      "       .long 36b,100b\n"
4944 +                      "       .long 37b,100b\n"
4945 +                      "       .long 99b,101b\n"
4946 +                      ".previous"
4947 +                      : "=&c"(size), "=&D" (d0), "=&S" (d1)
4948 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
4949                        : "eax", "edx", "memory");
4950         return size;
4951  }
4952 @@ -336,6 +462,7 @@ __copy_user_zeroing_intel(void *to, cons
4953  {
4954         int d0, d1;
4955         __asm__ __volatile__(
4956 +                      "        movw %w6, %%ds\n"
4957                        "        .align 2,0x90\n"
4958                        "0:      movl 32(%4), %%eax\n"
4959                        "        cmpl $67, %0\n"      
4960 @@ -344,36 +471,36 @@ __copy_user_zeroing_intel(void *to, cons
4961                        "        .align 2,0x90\n"     
4962                        "2:      movl 0(%4), %%eax\n" 
4963                        "21:     movl 4(%4), %%edx\n" 
4964 -                      "        movl %%eax, 0(%3)\n" 
4965 -                      "        movl %%edx, 4(%3)\n" 
4966 +                      "        movl %%eax, %%es:0(%3)\n" 
4967 +                      "        movl %%edx, %%es:4(%3)\n" 
4968                        "3:      movl 8(%4), %%eax\n" 
4969                        "31:     movl 12(%4),%%edx\n" 
4970 -                      "        movl %%eax, 8(%3)\n" 
4971 -                      "        movl %%edx, 12(%3)\n"
4972 +                      "        movl %%eax, %%es:8(%3)\n" 
4973 +                      "        movl %%edx, %%es:12(%3)\n"
4974                        "4:      movl 16(%4), %%eax\n"
4975                        "41:     movl 20(%4), %%edx\n"
4976 -                      "        movl %%eax, 16(%3)\n"
4977 -                      "        movl %%edx, 20(%3)\n"
4978 +                      "        movl %%eax, %%es:16(%3)\n"
4979 +                      "        movl %%edx, %%es:20(%3)\n"
4980                        "10:     movl 24(%4), %%eax\n"
4981                        "51:     movl 28(%4), %%edx\n"
4982 -                      "        movl %%eax, 24(%3)\n"
4983 -                      "        movl %%edx, 28(%3)\n"
4984 +                      "        movl %%eax, %%es:24(%3)\n"
4985 +                      "        movl %%edx, %%es:28(%3)\n"
4986                        "11:     movl 32(%4), %%eax\n"
4987                        "61:     movl 36(%4), %%edx\n"
4988 -                      "        movl %%eax, 32(%3)\n"
4989 -                      "        movl %%edx, 36(%3)\n"
4990 +                      "        movl %%eax, %%es:32(%3)\n"
4991 +                      "        movl %%edx, %%es:36(%3)\n"
4992                        "12:     movl 40(%4), %%eax\n"
4993                        "71:     movl 44(%4), %%edx\n"
4994 -                      "        movl %%eax, 40(%3)\n"
4995 -                      "        movl %%edx, 44(%3)\n"
4996 +                      "        movl %%eax, %%es:40(%3)\n"
4997 +                      "        movl %%edx, %%es:44(%3)\n"
4998                        "13:     movl 48(%4), %%eax\n"
4999                        "81:     movl 52(%4), %%edx\n"
5000 -                      "        movl %%eax, 48(%3)\n"
5001 -                      "        movl %%edx, 52(%3)\n"
5002 +                      "        movl %%eax, %%es:48(%3)\n"
5003 +                      "        movl %%edx, %%es:52(%3)\n"
5004                        "14:     movl 56(%4), %%eax\n"
5005                        "91:     movl 60(%4), %%edx\n"
5006 -                      "        movl %%eax, 56(%3)\n"
5007 -                      "        movl %%edx, 60(%3)\n"
5008 +                      "        movl %%eax, %%es:56(%3)\n"
5009 +                      "        movl %%edx, %%es:60(%3)\n"
5010                        "        addl $-64, %0\n"     
5011                        "        addl $64, %4\n"      
5012                        "        addl $64, %3\n"      
5013 @@ -387,6 +514,8 @@ __copy_user_zeroing_intel(void *to, cons
5014                        "        movl %%eax,%0\n"
5015                        "7:      rep; movsb\n"   
5016                        "8:\n"                   
5017 +                      "        pushl %%ss\n"
5018 +                      "        popl %%ds\n"
5019                        ".section .fixup,\"ax\"\n"
5020                        "9:      lea 0(%%eax,%0,4),%0\n" 
5021                        "16:     pushl %0\n"     
5022 @@ -421,7 +550,7 @@ __copy_user_zeroing_intel(void *to, cons
5023                        "        .long 7b,16b\n" 
5024                        ".previous"              
5025                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
5026 -                      :  "1"(to), "2"(from), "0"(size)
5027 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5028                        : "eax", "edx", "memory");
5029         return size;
5030  }
5031 @@ -437,6 +566,7 @@ static unsigned long __copy_user_zeroing
5032          int d0, d1;
5033  
5034         __asm__ __volatile__(
5035 +              "        movw %w6, %%ds\n"
5036                "        .align 2,0x90\n"
5037                "0:      movl 32(%4), %%eax\n"
5038                "        cmpl $67, %0\n"
5039 @@ -445,36 +575,36 @@ static unsigned long __copy_user_zeroing
5040                "        .align 2,0x90\n"
5041                "2:      movl 0(%4), %%eax\n"
5042                "21:     movl 4(%4), %%edx\n"
5043 -              "        movnti %%eax, 0(%3)\n"
5044 -              "        movnti %%edx, 4(%3)\n"
5045 +              "        movnti %%eax, %%es:0(%3)\n"
5046 +              "        movnti %%edx, %%es:4(%3)\n"
5047                "3:      movl 8(%4), %%eax\n"
5048                "31:     movl 12(%4),%%edx\n"
5049 -              "        movnti %%eax, 8(%3)\n"
5050 -              "        movnti %%edx, 12(%3)\n"
5051 +              "        movnti %%eax, %%es:8(%3)\n"
5052 +              "        movnti %%edx, %%es:12(%3)\n"
5053                "4:      movl 16(%4), %%eax\n"
5054                "41:     movl 20(%4), %%edx\n"
5055 -              "        movnti %%eax, 16(%3)\n"
5056 -              "        movnti %%edx, 20(%3)\n"
5057 +              "        movnti %%eax, %%es:16(%3)\n"
5058 +              "        movnti %%edx, %%es:20(%3)\n"
5059                "10:     movl 24(%4), %%eax\n"
5060                "51:     movl 28(%4), %%edx\n"
5061 -              "        movnti %%eax, 24(%3)\n"
5062 -              "        movnti %%edx, 28(%3)\n"
5063 +              "        movnti %%eax, %%es:24(%3)\n"
5064 +              "        movnti %%edx, %%es:28(%3)\n"
5065                "11:     movl 32(%4), %%eax\n"
5066                "61:     movl 36(%4), %%edx\n"
5067 -              "        movnti %%eax, 32(%3)\n"
5068 -              "        movnti %%edx, 36(%3)\n"
5069 +              "        movnti %%eax, %%es:32(%3)\n"
5070 +              "        movnti %%edx, %%es:36(%3)\n"
5071                "12:     movl 40(%4), %%eax\n"
5072                "71:     movl 44(%4), %%edx\n"
5073 -              "        movnti %%eax, 40(%3)\n"
5074 -              "        movnti %%edx, 44(%3)\n"
5075 +              "        movnti %%eax, %%es:40(%3)\n"
5076 +              "        movnti %%edx, %%es:44(%3)\n"
5077                "13:     movl 48(%4), %%eax\n"
5078                "81:     movl 52(%4), %%edx\n"
5079 -              "        movnti %%eax, 48(%3)\n"
5080 -              "        movnti %%edx, 52(%3)\n"
5081 +              "        movnti %%eax, %%es:48(%3)\n"
5082 +              "        movnti %%edx, %%es:52(%3)\n"
5083                "14:     movl 56(%4), %%eax\n"
5084                "91:     movl 60(%4), %%edx\n"
5085 -              "        movnti %%eax, 56(%3)\n"
5086 -              "        movnti %%edx, 60(%3)\n"
5087 +              "        movnti %%eax, %%es:56(%3)\n"
5088 +              "        movnti %%edx, %%es:60(%3)\n"
5089                "        addl $-64, %0\n"
5090                "        addl $64, %4\n"
5091                "        addl $64, %3\n"
5092 @@ -489,6 +619,8 @@ static unsigned long __copy_user_zeroing
5093                "        movl %%eax,%0\n"
5094                "7:      rep; movsb\n"
5095                "8:\n"
5096 +              "        pushl %%ss\n"
5097 +              "        popl %%ds\n"
5098                ".section .fixup,\"ax\"\n"
5099                "9:      lea 0(%%eax,%0,4),%0\n"
5100                "16:     pushl %0\n"
5101 @@ -523,7 +655,7 @@ static unsigned long __copy_user_zeroing
5102                "        .long 7b,16b\n"
5103                ".previous"
5104                : "=&c"(size), "=&D" (d0), "=&S" (d1)
5105 -              :  "1"(to), "2"(from), "0"(size)
5106 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5107                : "eax", "edx", "memory");
5108         return size;
5109  }
5110 @@ -534,6 +666,7 @@ static unsigned long __copy_user_intel_n
5111          int d0, d1;
5112  
5113         __asm__ __volatile__(
5114 +              "        movw %w6, %%ds\n"
5115                "        .align 2,0x90\n"
5116                "0:      movl 32(%4), %%eax\n"
5117                "        cmpl $67, %0\n"
5118 @@ -542,36 +675,36 @@ static unsigned long __copy_user_intel_n
5119                "        .align 2,0x90\n"
5120                "2:      movl 0(%4), %%eax\n"
5121                "21:     movl 4(%4), %%edx\n"
5122 -              "        movnti %%eax, 0(%3)\n"
5123 -              "        movnti %%edx, 4(%3)\n"
5124 +              "        movnti %%eax, %%es:0(%3)\n"
5125 +              "        movnti %%edx, %%es:4(%3)\n"
5126                "3:      movl 8(%4), %%eax\n"
5127                "31:     movl 12(%4),%%edx\n"
5128 -              "        movnti %%eax, 8(%3)\n"
5129 -              "        movnti %%edx, 12(%3)\n"
5130 +              "        movnti %%eax, %%es:8(%3)\n"
5131 +              "        movnti %%edx, %%es:12(%3)\n"
5132                "4:      movl 16(%4), %%eax\n"
5133                "41:     movl 20(%4), %%edx\n"
5134 -              "        movnti %%eax, 16(%3)\n"
5135 -              "        movnti %%edx, 20(%3)\n"
5136 +              "        movnti %%eax, %%es:16(%3)\n"
5137 +              "        movnti %%edx, %%es:20(%3)\n"
5138                "10:     movl 24(%4), %%eax\n"
5139                "51:     movl 28(%4), %%edx\n"
5140 -              "        movnti %%eax, 24(%3)\n"
5141 -              "        movnti %%edx, 28(%3)\n"
5142 +              "        movnti %%eax, %%es:24(%3)\n"
5143 +              "        movnti %%edx, %%es:28(%3)\n"
5144                "11:     movl 32(%4), %%eax\n"
5145                "61:     movl 36(%4), %%edx\n"
5146 -              "        movnti %%eax, 32(%3)\n"
5147 -              "        movnti %%edx, 36(%3)\n"
5148 +              "        movnti %%eax, %%es:32(%3)\n"
5149 +              "        movnti %%edx, %%es:36(%3)\n"
5150                "12:     movl 40(%4), %%eax\n"
5151                "71:     movl 44(%4), %%edx\n"
5152 -              "        movnti %%eax, 40(%3)\n"
5153 -              "        movnti %%edx, 44(%3)\n"
5154 +              "        movnti %%eax, %%es:40(%3)\n"
5155 +              "        movnti %%edx, %%es:44(%3)\n"
5156                "13:     movl 48(%4), %%eax\n"
5157                "81:     movl 52(%4), %%edx\n"
5158 -              "        movnti %%eax, 48(%3)\n"
5159 -              "        movnti %%edx, 52(%3)\n"
5160 +              "        movnti %%eax, %%es:48(%3)\n"
5161 +              "        movnti %%edx, %%es:52(%3)\n"
5162                "14:     movl 56(%4), %%eax\n"
5163                "91:     movl 60(%4), %%edx\n"
5164 -              "        movnti %%eax, 56(%3)\n"
5165 -              "        movnti %%edx, 60(%3)\n"
5166 +              "        movnti %%eax, %%es:56(%3)\n"
5167 +              "        movnti %%edx, %%es:60(%3)\n"
5168                "        addl $-64, %0\n"
5169                "        addl $64, %4\n"
5170                "        addl $64, %3\n"
5171 @@ -586,6 +719,8 @@ static unsigned long __copy_user_intel_n
5172                "        movl %%eax,%0\n"
5173                "7:      rep; movsb\n"
5174                "8:\n"
5175 +              "        pushl %%ss\n"
5176 +              "        popl %%ds\n"
5177                ".section .fixup,\"ax\"\n"
5178                "9:      lea 0(%%eax,%0,4),%0\n"
5179                "16:     jmp 8b\n"
5180 @@ -614,7 +749,7 @@ static unsigned long __copy_user_intel_n
5181                "        .long 7b,16b\n"
5182                ".previous"
5183                : "=&c"(size), "=&D" (d0), "=&S" (d1)
5184 -              :  "1"(to), "2"(from), "0"(size)
5185 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
5186                : "eax", "edx", "memory");
5187         return size;
5188  }
5189 @@ -627,90 +762,146 @@ static unsigned long __copy_user_intel_n
5190   */
5191  unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
5192                                         unsigned long size);
5193 -unsigned long __copy_user_intel(void __user *to, const void *from,
5194 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
5195 +                                       unsigned long size);
5196 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
5197                                         unsigned long size);
5198  unsigned long __copy_user_zeroing_intel_nocache(void *to,
5199                                 const void __user *from, unsigned long size);
5200  #endif /* CONFIG_X86_INTEL_USERCOPY */
5201  
5202  /* Generic arbitrary sized copy.  */
5203 -#define __copy_user(to,from,size)                                      \
5204 -do {                                                                   \
5205 -       int __d0, __d1, __d2;                                           \
5206 -       __asm__ __volatile__(                                           \
5207 -               "       cmp  $7,%0\n"                                   \
5208 -               "       jbe  1f\n"                                      \
5209 -               "       movl %1,%0\n"                                   \
5210 -               "       negl %0\n"                                      \
5211 -               "       andl $7,%0\n"                                   \
5212 -               "       subl %0,%3\n"                                   \
5213 -               "4:     rep; movsb\n"                                   \
5214 -               "       movl %3,%0\n"                                   \
5215 -               "       shrl $2,%0\n"                                   \
5216 -               "       andl $3,%3\n"                                   \
5217 -               "       .align 2,0x90\n"                                \
5218 -               "0:     rep; movsl\n"                                   \
5219 -               "       movl %3,%0\n"                                   \
5220 -               "1:     rep; movsb\n"                                   \
5221 -               "2:\n"                                                  \
5222 -               ".section .fixup,\"ax\"\n"                              \
5223 -               "5:     addl %3,%0\n"                                   \
5224 -               "       jmp 2b\n"                                       \
5225 -               "3:     lea 0(%3,%0,4),%0\n"                            \
5226 -               "       jmp 2b\n"                                       \
5227 -               ".previous\n"                                           \
5228 -               ".section __ex_table,\"a\"\n"                           \
5229 -               "       .align 4\n"                                     \
5230 -               "       .long 4b,5b\n"                                  \
5231 -               "       .long 0b,3b\n"                                  \
5232 -               "       .long 1b,2b\n"                                  \
5233 -               ".previous"                                             \
5234 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
5235 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
5236 -               : "memory");                                            \
5237 -} while (0)
5238 -
5239 -#define __copy_user_zeroing(to,from,size)                              \
5240 -do {                                                                   \
5241 -       int __d0, __d1, __d2;                                           \
5242 -       __asm__ __volatile__(                                           \
5243 -               "       cmp  $7,%0\n"                                   \
5244 -               "       jbe  1f\n"                                      \
5245 -               "       movl %1,%0\n"                                   \
5246 -               "       negl %0\n"                                      \
5247 -               "       andl $7,%0\n"                                   \
5248 -               "       subl %0,%3\n"                                   \
5249 -               "4:     rep; movsb\n"                                   \
5250 -               "       movl %3,%0\n"                                   \
5251 -               "       shrl $2,%0\n"                                   \
5252 -               "       andl $3,%3\n"                                   \
5253 -               "       .align 2,0x90\n"                                \
5254 -               "0:     rep; movsl\n"                                   \
5255 -               "       movl %3,%0\n"                                   \
5256 -               "1:     rep; movsb\n"                                   \
5257 -               "2:\n"                                                  \
5258 -               ".section .fixup,\"ax\"\n"                              \
5259 -               "5:     addl %3,%0\n"                                   \
5260 -               "       jmp 6f\n"                                       \
5261 -               "3:     lea 0(%3,%0,4),%0\n"                            \
5262 -               "6:     pushl %0\n"                                     \
5263 -               "       pushl %%eax\n"                                  \
5264 -               "       xorl %%eax,%%eax\n"                             \
5265 -               "       rep; stosb\n"                                   \
5266 -               "       popl %%eax\n"                                   \
5267 -               "       popl %0\n"                                      \
5268 -               "       jmp 2b\n"                                       \
5269 -               ".previous\n"                                           \
5270 -               ".section __ex_table,\"a\"\n"                           \
5271 -               "       .align 4\n"                                     \
5272 -               "       .long 4b,5b\n"                                  \
5273 -               "       .long 0b,3b\n"                                  \
5274 -               "       .long 1b,6b\n"                                  \
5275 -               ".previous"                                             \
5276 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
5277 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
5278 -               : "memory");                                            \
5279 -} while (0)
5280 +static unsigned long
5281 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
5282 +{
5283 +       int __d0, __d1, __d2;
5284 +
5285 +       __asm__ __volatile__(
5286 +               "       movw %w8,%%es\n"
5287 +               "       cmp  $7,%0\n"
5288 +               "       jbe  1f\n"
5289 +               "       movl %1,%0\n"
5290 +               "       negl %0\n"
5291 +               "       andl $7,%0\n"
5292 +               "       subl %0,%3\n"
5293 +               "4:     rep; movsb\n"
5294 +               "       movl %3,%0\n"
5295 +               "       shrl $2,%0\n"
5296 +               "       andl $3,%3\n"
5297 +               "       .align 2,0x90\n"
5298 +               "0:     rep; movsl\n"
5299 +               "       movl %3,%0\n"
5300 +               "1:     rep; movsb\n"
5301 +               "2:\n"
5302 +               "       pushl %%ss\n"
5303 +               "       popl %%es\n"
5304 +               ".section .fixup,\"ax\"\n"
5305 +               "5:     addl %3,%0\n"
5306 +               "       jmp 2b\n"
5307 +               "3:     lea 0(%3,%0,4),%0\n"
5308 +               "       jmp 2b\n"
5309 +               ".previous\n"
5310 +               ".section __ex_table,\"a\"\n"
5311 +               "       .align 4\n"
5312 +               "       .long 4b,5b\n"
5313 +               "       .long 0b,3b\n"
5314 +               "       .long 1b,2b\n"
5315 +               ".previous"
5316 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5317 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5318 +               : "memory");
5319 +       return size;
5320 +}
5321 +
5322 +static unsigned long
5323 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
5324 +{
5325 +       int __d0, __d1, __d2;
5326 +
5327 +       __asm__ __volatile__(
5328 +               "       movw %w8,%%ds\n"
5329 +               "       cmp  $7,%0\n"
5330 +               "       jbe  1f\n"
5331 +               "       movl %1,%0\n"
5332 +               "       negl %0\n"
5333 +               "       andl $7,%0\n"
5334 +               "       subl %0,%3\n"
5335 +               "4:     rep; movsb\n"
5336 +               "       movl %3,%0\n"
5337 +               "       shrl $2,%0\n"
5338 +               "       andl $3,%3\n"
5339 +               "       .align 2,0x90\n"
5340 +               "0:     rep; movsl\n"
5341 +               "       movl %3,%0\n"
5342 +               "1:     rep; movsb\n"
5343 +               "2:\n"
5344 +               "       pushl %%ss\n"
5345 +               "       popl %%ds\n"
5346 +               ".section .fixup,\"ax\"\n"
5347 +               "5:     addl %3,%0\n"
5348 +               "       jmp 2b\n"
5349 +               "3:     lea 0(%3,%0,4),%0\n"
5350 +               "       jmp 2b\n"
5351 +               ".previous\n"
5352 +               ".section __ex_table,\"a\"\n"
5353 +               "       .align 4\n"
5354 +               "       .long 4b,5b\n"
5355 +               "       .long 0b,3b\n"
5356 +               "       .long 1b,2b\n"
5357 +               ".previous"
5358 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5359 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5360 +               : "memory");
5361 +       return size;
5362 +}
5363 +
5364 +static unsigned long
5365 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
5366 +{
5367 +       int __d0, __d1, __d2;
5368 +
5369 +       __asm__ __volatile__(
5370 +               "       movw %w8,%%ds\n"
5371 +               "       cmp  $7,%0\n"
5372 +               "       jbe  1f\n"
5373 +               "       movl %1,%0\n"
5374 +               "       negl %0\n"
5375 +               "       andl $7,%0\n"
5376 +               "       subl %0,%3\n"
5377 +               "4:     rep; movsb\n"
5378 +               "       movl %3,%0\n"
5379 +               "       shrl $2,%0\n"
5380 +               "       andl $3,%3\n"
5381 +               "       .align 2,0x90\n"
5382 +               "0:     rep; movsl\n"
5383 +               "       movl %3,%0\n"
5384 +               "1:     rep; movsb\n"
5385 +               "2:\n"
5386 +               "       pushl %%ss\n"
5387 +               "       popl %%ds\n"
5388 +               ".section .fixup,\"ax\"\n"
5389 +               "5:     addl %3,%0\n"
5390 +               "       jmp 6f\n"
5391 +               "3:     lea 0(%3,%0,4),%0\n"
5392 +               "6:     pushl %0\n"
5393 +               "       pushl %%eax\n"
5394 +               "       xorl %%eax,%%eax\n"
5395 +               "       rep; stosb\n"
5396 +               "       popl %%eax\n"
5397 +               "       popl %0\n"
5398 +               "       jmp 2b\n"
5399 +               ".previous\n"
5400 +               ".section __ex_table,\"a\"\n"
5401 +               "       .align 4\n"
5402 +               "       .long 4b,5b\n"
5403 +               "       .long 0b,3b\n"
5404 +               "       .long 1b,6b\n"
5405 +               ".previous"
5406 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
5407 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
5408 +               : "memory");
5409 +       return size;
5410 +}
5411  
5412  unsigned long __copy_to_user_ll(void __user *to, const void *from,
5413                                 unsigned long n)
5414 @@ -766,9 +957,9 @@ survive:
5415         }
5416  #endif
5417         if (movsl_is_ok(to, from, n))
5418 -               __copy_user(to, from, n);
5419 +               n = __generic_copy_to_user(to, from, n);
5420         else
5421 -               n = __copy_user_intel(to, from, n);
5422 +               n = __generic_copy_to_user_intel(to, from, n);
5423         return n;
5424  }
5425  EXPORT_SYMBOL(__copy_to_user_ll);
5426 @@ -778,7 +969,7 @@ unsigned long __copy_from_user_ll(void *
5427  {
5428         BUG_ON((long)n < 0);
5429         if (movsl_is_ok(to, from, n))
5430 -               __copy_user_zeroing(to, from, n);
5431 +               n = __copy_user_zeroing(to, from, n);
5432         else
5433                 n = __copy_user_zeroing_intel(to, from, n);
5434         return n;
5435 @@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
5436  {
5437         BUG_ON((long)n < 0);
5438         if (movsl_is_ok(to, from, n))
5439 -               __copy_user(to, from, n);
5440 +               n = __generic_copy_from_user(to, from, n);
5441         else
5442 -               n = __copy_user_intel((void __user *)to,
5443 -                                     (const void *)from, n);
5444 +               n = __generic_copy_from_user_intel(to, from, n);
5445         return n;
5446  }
5447  EXPORT_SYMBOL(__copy_from_user_ll_nozero);
5448 @@ -804,11 +994,11 @@ unsigned long __copy_from_user_ll_nocach
5449         BUG_ON((long)n < 0);
5450  #ifdef CONFIG_X86_INTEL_USERCOPY
5451         if ( n > 64 && cpu_has_xmm2)
5452 -                n = __copy_user_zeroing_intel_nocache(to, from, n);
5453 +               n = __copy_user_zeroing_intel_nocache(to, from, n);
5454         else
5455 -               __copy_user_zeroing(to, from, n);
5456 +               n = __copy_user_zeroing(to, from, n);
5457  #else
5458 -        __copy_user_zeroing(to, from, n);
5459 +       n = __copy_user_zeroing(to, from, n);
5460  #endif
5461         return n;
5462  }
5463 @@ -819,11 +1009,11 @@ unsigned long __copy_from_user_ll_nocach
5464         BUG_ON((long)n < 0);
5465  #ifdef CONFIG_X86_INTEL_USERCOPY
5466         if ( n > 64 && cpu_has_xmm2)
5467 -                n = __copy_user_intel_nocache(to, from, n);
5468 +               n = __copy_user_intel_nocache(to, from, n);
5469         else
5470 -               __copy_user(to, from, n);
5471 +               n = __generic_copy_from_user(to, from, n);
5472  #else
5473 -        __copy_user(to, from, n);
5474 +       n = __generic_copy_from_user(to, from, n);
5475  #endif
5476         return n;
5477  }
5478 @@ -878,3 +1068,31 @@ copy_from_user(void *to, const void __us
5479         return n;
5480  }
5481  EXPORT_SYMBOL(copy_from_user);
5482 +
5483 +#ifdef CONFIG_PAX_MEMORY_UDEREF
5484 +void __set_fs(mm_segment_t x, int cpu)
5485 +{
5486 +       unsigned long limit = x.seg;
5487 +       __u32 a, b;
5488 +
5489 +       current_thread_info()->addr_limit = x;
5490 +       if (likely(limit))
5491 +               limit -= 1UL;
5492 +
5493 +       pack_descriptor(&a, &b, 0UL, limit, 0xF3, 0xC);
5494 +       write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, a, b);
5495 +}
5496 +
5497 +void set_fs(mm_segment_t x)
5498 +{
5499 +       __set_fs(x, get_cpu());
5500 +       put_cpu_no_resched();
5501 +}
5502 +#else
5503 +void set_fs(mm_segment_t x)
5504 +{
5505 +       current_thread_info()->addr_limit = x;
5506 +}
5507 +#endif
5508 +
5509 +EXPORT_SYMBOL(set_fs);
5510 diff -urNp linux-2.6.20.3/arch/i386/mach-default/setup.c linux-2.6.20.3/arch/i386/mach-default/setup.c
5511 --- linux-2.6.20.3/arch/i386/mach-default/setup.c       2007-03-13 14:27:08.000000000 -0400
5512 +++ linux-2.6.20.3/arch/i386/mach-default/setup.c       2007-03-23 08:10:06.000000000 -0400
5513 @@ -35,7 +35,7 @@ void __init pre_intr_init_hook(void)
5514  /*
5515   * IRQ2 is cascade interrupt to second interrupt controller
5516   */
5517 -static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL};
5518 +static struct irqaction irq2 = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL, 0, NULL};
5519  
5520  /**
5521   * intr_init_hook - post gate setup interrupt initialisation
5522 @@ -79,7 +79,7 @@ void __init trap_init_hook(void)
5523  {
5524  }
5525  
5526 -static struct irqaction irq0  = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL};
5527 +static struct irqaction irq0  = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL, 0, NULL};
5528  
5529  /**
5530   * time_init_hook - do any specific initialisations for the system timer.
5531 diff -urNp linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c
5532 --- linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c 2007-03-13 14:27:08.000000000 -0400
5533 +++ linux-2.6.20.3/arch/i386/mach-voyager/voyager_smp.c 2007-03-23 08:10:06.000000000 -0400
5534 @@ -583,11 +583,7 @@ do_boot_cpu(__u8 cpu)
5535         /* Pre-allocate and initialize the CPU's GDT and PDA so it
5536            doesn't have to do any memory allocation during the
5537            delicate CPU-bringup phase. */
5538 -       if (!init_gdt(cpu, idle)) {
5539 -               printk(KERN_INFO "Couldn't allocate GDT/PDA for CPU %d\n", cpu);
5540 -               cpucount--;
5541 -               return;
5542 -       }
5543 +       init_gdt(cpu, idle);
5544  
5545         irq_ctx_init(cpu);
5546  
5547 @@ -1322,7 +1318,7 @@ smp_local_timer_interrupt(void)
5548                                                 per_cpu(prof_counter, cpu);
5549                 }
5550  
5551 -               update_process_times(user_mode_vm(get_irq_regs()));
5552 +               update_process_times(user_mode(get_irq_regs()));
5553         }
5554  
5555         if( ((1<<cpu) & voyager_extended_vic_processors) == 0)
5556 diff -urNp linux-2.6.20.3/arch/i386/mm/boot_ioremap.c linux-2.6.20.3/arch/i386/mm/boot_ioremap.c
5557 --- linux-2.6.20.3/arch/i386/mm/boot_ioremap.c  2007-03-13 14:27:08.000000000 -0400
5558 +++ linux-2.6.20.3/arch/i386/mm/boot_ioremap.c  2007-03-23 08:10:06.000000000 -0400
5559 @@ -7,15 +7,6 @@
5560   * Written by Dave Hansen <haveblue@us.ibm.com>
5561   */
5562  
5563 -
5564 -/*
5565 - * We need to use the 2-level pagetable functions, but CONFIG_X86_PAE
5566 - * keeps that from happenning.  If anyone has a better way, I'm listening.
5567 - *
5568 - * boot_pte_t is defined only if this all works correctly
5569 - */
5570 -
5571 -#undef CONFIG_X86_PAE
5572  #undef CONFIG_PARAVIRT
5573  #include <asm/page.h>
5574  #include <asm/pgtable.h>
5575 @@ -23,41 +14,29 @@
5576  #include <linux/init.h>
5577  #include <linux/stddef.h>
5578  
5579 -/* 
5580 - * I'm cheating here.  It is known that the two boot PTE pages are 
5581 - * allocated next to each other.  I'm pretending that they're just
5582 - * one big array. 
5583 - */
5584 -
5585 -#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
5586 -
5587 -static unsigned long boot_pte_index(unsigned long vaddr) 
5588 -{
5589 -       return __pa(vaddr) >> PAGE_SHIFT;
5590 -}
5591 -
5592 -static inline boot_pte_t* boot_vaddr_to_pte(void *address)
5593 -{
5594 -       boot_pte_t* boot_pg = (boot_pte_t*)pg0;
5595 -       return &boot_pg[boot_pte_index((unsigned long)address)];
5596 -}
5597 -
5598  /*
5599   * This is only for a caller who is clever enough to page-align
5600   * phys_addr and virtual_source, and who also has a preference
5601   * about which virtual address from which to steal ptes
5602   */
5603 -static void __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
5604 -                   void* virtual_source)
5605 +static void __init __boot_ioremap(unsigned long phys_addr, unsigned long nrpages, 
5606 +                   char* virtual_source)
5607  {
5608 -       boot_pte_t* pte;
5609 -       int i;
5610 -       char *vaddr = virtual_source;
5611 +       pgd_t *pgd;
5612 +       pud_t *pud;
5613 +       pmd_t *pmd;
5614 +       pte_t* pte;
5615 +       unsigned int i;
5616 +       unsigned long vaddr = (unsigned long)virtual_source;
5617 +
5618 +       pgd = pgd_offset_k(vaddr);
5619 +       pud = pud_offset(pgd, vaddr);
5620 +       pmd = pmd_offset(pud, vaddr);
5621 +       pte = pte_offset_kernel(pmd, vaddr);
5622  
5623 -       pte = boot_vaddr_to_pte(virtual_source);
5624         for (i=0; i < nrpages; i++, phys_addr += PAGE_SIZE, pte++) {
5625                 set_pte(pte, pfn_pte(phys_addr>>PAGE_SHIFT, PAGE_KERNEL));
5626 -               __flush_tlb_one(&vaddr[i*PAGE_SIZE]);
5627 +               __flush_tlb_one(&virtual_source[i*PAGE_SIZE]);
5628         }
5629  }
5630  
5631 diff -urNp linux-2.6.20.3/arch/i386/mm/extable.c linux-2.6.20.3/arch/i386/mm/extable.c
5632 --- linux-2.6.20.3/arch/i386/mm/extable.c       2007-03-13 14:27:08.000000000 -0400
5633 +++ linux-2.6.20.3/arch/i386/mm/extable.c       2007-03-23 08:10:06.000000000 -0400
5634 @@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs
5635         const struct exception_table_entry *fixup;
5636  
5637  #ifdef CONFIG_PNPBIOS
5638 -       if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
5639 +       if (unlikely(!(regs->eflags & VM_MASK) && SEGMENT_IS_PNP_CODE(regs->xcs)))
5640         {
5641                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
5642                 extern u32 pnp_bios_is_utter_crap;
5643 diff -urNp linux-2.6.20.3/arch/i386/mm/fault.c linux-2.6.20.3/arch/i386/mm/fault.c
5644 --- linux-2.6.20.3/arch/i386/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
5645 +++ linux-2.6.20.3/arch/i386/mm/fault.c 2007-03-23 08:32:22.000000000 -0400
5646 @@ -23,11 +23,15 @@
5647  #include <linux/kprobes.h>
5648  #include <linux/uaccess.h>
5649  #include <linux/suspend.h>
5650 +#include <linux/unistd.h>
5651 +#include <linux/compiler.h>
5652 +#include <linux/binfmts.h>
5653  
5654  #include <asm/system.h>
5655  #include <asm/desc.h>
5656  #include <asm/kdebug.h>
5657  #include <asm/segment.h>
5658 +#include <asm/tlbflush.h>
5659  
5660  extern void die(const char *,struct pt_regs *,long);
5661  
5662 @@ -104,7 +108,8 @@ static inline unsigned long get_segment_
5663  {
5664         unsigned long eip = regs->eip;
5665         unsigned seg = regs->xcs & 0xffff;
5666 -       u32 seg_ar, seg_limit, base, *desc;
5667 +       u32 seg_ar, seg_limit, base;
5668 +       struct desc_struct *desc;
5669  
5670         /* Unlikely, but must come before segment checks. */
5671         if (unlikely(regs->eflags & VM_MASK)) {
5672 @@ -118,7 +123,7 @@ static inline unsigned long get_segment_
5673         
5674         /* By far the most common cases. */
5675         if (likely(SEGMENT_IS_FLAT_CODE(seg)))
5676 -               return eip;
5677 +               return eip + (seg == __KERNEL_CS ? __KERNEL_TEXT_OFFSET : 0);
5678  
5679         /* Check the segment exists, is within the current LDT/GDT size,
5680            that kernel/user (ring 0..3) has the appropriate privilege,
5681 @@ -136,16 +140,14 @@ static inline unsigned long get_segment_
5682         if (seg & (1<<2)) {
5683                 /* Must lock the LDT while reading it. */
5684                 down(&current->mm->context.sem);
5685 -               desc = current->mm->context.ldt;
5686 -               desc = (void *)desc + (seg & ~7);
5687 +               desc = &current->mm->context.ldt[seg >> 3];
5688         } else {
5689                 /* Must disable preemption while reading the GDT. */
5690 -               desc = (u32 *)get_cpu_gdt_table(get_cpu());
5691 -               desc = (void *)desc + (seg & ~7);
5692 +               desc = &get_cpu_gdt_table(get_cpu())[seg >> 3];
5693         }
5694  
5695         /* Decode the code segment base from the descriptor */
5696 -       base = get_desc_base((unsigned long *)desc);
5697 +       base = get_desc_base(desc);
5698  
5699         if (seg & (1<<2)) { 
5700                 up(&current->mm->context.sem);
5701 @@ -246,6 +248,30 @@ static noinline void force_sig_info_faul
5702  
5703  fastcall void do_invalid_op(struct pt_regs *, unsigned long);
5704  
5705 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5706 +static int pax_handle_fetch_fault(struct pt_regs *regs);
5707 +#endif
5708 +
5709 +#ifdef CONFIG_PAX_PAGEEXEC
5710 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
5711 +{
5712 +       pgd_t *pgd;
5713 +       pud_t *pud;
5714 +       pmd_t *pmd;
5715 +
5716 +       pgd = pgd_offset(mm, address);
5717 +       if (!pgd_present(*pgd))
5718 +               return NULL;
5719 +       pud = pud_offset(pgd, address);
5720 +       if (!pud_present(*pud))
5721 +               return NULL;
5722 +       pmd = pmd_offset(pud, address);
5723 +       if (!pmd_present(*pmd))
5724 +               return NULL;
5725 +       return pmd;
5726 +}
5727 +#endif
5728 +
5729  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
5730  {
5731         unsigned index = pgd_index(address);
5732 @@ -326,14 +352,20 @@ fastcall void __kprobes do_page_fault(st
5733         struct task_struct *tsk;
5734         struct mm_struct *mm;
5735         struct vm_area_struct * vma;
5736 -       unsigned long address;
5737 -       unsigned long page;
5738         int write, si_code;
5739  
5740 +#ifdef CONFIG_PAX_PAGEEXEC
5741 +       pmd_t *pmd;
5742 +       pte_t *pte;
5743 +       spinlock_t *ptl;
5744 +       unsigned char pte_mask;
5745 +#endif
5746 +
5747         /* get the address */
5748 -        address = read_cr2();
5749 +       const unsigned long address = read_cr2();
5750  
5751         tsk = current;
5752 +       mm = tsk->mm;
5753  
5754         si_code = SEGV_MAPERR;
5755  
5756 @@ -372,14 +404,12 @@ fastcall void __kprobes do_page_fault(st
5757         if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
5758                 local_irq_enable();
5759  
5760 -       mm = tsk->mm;
5761 -
5762         /*
5763          * If we're in an interrupt, have no user context or are running in an
5764          * atomic region then we must not take the fault..
5765          */
5766         if (in_atomic() || !mm)
5767 -               goto bad_area_nosemaphore;
5768 +               goto bad_area_nopax;
5769  
5770         /* When running in the kernel we expect faults to occur only to
5771          * addresses in user space.  All other faults represent errors in the
5772 @@ -399,10 +429,101 @@ fastcall void __kprobes do_page_fault(st
5773         if (!down_read_trylock(&mm->mmap_sem)) {
5774                 if ((error_code & 4) == 0 &&
5775                     !search_exception_tables(regs->eip))
5776 -                       goto bad_area_nosemaphore;
5777 +                       goto bad_area_nopax;
5778                 down_read(&mm->mmap_sem);
5779         }
5780  
5781 +#ifdef CONFIG_PAX_PAGEEXEC
5782 +       if (unlikely((error_code & 5) != 5 ||
5783 +                    (regs->eflags & X86_EFLAGS_VM) ||
5784 +                    !(mm->pax_flags & MF_PAX_PAGEEXEC)))
5785 +               goto not_pax_fault;
5786 +
5787 +       /* PaX: it's our fault, let's handle it if we can */
5788 +
5789 +       /* PaX: take a look at read faults before acquiring any locks */
5790 +       if (unlikely(!(error_code & 2) && (regs->eip == address))) {
5791 +               /* instruction fetch attempt from a protected page in user mode */
5792 +               up_read(&mm->mmap_sem);
5793 +
5794 +#ifdef CONFIG_PAX_EMUTRAMP
5795 +               switch (pax_handle_fetch_fault(regs)) {
5796 +               case 2:
5797 +                       return;
5798 +               }
5799 +#endif
5800 +
5801 +               pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5802 +               do_exit(SIGKILL);
5803 +       }
5804 +
5805 +       pmd = pax_get_pmd(mm, address);
5806 +       if (unlikely(!pmd))
5807 +               goto not_pax_fault;
5808 +
5809 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
5810 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
5811 +               pte_unmap_unlock(pte, ptl);
5812 +               goto not_pax_fault;
5813 +       }
5814 +
5815 +       if (unlikely((error_code & 2) && !pte_write(*pte))) {
5816 +               /* write attempt to a protected page in user mode */
5817 +               pte_unmap_unlock(pte, ptl);
5818 +               goto not_pax_fault;
5819 +       }
5820 +
5821 +#ifdef CONFIG_SMP
5822 +       if (likely(address > get_limit(regs->xcs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
5823 +#else
5824 +       if (likely(address > get_limit(regs->xcs)))
5825 +#endif
5826 +       {
5827 +               set_pte(pte, pte_mkread(*pte));
5828 +               __flush_tlb_one(address);
5829 +               pte_unmap_unlock(pte, ptl);
5830 +               up_read(&mm->mmap_sem);
5831 +               return;
5832 +       }
5833 +
5834 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1));
5835 +
5836 +       /*
5837 +        * PaX: fill DTLB with user rights and retry
5838 +        */
5839 +       __asm__ __volatile__ (
5840 +               "movw %w4,%%ds\n"
5841 +               "orb %2,%%ss:(%1)\n"
5842 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
5843 +/*
5844 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
5845 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
5846 + * page fault when examined during a TLB load attempt. this is true not only
5847 + * for PTEs holding a non-present entry but also present entries that will
5848 + * raise a page fault (such as those set up by PaX, or the copy-on-write
5849 + * mechanism). in effect it means that we do *not* need to flush the TLBs
5850 + * for our target pages since their PTEs are simply not in the TLBs at all.
5851 +
5852 + * the best thing in omitting it is that we gain around 15-20% speed in the
5853 + * fast path of the page fault handler and can get rid of tracing since we
5854 + * can no longer flush unintended entries.
5855 + */
5856 +               "invlpg (%0)\n"
5857 +#endif
5858 +               "testb $0,(%0)\n"
5859 +               "xorb %3,%%ss:(%1)\n"
5860 +               "pushl %%ss\n"
5861 +               "popl %%ds\n"
5862 +               :
5863 +               : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
5864 +               : "memory", "cc");
5865 +       pte_unmap_unlock(pte, ptl);
5866 +       up_read(&mm->mmap_sem);
5867 +       return;
5868 +
5869 +not_pax_fault:
5870 +#endif
5871 +
5872         vma = find_vma(mm, address);
5873         if (!vma)
5874                 goto bad_area;
5875 @@ -420,6 +541,12 @@ fastcall void __kprobes do_page_fault(st
5876                 if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
5877                         goto bad_area;
5878         }
5879 +
5880 +#ifdef CONFIG_PAX_SEGMEXEC
5881 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
5882 +               goto bad_area;
5883 +#endif
5884 +
5885         if (expand_stack(vma, address))
5886                 goto bad_area;
5887  /*
5888 @@ -484,6 +611,36 @@ bad_area:
5889         up_read(&mm->mmap_sem);
5890  
5891  bad_area_nosemaphore:
5892 +
5893 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5894 +       if (mm && (error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) {
5895 +
5896 +#ifdef CONFIG_PAX_PAGEEXEC
5897 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) {
5898 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5899 +                       do_exit(SIGKILL);
5900 +               }
5901 +#endif
5902 +
5903 +#ifdef CONFIG_PAX_SEGMEXEC
5904 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) {
5905 +
5906 +#ifdef CONFIG_PAX_EMUTRAMP
5907 +                       switch (pax_handle_fetch_fault(regs)) {
5908 +                       case 2:
5909 +                               return;
5910 +                       }
5911 +#endif
5912 +
5913 +                       pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp);
5914 +                       do_exit(SIGKILL);
5915 +               }
5916 +#endif
5917 +
5918 +       }
5919 +#endif
5920 +
5921 +bad_area_nopax:
5922         /* User mode accesses just cause a SIGSEGV */
5923         if (error_code & 4) {
5924                 /* 
5925 @@ -508,7 +666,7 @@ bad_area_nosemaphore:
5926         if (boot_cpu_data.f00f_bug) {
5927                 unsigned long nr;
5928                 
5929 -               nr = (address - idt_descr.address) >> 3;
5930 +               nr = (address - (unsigned long)idt_descr.address) >> 3;
5931  
5932                 if (nr == 6) {
5933                         do_invalid_op(regs, 0);
5934 @@ -551,6 +709,22 @@ no_context:
5935                 if (address < PAGE_SIZE)
5936                         printk(KERN_ALERT "BUG: unable to handle kernel NULL "
5937                                         "pointer dereference");
5938 +
5939 +#ifdef CONFIG_PAX_KERNEXEC
5940 +#ifdef CONFIG_MODULES
5941 +               else if (init_mm.start_code <= address && address < (unsigned long)MODULES_END) {
5942 +#else
5943 +               else if (init_mm.start_code <= address && address < init_mm.end_code) {
5944 +#endif
5945 +                       if (tsk->signal->curr_ip)
5946 +                               printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5947 +                                        NIPQUAD(tsk->signal->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5948 +                       else
5949 +                               printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code",
5950 +                                        tsk->comm, tsk->pid, tsk->uid, tsk->euid);
5951 +               }
5952 +#endif
5953 +
5954                 else
5955                         printk(KERN_ALERT "BUG: unable to handle kernel paging"
5956                                         " request");
5957 @@ -558,24 +732,34 @@ no_context:
5958                 printk(KERN_ALERT " printing eip:\n");
5959                 printk("%08lx\n", regs->eip);
5960         }
5961 -       page = read_cr3();
5962 -       page = ((unsigned long *) __va(page))[address >> 22];
5963 -       if (oops_may_print())
5964 -               printk(KERN_ALERT "*pde = %08lx\n", page);
5965 -       /*
5966 -        * We must not directly access the pte in the highpte
5967 -        * case, the page table might be allocated in highmem.
5968 -        * And lets rather not kmap-atomic the pte, just in case
5969 -        * it's allocated already.
5970 -        */
5971 +
5972 +       if (oops_may_print()) {
5973 +               unsigned long index = pgd_index(address);
5974 +               pgd_t *pgd;
5975 +               pud_t *pud;
5976 +               pmd_t *pmd;
5977 +               pte_t *pte;
5978 +
5979 +               pgd = index + (pgd_t *)__va(read_cr3());
5980 +               printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd));
5981 +               if (pgd_present(*pgd)) {
5982 +                       pud = pud_offset(pgd, address);
5983 +                       pmd = pmd_offset(pud, address);
5984 +                       printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd));
5985 +                       /*
5986 +                        * We must not directly access the pte in the highpte
5987 +                        * case, the page table might be allocated in highmem.
5988 +                        * And lets rather not kmap-atomic the pte, just in case
5989 +                        * it's allocated already.
5990 +                        */
5991  #ifndef CONFIG_HIGHPTE
5992 -       if ((page & 1) && oops_may_print()) {
5993 -               page &= PAGE_MASK;
5994 -               address &= 0x003ff000;
5995 -               page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
5996 -               printk(KERN_ALERT "*pte = %08lx\n", page);
5997 -       }
5998 +                       if (pmd_present(*pmd) && !pmd_large(*pmd)) {
5999 +                               pte = pte_offset_kernel(pmd, address);
6000 +                               printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte));
6001 +                       }
6002  #endif
6003 +               }
6004 +       }
6005         tsk->thread.cr2 = address;
6006         tsk->thread.trap_no = 14;
6007         tsk->thread.error_code = error_code;
6008 @@ -653,3 +837,101 @@ void vmalloc_sync_all(void)
6009         }
6010  }
6011  #endif
6012 +
6013 +#ifdef CONFIG_PAX_EMUTRAMP
6014 +/*
6015 + * PaX: decide what to do with offenders (regs->eip = fault address)
6016 + *
6017 + * returns 1 when task should be killed
6018 + *         2 when gcc trampoline was detected
6019 + */
6020 +static int pax_handle_fetch_fault(struct pt_regs *regs)
6021 +{
6022 +
6023 +       static const unsigned char trans[8] = {6, 1, 2, 0, 13, 5, 3, 4};
6024 +       int err;
6025 +
6026 +       if (regs->eflags & X86_EFLAGS_VM)
6027 +               return 1;
6028 +
6029 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
6030 +               return 1;
6031 +
6032 +       do { /* PaX: gcc trampoline emulation #1 */
6033 +               unsigned char mov1, mov2;
6034 +               unsigned short jmp;
6035 +               unsigned long addr1, addr2;
6036 +
6037 +               err = get_user(mov1, (unsigned char __user *)regs->eip);
6038 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6039 +               err |= get_user(mov2, (unsigned char __user *)(regs->eip + 5));
6040 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6041 +               err |= get_user(jmp, (unsigned short __user *)(regs->eip + 10));
6042 +
6043 +               if (err)
6044 +                       break;
6045 +
6046 +               if ((mov1 & 0xF8) == 0xB8 &&
6047 +                   (mov2 & 0xF8) == 0xB8 &&
6048 +                   (mov1 & 0x07) != (mov2 & 0x07) &&
6049 +                   (jmp & 0xF8FF) == 0xE0FF &&
6050 +                   (mov2 & 0x07) == ((jmp>>8) & 0x07))
6051 +               {
6052 +                       ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1;
6053 +                       ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2;
6054 +                       regs->eip = addr2;
6055 +                       return 2;
6056 +               }
6057 +       } while (0);
6058 +
6059 +       do { /* PaX: gcc trampoline emulation #2 */
6060 +               unsigned char mov, jmp;
6061 +               unsigned long addr1, addr2;
6062 +
6063 +               err = get_user(mov, (unsigned char __user *)regs->eip);
6064 +               err |= get_user(addr1, (unsigned long __user *)(regs->eip + 1));
6065 +               err |= get_user(jmp, (unsigned char __user *)(regs->eip + 5));
6066 +               err |= get_user(addr2, (unsigned long __user *)(regs->eip + 6));
6067 +
6068 +               if (err)
6069 +                       break;
6070 +
6071 +               if ((mov & 0xF8) == 0xB8 &&
6072 +                   jmp == 0xE9)
6073 +               {
6074 +                       ((unsigned long *)regs)[trans[mov & 0x07]] = addr1;
6075 +                       regs->eip += addr2 + 10;
6076 +                       return 2;
6077 +               }
6078 +       } while (0);
6079 +
6080 +       return 1; /* PaX in action */
6081 +}
6082 +#endif
6083 +
6084 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6085 +void pax_report_insns(void *pc, void *sp)
6086 +{
6087 +       long i;
6088 +
6089 +       printk(KERN_ERR "PAX: bytes at PC: ");
6090 +       for (i = 0; i < 20; i++) {
6091 +               unsigned char c;
6092 +               if (get_user(c, (unsigned char __user *)pc+i))
6093 +                       printk("?? ");
6094 +               else
6095 +                       printk("%02x ", c);
6096 +       }
6097 +       printk("\n");
6098 +
6099 +       printk(KERN_ERR "PAX: bytes at SP-4: ");
6100 +       for (i = -1; i < 20; i++) {
6101 +               unsigned long c;
6102 +               if (get_user(c, (unsigned long __user *)sp+i))
6103 +                       printk("???????? ");
6104 +               else
6105 +                       printk("%08lx ", c);
6106 +       }
6107 +       printk("\n");
6108 +}
6109 +#endif
6110 diff -urNp linux-2.6.20.3/arch/i386/mm/hugetlbpage.c linux-2.6.20.3/arch/i386/mm/hugetlbpage.c
6111 --- linux-2.6.20.3/arch/i386/mm/hugetlbpage.c   2007-03-13 14:27:08.000000000 -0400
6112 +++ linux-2.6.20.3/arch/i386/mm/hugetlbpage.c   2007-03-23 08:10:06.000000000 -0400
6113 @@ -230,7 +230,12 @@ static unsigned long hugetlb_get_unmappe
6114  {
6115         struct mm_struct *mm = current->mm;
6116         struct vm_area_struct *vma;
6117 -       unsigned long start_addr;
6118 +       unsigned long start_addr, task_size = TASK_SIZE;
6119 +
6120 +#ifdef CONFIG_PAX_SEGMEXEC
6121 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6122 +               task_size = SEGMEXEC_TASK_SIZE;
6123 +#endif
6124  
6125         if (len > mm->cached_hole_size) {
6126                 start_addr = mm->free_area_cache;
6127 @@ -244,7 +249,7 @@ full_search:
6128  
6129         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6130                 /* At this point:  (!vma || addr < vma->vm_end). */
6131 -               if (TASK_SIZE - len < addr) {
6132 +               if (task_size - len < addr) {
6133                         /*
6134                          * Start a new search - just in case we missed
6135                          * some holes.
6136 @@ -272,9 +277,8 @@ static unsigned long hugetlb_get_unmappe
6137  {
6138         struct mm_struct *mm = current->mm;
6139         struct vm_area_struct *vma, *prev_vma;
6140 -       unsigned long base = mm->mmap_base, addr = addr0;
6141 +       unsigned long base = mm->mmap_base, addr;
6142         unsigned long largest_hole = mm->cached_hole_size;
6143 -       int first_time = 1;
6144  
6145         /* don't allow allocations above current base */
6146         if (mm->free_area_cache > base)
6147 @@ -284,7 +288,7 @@ static unsigned long hugetlb_get_unmappe
6148                 largest_hole = 0;
6149                 mm->free_area_cache  = base;
6150         }
6151 -try_again:
6152 +
6153         /* make sure it can fit in the remaining address space */
6154         if (mm->free_area_cache < len)
6155                 goto fail;
6156 @@ -326,16 +330,6 @@ try_again:
6157  
6158  fail:
6159         /*
6160 -        * if hint left us with no space for the requested
6161 -        * mapping then try again:
6162 -        */
6163 -       if (first_time) {
6164 -               mm->free_area_cache = base;
6165 -               largest_hole = 0;
6166 -               first_time = 0;
6167 -               goto try_again;
6168 -       }
6169 -       /*
6170          * A failed mmap() very likely causes application failure,
6171          * so fall back to the bottom-up function here. This scenario
6172          * can happen with large stack limits and large mmap()
6173 @@ -361,16 +355,23 @@ hugetlb_get_unmapped_area(struct file *f
6174  {
6175         struct mm_struct *mm = current->mm;
6176         struct vm_area_struct *vma;
6177 +       unsigned long task_size = TASK_SIZE;
6178  
6179         if (len & ~HPAGE_MASK)
6180                 return -EINVAL;
6181 -       if (len > TASK_SIZE)
6182 +
6183 +#ifdef CONFIG_PAX_SEGMEXEC
6184 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6185 +               task_size = SEGMEXEC_TASK_SIZE;
6186 +#endif
6187 +
6188 +       if (len > task_size || addr > task_size - len)
6189                 return -ENOMEM;
6190  
6191         if (addr) {
6192                 addr = ALIGN(addr, HPAGE_SIZE);
6193                 vma = find_vma(mm, addr);
6194 -               if (TASK_SIZE - len >= addr &&
6195 +               if (task_size - len >= addr &&
6196                     (!vma || addr + len <= vma->vm_start))
6197                         return addr;
6198         }
6199 diff -urNp linux-2.6.20.3/arch/i386/mm/init.c linux-2.6.20.3/arch/i386/mm/init.c
6200 --- linux-2.6.20.3/arch/i386/mm/init.c  2007-03-13 14:27:08.000000000 -0400
6201 +++ linux-2.6.20.3/arch/i386/mm/init.c  2007-03-23 08:10:06.000000000 -0400
6202 @@ -42,6 +42,7 @@
6203  #include <asm/tlb.h>
6204  #include <asm/tlbflush.h>
6205  #include <asm/sections.h>
6206 +#include <asm/desc.h>
6207  
6208  unsigned int __VMALLOC_RESERVE = 128 << 20;
6209  
6210 @@ -51,30 +52,6 @@ unsigned long highstart_pfn, highend_pfn
6211  static int noinline do_test_wp_bit(void);
6212  
6213  /*
6214 - * Creates a middle page table and puts a pointer to it in the
6215 - * given global directory entry. This only returns the gd entry
6216 - * in non-PAE compilation mode, since the middle layer is folded.
6217 - */
6218 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
6219 -{
6220 -       pud_t *pud;
6221 -       pmd_t *pmd_table;
6222 -               
6223 -#ifdef CONFIG_X86_PAE
6224 -       pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6225 -       set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
6226 -       pud = pud_offset(pgd, 0);
6227 -       if (pmd_table != pmd_offset(pud, 0)) 
6228 -               BUG();
6229 -#else
6230 -       pud = pud_offset(pgd, 0);
6231 -       pmd_table = pmd_offset(pud, 0);
6232 -#endif
6233 -
6234 -       return pmd_table;
6235 -}
6236 -
6237 -/*
6238   * Create a page table and place a pointer to it in a middle page
6239   * directory entry.
6240   */
6241 @@ -82,7 +59,11 @@ static pte_t * __init one_page_table_ini
6242  {
6243         if (pmd_none(*pmd)) {
6244                 pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
6245 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
6246 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
6247 +#else
6248                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
6249 +#endif
6250                 if (page_table != pte_offset_kernel(pmd, 0))
6251                         BUG();  
6252  
6253 @@ -117,8 +98,6 @@ static void __init page_table_range_init
6254         pgd = pgd_base + pgd_idx;
6255  
6256         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
6257 -               if (pgd_none(*pgd)) 
6258 -                       one_md_table_init(pgd);
6259                 pud = pud_offset(pgd, vaddr);
6260                 pmd = pmd_offset(pud, vaddr);
6261                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++, pmd_idx++) {
6262 @@ -131,11 +110,22 @@ static void __init page_table_range_init
6263         }
6264  }
6265  
6266 -static inline int is_kernel_text(unsigned long addr)
6267 +static inline int is_kernel_text(unsigned long start, unsigned long end)
6268  {
6269 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
6270 -               return 1;
6271 -       return 0;
6272 +       unsigned long etext;
6273 +
6274 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
6275 +       etext = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6276 +#else
6277 +       etext = (unsigned long)&_etext;
6278 +#endif
6279 +
6280 +       if ((start > etext + __KERNEL_TEXT_OFFSET ||
6281 +            end <= (unsigned long)_stext + __KERNEL_TEXT_OFFSET) &&
6282 +           (start > (unsigned long)_einittext + __KERNEL_TEXT_OFFSET ||
6283 +            end <= (unsigned long)_sinittext + __KERNEL_TEXT_OFFSET))
6284 +               return 0;
6285 +       return 1;
6286  }
6287  
6288  /*
6289 @@ -147,26 +137,24 @@ static void __init kernel_physical_mappi
6290  {
6291         unsigned long pfn;
6292         pgd_t *pgd;
6293 +       pud_t *pud;
6294         pmd_t *pmd;
6295         pte_t *pte;
6296 -       int pgd_idx, pmd_idx, pte_ofs;
6297 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
6298  
6299         pgd_idx = pgd_index(PAGE_OFFSET);
6300         pgd = pgd_base + pgd_idx;
6301         pfn = 0;
6302  
6303 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
6304 -               pmd = one_md_table_init(pgd);
6305 -               if (pfn >= max_low_pfn)
6306 -                       continue;
6307 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
6308 +               pud = pud_offset(pgd, 0);
6309 +               pmd = pmd_offset(pud, 0);
6310                 for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++, pmd_idx++) {
6311 -                       unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
6312 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
6313  
6314                         /* Map with big pages if possible, otherwise create normal page tables. */
6315                         if (cpu_has_pse) {
6316 -                               unsigned int address2 = (pfn + PTRS_PER_PTE - 1) * PAGE_SIZE + PAGE_OFFSET + PAGE_SIZE-1;
6317 -
6318 -                               if (is_kernel_text(address) || is_kernel_text(address2))
6319 +                               if (is_kernel_text(address, address + PMD_SIZE))
6320                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE_EXEC));
6321                                 else
6322                                         set_pmd(pmd, pfn_pmd(pfn, PAGE_KERNEL_LARGE));
6323 @@ -175,7 +163,7 @@ static void __init kernel_physical_mappi
6324                                 pte = one_page_table_init(pmd);
6325  
6326                                 for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE && pfn < max_low_pfn; pte++, pfn++, pte_ofs++) {
6327 -                                               if (is_kernel_text(address))
6328 +                                               if (is_kernel_text(address, address + PAGE_SIZE))
6329                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL_EXEC));
6330                                                 else
6331                                                         set_pte(pte, pfn_pte(pfn, PAGE_KERNEL));
6332 @@ -340,13 +328,6 @@ static void __init pagetable_init (void)
6333         unsigned long vaddr;
6334         pgd_t *pgd_base = swapper_pg_dir;
6335  
6336 -#ifdef CONFIG_X86_PAE
6337 -       int i;
6338 -       /* Init entries of the first-level page table to the zero page */
6339 -       for (i = 0; i < PTRS_PER_PGD; i++)
6340 -               set_pgd(pgd_base + i, __pgd(__pa(empty_zero_page) | _PAGE_PRESENT));
6341 -#endif
6342 -
6343         /* Enable PSE if available */
6344         if (cpu_has_pse) {
6345                 set_in_cr4(X86_CR4_PSE);
6346 @@ -370,17 +351,6 @@ static void __init pagetable_init (void)
6347         page_table_range_init(vaddr, 0, pgd_base);
6348  
6349         permanent_kmaps_init(pgd_base);
6350 -
6351 -#ifdef CONFIG_X86_PAE
6352 -       /*
6353 -        * Add low memory identity-mappings - SMP needs it when
6354 -        * starting up on an AP from real-mode. In the non-PAE
6355 -        * case we already have these mappings through head.S.
6356 -        * All user-space mappings are explicitly cleared after
6357 -        * SMP startup.
6358 -        */
6359 -       set_pgd(&pgd_base[0], pgd_base[USER_PTRS_PER_PGD]);
6360 -#endif
6361  }
6362  
6363  #if defined(CONFIG_SUSPEND_SHARED) || defined(CONFIG_ACPI_SLEEP)
6364 @@ -388,12 +358,12 @@ static void __init pagetable_init (void)
6365   * Swap suspend & friends need this for resume because things like the intel-agp
6366   * driver might have split up a kernel 4MB mapping.
6367   */
6368 -char __nosavedata swsusp_pg_dir[PAGE_SIZE]
6369 +pgd_t __nosavedata swsusp_pg_dir[PTRS_PER_PGD]
6370         __attribute__ ((aligned (PAGE_SIZE)));
6371  
6372  static inline void save_pg_dir(void)
6373  {
6374 -       memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
6375 +       clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
6376  }
6377  #else
6378  static inline void save_pg_dir(void)
6379 @@ -422,7 +392,6 @@ void zap_low_mappings (void)
6380         flush_tlb_all();
6381  }
6382  
6383 -static int disable_nx __initdata = 0;
6384  u64 __supported_pte_mask __read_mostly = ~_PAGE_NX;
6385  
6386  /*
6387 @@ -436,13 +405,10 @@ u64 __supported_pte_mask __read_mostly =
6388  static int __init noexec_setup(char *str)
6389  {
6390         if (!str || !strcmp(str, "on")) {
6391 -               if (cpu_has_nx) {
6392 -                       __supported_pte_mask |= _PAGE_NX;
6393 -                       disable_nx = 0;
6394 -               }
6395 +               if (cpu_has_nx)
6396 +                       nx_enabled = 1;
6397         } else if (!strcmp(str,"off")) {
6398 -               disable_nx = 1;
6399 -               __supported_pte_mask &= ~_PAGE_NX;
6400 +               nx_enabled = 0;
6401         } else
6402                 return -EINVAL;
6403  
6404 @@ -455,17 +421,13 @@ int nx_enabled = 0;
6405  
6406  static void __init set_nx(void)
6407  {
6408 -       unsigned int v[4], l, h;
6409 +       if (!nx_enabled && cpu_has_nx) {
6410 +               unsigned l, h;
6411  
6412 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
6413 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
6414 -               if ((v[3] & (1 << 20)) && !disable_nx) {
6415 -                       rdmsr(MSR_EFER, l, h);
6416 -                       l |= EFER_NX;
6417 -                       wrmsr(MSR_EFER, l, h);
6418 -                       nx_enabled = 1;
6419 -                       __supported_pte_mask |= _PAGE_NX;
6420 -               }
6421 +               __supported_pte_mask &= ~_PAGE_NX;
6422 +               rdmsr(MSR_EFER, l, h);
6423 +               l &= ~EFER_NX;
6424 +               wrmsr(MSR_EFER, l, h);
6425         }
6426  }
6427  
6428 @@ -518,14 +480,6 @@ void __init paging_init(void)
6429  
6430         load_cr3(swapper_pg_dir);
6431  
6432 -#ifdef CONFIG_X86_PAE
6433 -       /*
6434 -        * We will bail out later - printk doesn't work right now so
6435 -        * the user would just see a hanging kernel.
6436 -        */
6437 -       if (cpu_has_pae)
6438 -               set_in_cr4(X86_CR4_PAE);
6439 -#endif
6440         __flush_tlb_all();
6441  
6442         kmap_init();
6443 @@ -596,7 +550,7 @@ void __init mem_init(void)
6444         set_highmem_pages_init(bad_ppro);
6445  
6446         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
6447 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
6448 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
6449         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
6450  
6451         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); 
6452 @@ -641,10 +595,10 @@ void __init mem_init(void)
6453                (unsigned long)&__init_begin, (unsigned long)&__init_end,
6454                ((unsigned long)&__init_end - (unsigned long)&__init_begin) >> 10,
6455  
6456 -              (unsigned long)&_etext, (unsigned long)&_edata,
6457 -              ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
6458 +              (unsigned long)&_data, (unsigned long)&_edata,
6459 +              ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
6460  
6461 -              (unsigned long)&_text, (unsigned long)&_etext,
6462 +              (unsigned long)&_text + __KERNEL_TEXT_OFFSET, (unsigned long)&_etext + __KERNEL_TEXT_OFFSET,
6463                ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
6464  
6465  #ifdef CONFIG_HIGHMEM
6466 @@ -655,10 +609,6 @@ void __init mem_init(void)
6467         BUG_ON((unsigned long)high_memory      > VMALLOC_START);
6468  #endif /* double-sanity-check paranoia */
6469  
6470 -#ifdef CONFIG_X86_PAE
6471 -       if (!cpu_has_pae)
6472 -               panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
6473 -#endif
6474         if (boot_cpu_data.wp_works_ok < 0)
6475                 test_wp_bit();
6476  
6477 @@ -781,6 +731,38 @@ void free_init_pages(char *what, unsigne
6478  
6479  void free_initmem(void)
6480  {
6481 +
6482 +#ifdef CONFIG_PAX_KERNEXEC
6483 +       /* PaX: limit KERNEL_CS to actual size */
6484 +       unsigned long addr, limit;
6485 +       __u32 a, b;
6486 +       int cpu;
6487 +       pgd_t *pgd;
6488 +       pud_t *pud;
6489 +       pmd_t *pmd;
6490 +
6491 +#ifdef CONFIG_MODULES
6492 +       limit = (unsigned long)&MODULES_END - __KERNEL_TEXT_OFFSET;
6493 +#else
6494 +       limit = (unsigned long)&_etext;
6495 +#endif
6496 +       limit = (limit - 1UL) >> PAGE_SHIFT;
6497 +
6498 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
6499 +               pack_descriptor(&a, &b, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
6500 +               write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, a, b);
6501 +       }
6502 +
6503 +       /* PaX: make KERNEL_CS read-only */
6504 +       for (addr = __KERNEL_TEXT_OFFSET; addr < (unsigned long)&_data; addr += PMD_SIZE) {
6505 +               pgd = pgd_offset_k(addr);
6506 +               pud = pud_offset(pgd, addr);
6507 +               pmd = pmd_offset(pud, addr);
6508 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
6509 +       }
6510 +       flush_tlb_all();
6511 +#endif
6512 +
6513         free_init_pages("unused kernel memory",
6514                         (unsigned long)(&__init_begin),
6515                         (unsigned long)(&__init_end));
6516 diff -urNp linux-2.6.20.3/arch/i386/mm/mmap.c linux-2.6.20.3/arch/i386/mm/mmap.c
6517 --- linux-2.6.20.3/arch/i386/mm/mmap.c  2007-03-13 14:27:08.000000000 -0400
6518 +++ linux-2.6.20.3/arch/i386/mm/mmap.c  2007-03-23 08:10:06.000000000 -0400
6519 @@ -34,12 +34,18 @@
6520   * Leave an at least ~128 MB hole.
6521   */
6522  #define MIN_GAP (128*1024*1024)
6523 -#define MAX_GAP (TASK_SIZE/6*5)
6524 +#define MAX_GAP (task_size/6*5)
6525  
6526  static inline unsigned long mmap_base(struct mm_struct *mm)
6527  {
6528         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
6529         unsigned long random_factor = 0;
6530 +       unsigned long task_size = TASK_SIZE;
6531 +
6532 +#ifdef CONFIG_PAX_SEGMEXEC
6533 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6534 +               task_size = SEGMEXEC_TASK_SIZE;
6535 +#endif
6536  
6537         if (current->flags & PF_RANDOMIZE)
6538                 random_factor = get_random_int() % (1024*1024);
6539 @@ -49,7 +55,7 @@ static inline unsigned long mmap_base(st
6540         else if (gap > MAX_GAP)
6541                 gap = MAX_GAP;
6542  
6543 -       return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
6544 +       return PAGE_ALIGN(task_size - gap - random_factor);
6545  }
6546  
6547  /*
6548 @@ -66,10 +72,22 @@ void arch_pick_mmap_layout(struct mm_str
6549                         (current->personality & ADDR_COMPAT_LAYOUT) ||
6550                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
6551                 mm->mmap_base = TASK_UNMAPPED_BASE;
6552 +
6553 +#ifdef CONFIG_PAX_RANDMMAP
6554 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6555 +                       mm->mmap_base += mm->delta_mmap;
6556 +#endif
6557 +
6558                 mm->get_unmapped_area = arch_get_unmapped_area;
6559                 mm->unmap_area = arch_unmap_area;
6560         } else {
6561                 mm->mmap_base = mmap_base(mm);
6562 +
6563 +#ifdef CONFIG_PAX_RANDMMAP
6564 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6565 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
6566 +#endif
6567 +
6568                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
6569                 mm->unmap_area = arch_unmap_area_topdown;
6570         }
6571 diff -urNp linux-2.6.20.3/arch/i386/mm/pageattr.c linux-2.6.20.3/arch/i386/mm/pageattr.c
6572 --- linux-2.6.20.3/arch/i386/mm/pageattr.c      2007-03-13 14:27:08.000000000 -0400
6573 +++ linux-2.6.20.3/arch/i386/mm/pageattr.c      2007-03-23 08:10:06.000000000 -0400
6574 @@ -13,6 +13,7 @@
6575  #include <asm/tlbflush.h>
6576  #include <asm/pgalloc.h>
6577  #include <asm/sections.h>
6578 +#include <asm/desc.h>
6579  
6580  static DEFINE_SPINLOCK(cpa_lock);
6581  static struct list_head df_list = LIST_HEAD_INIT(df_list);
6582 @@ -89,7 +90,18 @@ static void set_pmd_pte(pte_t *kpte, uns
6583         struct page *page;
6584         unsigned long flags;
6585  
6586 +#ifdef CONFIG_PAX_KERNEXEC
6587 +       unsigned long cr0;
6588 +
6589 +       pax_open_kernel(cr0);
6590 +#endif
6591 +
6592         set_pte_atomic(kpte, pte);      /* change init_mm */
6593 +
6594 +#ifdef CONFIG_PAX_KERNEXEC
6595 +       pax_close_kernel(cr0);
6596 +#endif
6597 +
6598         if (PTRS_PER_PMD > 1)
6599                 return;
6600  
6601 @@ -116,7 +128,7 @@ static inline void revert_page(struct pa
6602         pte_t *linear;
6603  
6604         ref_prot =
6605 -       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
6606 +       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
6607                 ? PAGE_KERNEL_LARGE_EXEC : PAGE_KERNEL_LARGE;
6608  
6609         linear = (pte_t *)
6610 @@ -148,7 +160,7 @@ __change_page_attr(struct page *page, pg
6611                         struct page *split;
6612  
6613                         ref_prot =
6614 -                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext)
6615 +                       ((address & LARGE_PAGE_MASK) < (unsigned long)&_etext + __KERNEL_TEXT_OFFSET)
6616                                 ? PAGE_KERNEL_EXEC : PAGE_KERNEL;
6617                         split = split_large_page(address, prot, ref_prot);
6618                         if (!split)
6619 diff -urNp linux-2.6.20.3/arch/i386/oprofile/backtrace.c linux-2.6.20.3/arch/i386/oprofile/backtrace.c
6620 --- linux-2.6.20.3/arch/i386/oprofile/backtrace.c       2007-03-13 14:27:08.000000000 -0400
6621 +++ linux-2.6.20.3/arch/i386/oprofile/backtrace.c       2007-03-23 08:10:06.000000000 -0400
6622 @@ -116,7 +116,7 @@ x86_backtrace(struct pt_regs * const reg
6623         head = (struct frame_head *)regs->ebp;
6624  #endif
6625  
6626 -       if (!user_mode_vm(regs)) {
6627 +       if (!user_mode(regs)) {
6628                 while (depth-- && valid_kernel_stack(head, regs))
6629                         head = dump_kernel_backtrace(head);
6630                 return;
6631 diff -urNp linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c
6632 --- linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c     2007-03-13 14:27:08.000000000 -0400
6633 +++ linux-2.6.20.3/arch/i386/oprofile/op_model_p4.c     2007-03-23 08:10:06.000000000 -0400
6634 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
6635  #endif
6636  }
6637  
6638 -static int inline addr_increment(void)
6639 +static inline int addr_increment(void)
6640  {
6641  #ifdef CONFIG_SMP
6642         return smp_num_siblings == 2 ? 2 : 1;
6643 diff -urNp linux-2.6.20.3/arch/i386/pci/common.c linux-2.6.20.3/arch/i386/pci/common.c
6644 --- linux-2.6.20.3/arch/i386/pci/common.c       2007-03-13 14:27:08.000000000 -0400
6645 +++ linux-2.6.20.3/arch/i386/pci/common.c       2007-03-23 08:10:06.000000000 -0400
6646 @@ -191,7 +191,7 @@ static struct dmi_system_id __devinitdat
6647                         DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
6648                 },
6649         },
6650 -       {}
6651 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
6652  };
6653  
6654  struct pci_bus * __devinit pcibios_scan_root(int busnum)
6655 diff -urNp linux-2.6.20.3/arch/i386/pci/early.c linux-2.6.20.3/arch/i386/pci/early.c
6656 --- linux-2.6.20.3/arch/i386/pci/early.c        2007-03-13 14:27:08.000000000 -0400
6657 +++ linux-2.6.20.3/arch/i386/pci/early.c        2007-03-23 08:10:06.000000000 -0400
6658 @@ -7,7 +7,7 @@
6659  /* Direct PCI access. This is used for PCI accesses in early boot before
6660     the PCI subsystem works. */
6661  
6662 -#define PDprintk(x...)
6663 +#define PDprintk(x...) do {} while (0)
6664  
6665  u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
6666  {
6667 diff -urNp linux-2.6.20.3/arch/i386/pci/fixup.c linux-2.6.20.3/arch/i386/pci/fixup.c
6668 --- linux-2.6.20.3/arch/i386/pci/fixup.c        2007-03-13 14:27:08.000000000 -0400
6669 +++ linux-2.6.20.3/arch/i386/pci/fixup.c        2007-03-23 08:10:06.000000000 -0400
6670 @@ -389,7 +389,7 @@ static struct dmi_system_id __devinitdat
6671                         DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
6672                 },
6673         },
6674 -       { }
6675 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
6676  };
6677  
6678  static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
6679 diff -urNp linux-2.6.20.3/arch/i386/pci/irq.c linux-2.6.20.3/arch/i386/pci/irq.c
6680 --- linux-2.6.20.3/arch/i386/pci/irq.c  2007-03-13 14:27:08.000000000 -0400
6681 +++ linux-2.6.20.3/arch/i386/pci/irq.c  2007-03-23 08:10:06.000000000 -0400
6682 @@ -507,7 +507,7 @@ static __init int intel_router_probe(str
6683         static struct pci_device_id __initdata pirq_440gx[] = {
6684                 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
6685                 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
6686 -               { },
6687 +               { PCI_DEVICE(0, 0) }
6688         };
6689  
6690         /* 440GX has a proprietary PIRQ router -- don't use it */
6691 @@ -1049,7 +1049,7 @@ static struct dmi_system_id __initdata p
6692                         DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
6693                 },
6694         },
6695 -       { }
6696 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
6697  };
6698  
6699  static int __init pcibios_irq_init(void)
6700 diff -urNp linux-2.6.20.3/arch/i386/power/cpu.c linux-2.6.20.3/arch/i386/power/cpu.c
6701 --- linux-2.6.20.3/arch/i386/power/cpu.c        2007-03-13 14:27:08.000000000 -0400
6702 +++ linux-2.6.20.3/arch/i386/power/cpu.c        2007-03-23 08:10:06.000000000 -0400
6703 @@ -63,7 +63,7 @@ static void do_fpu_end(void)
6704  static void fix_processor_context(void)
6705  {
6706         int cpu = smp_processor_id();
6707 -       struct tss_struct * t = &per_cpu(init_tss, cpu);
6708 +       struct tss_struct * t = init_tss + cpu;
6709  
6710         set_tss_desc(cpu,t);    /* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */
6711  
6712 diff -urNp linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c
6713 --- linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c        2007-03-13 14:27:08.000000000 -0400
6714 +++ linux-2.6.20.3/arch/ia64/ia32/binfmt_elf32.c        2007-03-23 08:10:06.000000000 -0400
6715 @@ -45,6 +45,17 @@ randomize_stack_top(unsigned long stack_
6716  
6717  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
6718  
6719 +#ifdef CONFIG_PAX_ASLR
6720 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
6721 +
6722 +#define PAX_DELTA_MMAP_LSB(tsk)                IA32_PAGE_SHIFT
6723 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
6724 +#define PAX_DELTA_EXEC_LSB(tsk)                IA32_PAGE_SHIFT
6725 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
6726 +#define PAX_DELTA_STACK_LSB(tsk)       IA32_PAGE_SHIFT
6727 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - IA32_PAGE_SHIFT)
6728 +#endif
6729 +
6730  /* Ugly but avoids duplication */
6731  #include "../../../fs/binfmt_elf.c"
6732  
6733 diff -urNp linux-2.6.20.3/arch/ia64/ia32/ia32priv.h linux-2.6.20.3/arch/ia64/ia32/ia32priv.h
6734 --- linux-2.6.20.3/arch/ia64/ia32/ia32priv.h    2007-03-13 14:27:08.000000000 -0400
6735 +++ linux-2.6.20.3/arch/ia64/ia32/ia32priv.h    2007-03-23 08:10:06.000000000 -0400
6736 @@ -304,7 +304,14 @@ struct old_linux32_dirent {
6737  #define ELF_DATA       ELFDATA2LSB
6738  #define ELF_ARCH       EM_386
6739  
6740 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
6741 +#ifdef CONFIG_PAX_RANDUSTACK
6742 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
6743 +#else
6744 +#define __IA32_DELTA_STACK     0UL
6745 +#endif
6746 +
6747 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
6748 +
6749  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
6750  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
6751  
6752 diff -urNp linux-2.6.20.3/arch/ia64/kernel/module.c linux-2.6.20.3/arch/ia64/kernel/module.c
6753 --- linux-2.6.20.3/arch/ia64/kernel/module.c    2007-03-13 14:27:08.000000000 -0400
6754 +++ linux-2.6.20.3/arch/ia64/kernel/module.c    2007-03-23 08:10:06.000000000 -0400
6755 @@ -321,7 +321,7 @@ module_alloc (unsigned long size)
6756  void
6757  module_free (struct module *mod, void *module_region)
6758  {
6759 -       if (mod->arch.init_unw_table && module_region == mod->module_init) {
6760 +       if (mod->arch.init_unw_table && module_region == mod->module_init_rx) {
6761                 unw_remove_unwind_table(mod->arch.init_unw_table);
6762                 mod->arch.init_unw_table = NULL;
6763         }
6764 @@ -499,15 +499,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
6765  }
6766  
6767  static inline int
6768 +in_init_rx (const struct module *mod, uint64_t addr)
6769 +{
6770 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
6771 +}
6772 +
6773 +static inline int
6774 +in_init_rw (const struct module *mod, uint64_t addr)
6775 +{
6776 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
6777 +}
6778 +
6779 +static inline int
6780  in_init (const struct module *mod, uint64_t addr)
6781  {
6782 -       return addr - (uint64_t) mod->module_init < mod->init_size;
6783 +       return in_init_rx(mod, value) || in_init_rw(mod, value);
6784 +}
6785 +
6786 +static inline int
6787 +in_core_rx (const struct module *mod, uint64_t addr)
6788 +{
6789 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
6790 +}
6791 +
6792 +static inline int
6793 +in_core_rw (const struct module *mod, uint64_t addr)
6794 +{
6795 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
6796  }
6797  
6798  static inline int
6799  in_core (const struct module *mod, uint64_t addr)
6800  {
6801 -       return addr - (uint64_t) mod->module_core < mod->core_size;
6802 +       return in_core_rx(mod, value) || in_core_rw(mod, value);
6803  }
6804  
6805  static inline int
6806 @@ -691,7 +715,14 @@ do_reloc (struct module *mod, uint8_t r_
6807                 break;
6808  
6809               case RV_BDREL:
6810 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
6811 +               if (in_init_rx(mod, val))
6812 +                       val -= (uint64_t) mod->module_init_rx;
6813 +               else if (in_init_rw(mod, val))
6814 +                       val -= (uint64_t) mod->module_init_rw;
6815 +               else if (in_core_rx(mod, val))
6816 +                       val -= (uint64_t) mod->module_core_rx;
6817 +               else if (in_core_rw(mod, val))
6818 +                       val -= (uint64_t) mod->module_core_rw;
6819                 break;
6820  
6821               case RV_LTV:
6822 @@ -825,15 +856,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
6823                  *     addresses have been selected...
6824                  */
6825                 uint64_t gp;
6826 -               if (mod->core_size > MAX_LTOFF)
6827 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
6828                         /*
6829                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
6830                          * at the end of the module.
6831                          */
6832 -                       gp = mod->core_size - MAX_LTOFF / 2;
6833 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
6834                 else
6835 -                       gp = mod->core_size / 2;
6836 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
6837 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
6838 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
6839                 mod->arch.gp = gp;
6840                 DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp);
6841         }
6842 diff -urNp linux-2.6.20.3/arch/ia64/kernel/ptrace.c linux-2.6.20.3/arch/ia64/kernel/ptrace.c
6843 --- linux-2.6.20.3/arch/ia64/kernel/ptrace.c    2007-03-13 14:27:08.000000000 -0400
6844 +++ linux-2.6.20.3/arch/ia64/kernel/ptrace.c    2007-03-23 08:11:18.000000000 -0400
6845 @@ -18,6 +18,7 @@
6846  #include <linux/audit.h>
6847  #include <linux/signal.h>
6848  #include <linux/vs_base.h>
6849 +#include <linux/grsecurity.h>
6850  
6851  #include <asm/pgtable.h>
6852  #include <asm/processor.h>
6853 @@ -1446,6 +1447,9 @@ sys_ptrace (long request, pid_t pid, uns
6854         if (pid == 1)           /* no messing around with init! */
6855                 goto out_tsk;
6856  
6857 +       if (gr_handle_ptrace(child, request))
6858 +               goto out_tsk;
6859 +
6860         if (request == PTRACE_ATTACH) {
6861                 ret = ptrace_attach(child);
6862                 goto out_tsk;
6863 diff -urNp linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c
6864 --- linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c  2007-03-13 14:27:08.000000000 -0400
6865 +++ linux-2.6.20.3/arch/ia64/kernel/sys_ia64.c  2007-03-23 08:10:06.000000000 -0400
6866 @@ -37,6 +37,13 @@ arch_get_unmapped_area (struct file *fil
6867         if (REGION_NUMBER(addr) == RGN_HPAGE)
6868                 addr = 0;
6869  #endif
6870 +
6871 +#ifdef CONFIG_PAX_RANDMMAP
6872 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
6873 +               addr = mm->free_area_cache;
6874 +       else
6875 +#endif
6876 +
6877         if (!addr)
6878                 addr = mm->free_area_cache;
6879  
6880 @@ -55,9 +62,9 @@ arch_get_unmapped_area (struct file *fil
6881         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6882                 /* At this point:  (!vma || addr < vma->vm_end). */
6883                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
6884 -                       if (start_addr != TASK_UNMAPPED_BASE) {
6885 +                       if (start_addr != mm->mmap_base) {
6886                                 /* Start a new search --- just in case we missed some holes.  */
6887 -                               addr = TASK_UNMAPPED_BASE;
6888 +                               addr = mm->mmap_base;
6889                                 goto full_search;
6890                         }
6891                         return -ENOMEM;
6892 diff -urNp linux-2.6.20.3/arch/ia64/mm/fault.c linux-2.6.20.3/arch/ia64/mm/fault.c
6893 --- linux-2.6.20.3/arch/ia64/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
6894 +++ linux-2.6.20.3/arch/ia64/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
6895 @@ -10,6 +10,7 @@
6896  #include <linux/interrupt.h>
6897  #include <linux/kprobes.h>
6898  #include <linux/vs_memory.h>
6899 +#include <linux/binfmts.h>
6900  
6901  #include <asm/pgtable.h>
6902  #include <asm/processor.h>
6903 @@ -86,6 +87,23 @@ mapped_kernel_page_is_present (unsigned 
6904         return pte_present(pte);
6905  }
6906  
6907 +#ifdef CONFIG_PAX_PAGEEXEC
6908 +void pax_report_insns(void *pc, void *sp)
6909 +{
6910 +       unsigned long i;
6911 +
6912 +       printk(KERN_ERR "PAX: bytes at PC: ");
6913 +       for (i = 0; i < 8; i++) {
6914 +               unsigned int c;
6915 +               if (get_user(c, (unsigned int*)pc+i))
6916 +                       printk("???????? ");
6917 +               else
6918 +                       printk("%08x ", c);
6919 +       }
6920 +       printk("\n");
6921 +}
6922 +#endif
6923 +
6924  void __kprobes
6925  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
6926  {
6927 @@ -153,9 +171,23 @@ ia64_do_page_fault (unsigned long addres
6928         mask = (  (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
6929                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
6930  
6931 -       if ((vma->vm_flags & mask) != mask)
6932 +       if ((vma->vm_flags & mask) != mask) {
6933 +
6934 +#ifdef CONFIG_PAX_PAGEEXEC
6935 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
6936 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
6937 +                               goto bad_area;
6938 +
6939 +                       up_read(&mm->mmap_sem);
6940 +                       pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12);
6941 +                       do_exit(SIGKILL);
6942 +               }
6943 +#endif
6944 +
6945                 goto bad_area;
6946  
6947 +       }
6948 +
6949    survive:
6950         /*
6951          * If for any reason at all we couldn't handle the fault, make
6952 diff -urNp linux-2.6.20.3/arch/ia64/mm/init.c linux-2.6.20.3/arch/ia64/mm/init.c
6953 --- linux-2.6.20.3/arch/ia64/mm/init.c  2007-03-13 14:27:08.000000000 -0400
6954 +++ linux-2.6.20.3/arch/ia64/mm/init.c  2007-03-23 08:10:06.000000000 -0400
6955 @@ -19,8 +19,8 @@
6956  #include <linux/swap.h>
6957  #include <linux/proc_fs.h>
6958  #include <linux/bitops.h>
6959 +#include <linux/a.out.h>
6960  
6961 -#include <asm/a.out.h>
6962  #include <asm/dma.h>
6963  #include <asm/ia32.h>
6964  #include <asm/io.h>
6965 diff -urNp linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c
6966 --- linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c     2007-03-13 14:27:08.000000000 -0400
6967 +++ linux-2.6.20.3/arch/mips/kernel/binfmt_elfn32.c     2007-03-23 08:10:06.000000000 -0400
6968 @@ -50,6 +50,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6969  #undef ELF_ET_DYN_BASE
6970  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
6971  
6972 +#ifdef CONFIG_PAX_ASLR
6973 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6974 +
6975 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
6976 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6977 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
6978 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6979 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
6980 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6981 +#endif
6982 +
6983  #include <asm/processor.h>
6984  #include <linux/module.h>
6985  #include <linux/elfcore.h>
6986 diff -urNp linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c
6987 --- linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c     2007-03-13 14:27:08.000000000 -0400
6988 +++ linux-2.6.20.3/arch/mips/kernel/binfmt_elfo32.c     2007-03-23 08:10:06.000000000 -0400
6989 @@ -52,6 +52,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
6990  #undef ELF_ET_DYN_BASE
6991  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
6992  
6993 +#ifdef CONFIG_PAX_ASLR
6994 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
6995 +
6996 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
6997 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
6998 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
6999 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7000 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
7001 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
7002 +#endif
7003 +
7004  #include <asm/processor.h>
7005  #include <linux/module.h>
7006  #include <linux/elfcore.h>
7007 diff -urNp linux-2.6.20.3/arch/mips/kernel/syscall.c linux-2.6.20.3/arch/mips/kernel/syscall.c
7008 --- linux-2.6.20.3/arch/mips/kernel/syscall.c   2007-03-13 14:27:08.000000000 -0400
7009 +++ linux-2.6.20.3/arch/mips/kernel/syscall.c   2007-03-23 08:10:06.000000000 -0400
7010 @@ -88,6 +88,11 @@ unsigned long arch_get_unmapped_area(str
7011         do_color_align = 0;
7012         if (filp || (flags & MAP_SHARED))
7013                 do_color_align = 1;
7014 +
7015 +#ifdef CONFIG_PAX_RANDMMAP
7016 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
7017 +#endif
7018 +
7019         if (addr) {
7020                 if (do_color_align)
7021                         addr = COLOUR_ALIGN(addr, pgoff);
7022 @@ -98,7 +103,7 @@ unsigned long arch_get_unmapped_area(str
7023                     (!vmm || addr + len <= vmm->vm_start))
7024                         return addr;
7025         }
7026 -       addr = TASK_UNMAPPED_BASE;
7027 +       addr = current->mm->mmap_base;
7028         if (do_color_align)
7029                 addr = COLOUR_ALIGN(addr, pgoff);
7030         else
7031 diff -urNp linux-2.6.20.3/arch/mips/mm/fault.c linux-2.6.20.3/arch/mips/mm/fault.c
7032 --- linux-2.6.20.3/arch/mips/mm/fault.c 2007-03-13 14:27:08.000000000 -0400
7033 +++ linux-2.6.20.3/arch/mips/mm/fault.c 2007-03-23 08:10:06.000000000 -0400
7034 @@ -27,6 +27,23 @@
7035  #include <asm/ptrace.h>
7036  #include <asm/highmem.h>               /* For VMALLOC_END */
7037  
7038 +#ifdef CONFIG_PAX_PAGEEXEC
7039 +void pax_report_insns(void *pc)
7040 +{
7041 +       unsigned long i;
7042 +
7043 +       printk(KERN_ERR "PAX: bytes at PC: ");
7044 +       for (i = 0; i < 5; i++) {
7045 +               unsigned int c;
7046 +               if (get_user(c, (unsigned int*)pc+i))
7047 +                       printk("???????? ");
7048 +               else
7049 +                       printk("%08x ", c);
7050 +       }
7051 +       printk("\n");
7052 +}
7053 +#endif
7054 +
7055  /*
7056   * This routine handles page faults.  It determines the address,
7057   * and the problem, and then passes it off to one of the appropriate
7058 diff -urNp linux-2.6.20.3/arch/parisc/kernel/module.c linux-2.6.20.3/arch/parisc/kernel/module.c
7059 --- linux-2.6.20.3/arch/parisc/kernel/module.c  2007-03-13 14:27:08.000000000 -0400
7060 +++ linux-2.6.20.3/arch/parisc/kernel/module.c  2007-03-23 08:10:06.000000000 -0400
7061 @@ -72,16 +72,38 @@
7062  
7063  /* three functions to determine where in the module core
7064   * or init pieces the location is */
7065 +static inline int in_init_rx(struct module *me, void *loc)
7066 +{
7067 +       return (loc >= me->module_init_rx &&
7068 +               loc < (me->module_init_rx + me->init_size_rx));
7069 +}
7070 +
7071 +static inline int in_init_rw(struct module *me, void *loc)
7072 +{
7073 +       return (loc >= me->module_init_rw &&
7074 +               loc < (me->module_init_rw + me->init_size_rw));
7075 +}
7076 +
7077  static inline int in_init(struct module *me, void *loc)
7078  {
7079 -       return (loc >= me->module_init &&
7080 -               loc <= (me->module_init + me->init_size));
7081 +       return in_init_rx(me, loc) || in_init_rw(me, loc);
7082 +}
7083 +
7084 +static inline int in_core_rx(struct module *me, void *loc)
7085 +{
7086 +       return (loc >= me->module_core_rx &&
7087 +               loc < (me->module_core_rx + me->core_size_rx));
7088 +}
7089 +
7090 +static inline int in_core_rw(struct module *me, void *loc)
7091 +{
7092 +       return (loc >= me->module_core_rw &&
7093 +               loc < (me->module_core_rw + me->core_size_rw));
7094  }
7095  
7096  static inline int in_core(struct module *me, void *loc)
7097  {
7098 -       return (loc >= me->module_core &&
7099 -               loc <= (me->module_core + me->core_size));
7100 +       return in_core_rx(me, loc) || in_core_rw(me, loc);
7101  }
7102  
7103  static inline int in_local(struct module *me, void *loc)
7104 @@ -295,21 +317,21 @@ int module_frob_arch_sections(CONST Elf_
7105         }
7106  
7107         /* align things a bit */
7108 -       me->core_size = ALIGN(me->core_size, 16);
7109 -       me->arch.got_offset = me->core_size;
7110 -       me->core_size += gots * sizeof(struct got_entry);
7111 -
7112 -       me->core_size = ALIGN(me->core_size, 16);
7113 -       me->arch.fdesc_offset = me->core_size;
7114 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
7115 -
7116 -       me->core_size = ALIGN(me->core_size, 16);
7117 -       me->arch.stub_offset = me->core_size;
7118 -       me->core_size += stubs * sizeof(struct stub_entry);
7119 -
7120 -       me->init_size = ALIGN(me->init_size, 16);
7121 -       me->arch.init_stub_offset = me->init_size;
7122 -       me->init_size += init_stubs * sizeof(struct stub_entry);
7123 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
7124 +       me->arch.got_offset = me->core_size_rw;
7125 +       me->core_size_rw += gots * sizeof(struct got_entry);
7126 +
7127 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
7128 +       me->arch.fdesc_offset = me->core_size_rw;
7129 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
7130 +
7131 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
7132 +       me->arch.stub_offset = me->core_size_rx;
7133 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
7134 +
7135 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
7136 +       me->arch.init_stub_offset = me->init_size_rx;
7137 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
7138  
7139         me->arch.got_max = gots;
7140         me->arch.fdesc_max = fdescs;
7141 @@ -329,7 +351,7 @@ static Elf64_Word get_got(struct module 
7142  
7143         BUG_ON(value == 0);
7144  
7145 -       got = me->module_core + me->arch.got_offset;
7146 +       got = me->module_core_rw + me->arch.got_offset;
7147         for (i = 0; got[i].addr; i++)
7148                 if (got[i].addr == value)
7149                         goto out;
7150 @@ -347,7 +369,7 @@ static Elf64_Word get_got(struct module 
7151  #ifdef __LP64__
7152  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
7153  {
7154 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
7155 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
7156  
7157         if (!value) {
7158                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
7159 @@ -365,7 +387,7 @@ static Elf_Addr get_fdesc(struct module 
7160  
7161         /* Create new one */
7162         fdesc->addr = value;
7163 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
7164 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
7165         return (Elf_Addr)fdesc;
7166  }
7167  #endif /* __LP64__ */
7168 @@ -385,12 +407,12 @@ static Elf_Addr get_stub(struct module *
7169         if(init_section) {
7170                 i = me->arch.init_stub_count++;
7171                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
7172 -               stub = me->module_init + me->arch.init_stub_offset + 
7173 +               stub = me->module_init_rx + me->arch.init_stub_offset + 
7174                         i * sizeof(struct stub_entry);
7175         } else {
7176                 i = me->arch.stub_count++;
7177                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
7178 -               stub = me->module_core + me->arch.stub_offset + 
7179 +               stub = me->module_core_rx + me->arch.stub_offset + 
7180                         i * sizeof(struct stub_entry);
7181         }
7182  
7183 @@ -758,7 +780,7 @@ register_unwind_table(struct module *me,
7184  
7185         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
7186         end = table + sechdrs[me->arch.unwind_section].sh_size;
7187 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
7188 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
7189  
7190         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
7191                me->arch.unwind_section, table, end, gp);
7192 diff -urNp linux-2.6.20.3/arch/parisc/kernel/ptrace.c linux-2.6.20.3/arch/parisc/kernel/ptrace.c
7193 --- linux-2.6.20.3/arch/parisc/kernel/ptrace.c  2007-03-13 14:27:08.000000000 -0400
7194 +++ linux-2.6.20.3/arch/parisc/kernel/ptrace.c  2007-03-23 08:11:18.000000000 -0400
7195 @@ -18,6 +18,7 @@
7196  #include <linux/security.h>
7197  #include <linux/compat.h>
7198  #include <linux/signal.h>
7199 +#include <linux/grsecurity.h>
7200  
7201  #include <asm/uaccess.h>
7202  #include <asm/pgtable.h>
7203 diff -urNp linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c
7204 --- linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c      2007-03-13 14:27:08.000000000 -0400
7205 +++ linux-2.6.20.3/arch/parisc/kernel/sys_parisc.c      2007-03-23 08:10:06.000000000 -0400
7206 @@ -107,7 +107,7 @@ unsigned long arch_get_unmapped_area(str
7207         if (len > TASK_SIZE)
7208                 return -ENOMEM;
7209         if (!addr)
7210 -               addr = TASK_UNMAPPED_BASE;
7211 +               addr = current->mm->mmap_base;
7212  
7213         if (filp) {
7214                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
7215 diff -urNp linux-2.6.20.3/arch/parisc/kernel/traps.c linux-2.6.20.3/arch/parisc/kernel/traps.c
7216 --- linux-2.6.20.3/arch/parisc/kernel/traps.c   2007-03-13 14:27:08.000000000 -0400
7217 +++ linux-2.6.20.3/arch/parisc/kernel/traps.c   2007-03-23 08:10:06.000000000 -0400
7218 @@ -716,9 +716,7 @@ void handle_interruption(int code, struc
7219  
7220                         down_read(&current->mm->mmap_sem);
7221                         vma = find_vma(current->mm,regs->iaoq[0]);
7222 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
7223 -                               && (vma->vm_flags & VM_EXEC)) {
7224 -
7225 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
7226                                 fault_address = regs->iaoq[0];
7227                                 fault_space = regs->iasq[0];
7228  
7229 diff -urNp linux-2.6.20.3/arch/parisc/mm/fault.c linux-2.6.20.3/arch/parisc/mm/fault.c
7230 --- linux-2.6.20.3/arch/parisc/mm/fault.c       2007-03-13 14:27:08.000000000 -0400
7231 +++ linux-2.6.20.3/arch/parisc/mm/fault.c       2007-03-23 08:10:06.000000000 -0400
7232 @@ -16,6 +16,8 @@
7233  #include <linux/sched.h>
7234  #include <linux/interrupt.h>
7235  #include <linux/module.h>
7236 +#include <linux/unistd.h>
7237 +#include <linux/binfmts.h>
7238  
7239  #include <asm/uaccess.h>
7240  #include <asm/traps.h>
7241 @@ -57,7 +59,7 @@ DEFINE_PER_CPU(struct exception_data, ex
7242  static unsigned long
7243  parisc_acctyp(unsigned long code, unsigned int inst)
7244  {
7245 -       if (code == 6 || code == 16)
7246 +       if (code == 6 || code == 7 || code == 16)
7247             return VM_EXEC;
7248  
7249         switch (inst & 0xf0000000) {
7250 @@ -143,6 +145,116 @@ parisc_acctyp(unsigned long code, unsign
7251                         }
7252  #endif
7253  
7254 +#ifdef CONFIG_PAX_PAGEEXEC
7255 +/*
7256 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
7257 + *
7258 + * returns 1 when task should be killed
7259 + *         2 when rt_sigreturn trampoline was detected
7260 + *         3 when unpatched PLT trampoline was detected
7261 + */
7262 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7263 +{
7264 +
7265 +#ifdef CONFIG_PAX_EMUPLT
7266 +       int err;
7267 +
7268 +       do { /* PaX: unpatched PLT emulation */
7269 +               unsigned int bl, depwi;
7270 +
7271 +               err = get_user(bl, (unsigned int*)instruction_pointer(regs));
7272 +               err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4));
7273 +
7274 +               if (err)
7275 +                       break;
7276 +
7277 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
7278 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
7279 +
7280 +                       err = get_user(ldw, (unsigned int*)addr);
7281 +                       err |= get_user(bv, (unsigned int*)(addr+4));
7282 +                       err |= get_user(ldw2, (unsigned int*)(addr+8));
7283 +
7284 +                       if (err)
7285 +                               break;
7286 +
7287 +                       if (ldw == 0x0E801096U &&
7288 +                           bv == 0xEAC0C000U &&
7289 +                           ldw2 == 0x0E881095U)
7290 +                       {
7291 +                               unsigned int resolver, map;
7292 +
7293 +                               err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8));
7294 +                               err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12));
7295 +                               if (err)
7296 +                                       break;
7297 +
7298 +                               regs->gr[20] = instruction_pointer(regs)+8;
7299 +                               regs->gr[21] = map;
7300 +                               regs->gr[22] = resolver;
7301 +                               regs->iaoq[0] = resolver | 3UL;
7302 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
7303 +                               return 3;
7304 +                       }
7305 +               }
7306 +       } while (0);
7307 +#endif
7308 +
7309 +#ifdef CONFIG_PAX_EMUTRAMP
7310 +
7311 +#ifndef CONFIG_PAX_EMUSIGRT
7312 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
7313 +               return 1;
7314 +#endif
7315 +
7316 +       do { /* PaX: rt_sigreturn emulation */
7317 +               unsigned int ldi1, ldi2, bel, nop;
7318 +
7319 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
7320 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
7321 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
7322 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
7323 +
7324 +               if (err)
7325 +                       break;
7326 +
7327 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
7328 +                   ldi2 == 0x3414015AU &&
7329 +                   bel == 0xE4008200U &&
7330 +                   nop == 0x08000240U)
7331 +               {
7332 +                       regs->gr[25] = (ldi1 & 2) >> 1;
7333 +                       regs->gr[20] = __NR_rt_sigreturn;
7334 +                       regs->gr[31] = regs->iaoq[1] + 16;
7335 +                       regs->sr[0] = regs->iasq[1];
7336 +                       regs->iaoq[0] = 0x100UL;
7337 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
7338 +                       regs->iasq[0] = regs->sr[2];
7339 +                       regs->iasq[1] = regs->sr[2];
7340 +                       return 2;
7341 +               }
7342 +       } while (0);
7343 +#endif
7344 +
7345 +       return 1;
7346 +}
7347 +
7348 +void pax_report_insns(void *pc, void *sp)
7349 +{
7350 +       unsigned long i;
7351 +
7352 +       printk(KERN_ERR "PAX: bytes at PC: ");
7353 +       for (i = 0; i < 5; i++) {
7354 +               unsigned int c;
7355 +               if (get_user(c, (unsigned int*)pc+i))
7356 +                       printk("???????? ");
7357 +               else
7358 +                       printk("%08x ", c);
7359 +       }
7360 +       printk("\n");
7361 +}
7362 +#endif
7363 +
7364  void do_page_fault(struct pt_regs *regs, unsigned long code,
7365                               unsigned long address)
7366  {
7367 @@ -168,8 +280,33 @@ good_area:
7368  
7369         acc_type = parisc_acctyp(code,regs->iir);
7370  
7371 -       if ((vma->vm_flags & acc_type) != acc_type)
7372 +       if ((vma->vm_flags & acc_type) != acc_type) {
7373 +
7374 +#ifdef CONFIG_PAX_PAGEEXEC
7375 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
7376 +                   (address & ~3UL) == instruction_pointer(regs))
7377 +               {
7378 +                       up_read(&mm->mmap_sem);
7379 +                       switch(pax_handle_fetch_fault(regs)) {
7380 +
7381 +#ifdef CONFIG_PAX_EMUPLT
7382 +                       case 3:
7383 +                               return;
7384 +#endif
7385 +
7386 +#ifdef CONFIG_PAX_EMUTRAMP
7387 +                       case 2:
7388 +                               return;
7389 +#endif
7390 +
7391 +                       }
7392 +                       pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]);
7393 +                       do_exit(SIGKILL);
7394 +               }
7395 +#endif
7396 +
7397                 goto bad_area;
7398 +       }
7399  
7400         /*
7401          * If for any reason at all we couldn't handle the fault, make
7402 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/module_32.c linux-2.6.20.3/arch/powerpc/kernel/module_32.c
7403 --- linux-2.6.20.3/arch/powerpc/kernel/module_32.c      2007-03-13 14:27:08.000000000 -0400
7404 +++ linux-2.6.20.3/arch/powerpc/kernel/module_32.c      2007-03-23 08:10:06.000000000 -0400
7405 @@ -126,7 +126,7 @@ int module_frob_arch_sections(Elf32_Ehdr
7406                         me->arch.core_plt_section = i;
7407         }
7408         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
7409 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
7410 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
7411                 return -ENOEXEC;
7412         }
7413  
7414 @@ -167,11 +167,16 @@ static uint32_t do_plt_call(void *locati
7415  
7416         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
7417         /* Init, or core PLT? */
7418 -       if (location >= mod->module_core
7419 -           && location < mod->module_core + mod->core_size)
7420 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
7421 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
7422                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
7423 -       else
7424 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
7425 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
7426                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
7427 +       else {
7428 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
7429 +               return ~0UL;
7430 +       }
7431  
7432         /* Find this entry, or if that fails, the next avail. entry */
7433         while (entry->jump[0]) {
7434 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/signal_32.c linux-2.6.20.3/arch/powerpc/kernel/signal_32.c
7435 --- linux-2.6.20.3/arch/powerpc/kernel/signal_32.c      2007-03-13 14:27:08.000000000 -0400
7436 +++ linux-2.6.20.3/arch/powerpc/kernel/signal_32.c      2007-03-23 08:10:06.000000000 -0400
7437 @@ -759,7 +759,7 @@ static int handle_rt_signal(unsigned lon
7438  
7439         /* Save user registers on the stack */
7440         frame = &rt_sf->uc.uc_mcontext;
7441 -       if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
7442 +       if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
7443                 if (save_user_regs(regs, frame, 0))
7444                         goto badframe;
7445                 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
7446 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/signal_64.c linux-2.6.20.3/arch/powerpc/kernel/signal_64.c
7447 --- linux-2.6.20.3/arch/powerpc/kernel/signal_64.c      2007-03-13 14:27:08.000000000 -0400
7448 +++ linux-2.6.20.3/arch/powerpc/kernel/signal_64.c      2007-03-23 08:10:06.000000000 -0400
7449 @@ -397,7 +397,7 @@ static int setup_rt_frame(int signr, str
7450         current->thread.fpscr.val = 0;
7451  
7452         /* Set up to return from userspace. */
7453 -       if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
7454 +       if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
7455                 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
7456         } else {
7457                 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
7458 diff -urNp linux-2.6.20.3/arch/powerpc/kernel/vdso.c linux-2.6.20.3/arch/powerpc/kernel/vdso.c
7459 --- linux-2.6.20.3/arch/powerpc/kernel/vdso.c   2007-03-13 14:27:08.000000000 -0400
7460 +++ linux-2.6.20.3/arch/powerpc/kernel/vdso.c   2007-03-23 08:10:06.000000000 -0400
7461 @@ -239,7 +239,7 @@ int arch_setup_additional_pages(struct l
7462         vdso_base = VDSO32_MBASE;
7463  #endif
7464  
7465 -       current->mm->context.vdso_base = 0;
7466 +       current->mm->context.vdso_base = ~0UL;
7467  
7468         /* vDSO has a problem and was disabled, just don't "enable" it for the
7469          * process
7470 @@ -256,7 +256,7 @@ int arch_setup_additional_pages(struct l
7471          */
7472         down_write(&mm->mmap_sem);
7473         vdso_base = get_unmapped_area(NULL, vdso_base,
7474 -                                     vdso_pages << PAGE_SHIFT, 0, 0);
7475 +                                     vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
7476         if (IS_ERR_VALUE(vdso_base)) {
7477                 rc = vdso_base;
7478                 goto fail_mmapsem;
7479 @@ -284,6 +284,12 @@ int arch_setup_additional_pages(struct l
7480          * pages though
7481          */
7482         vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC;
7483 +
7484 +#ifdef CONFIG_PAX_MPROTECT
7485 +       if (mm->pax_flags & MF_PAX_MPROTECT)
7486 +               vma->vm_flags &= ~VM_MAYWRITE;
7487 +#endif
7488 +
7489         /*
7490          * Make sure the vDSO gets into every core dump.
7491          * Dumping its contents makes post-mortem fully interpretable later
7492 @@ -292,7 +298,7 @@ int arch_setup_additional_pages(struct l
7493          */
7494         vma->vm_flags |= VM_ALWAYSDUMP;
7495         vma->vm_flags |= mm->def_flags;
7496 -       vma->vm_page_prot = protection_map[vma->vm_flags & 0x7];
7497 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
7498         vma->vm_ops = &vdso_vmops;
7499  
7500         /* Insert new VMA */
7501 diff -urNp linux-2.6.20.3/arch/powerpc/mm/fault.c linux-2.6.20.3/arch/powerpc/mm/fault.c
7502 --- linux-2.6.20.3/arch/powerpc/mm/fault.c      2007-03-13 14:27:08.000000000 -0400
7503 +++ linux-2.6.20.3/arch/powerpc/mm/fault.c      2007-03-23 08:10:06.000000000 -0400
7504 @@ -28,6 +28,12 @@
7505  #include <linux/highmem.h>
7506  #include <linux/module.h>
7507  #include <linux/kprobes.h>
7508 +#include <linux/binfmts.h>
7509 +#include <linux/slab.h>
7510 +#include <linux/pagemap.h>
7511 +#include <linux/compiler.h>
7512 +#include <linux/binfmts.h>
7513 +#include <linux/unistd.h>
7514  
7515  #include <asm/page.h>
7516  #include <asm/pgtable.h>
7517 @@ -73,6 +79,364 @@ static inline int notify_page_fault(enum
7518  }
7519  #endif
7520  
7521 +#ifdef CONFIG_PAX_EMUSIGRT
7522 +void pax_syscall_close(struct vm_area_struct * vma)
7523 +{
7524 +       vma->vm_mm->call_syscall = 0UL;
7525 +}
7526 +
7527 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
7528 +{
7529 +       struct page* page;
7530 +       unsigned int *kaddr;
7531 +
7532 +       page = alloc_page(GFP_HIGHUSER);
7533 +       if (!page)
7534 +               return NOPAGE_OOM;
7535 +
7536 +       kaddr = kmap(page);
7537 +       memset(kaddr, 0, PAGE_SIZE);
7538 +       kaddr[0] = 0x44000002U; /* sc */
7539 +       __flush_dcache_icache(kaddr);
7540 +       kunmap(page);
7541 +       if (type)
7542 +               *type = VM_FAULT_MAJOR;
7543 +       return page;
7544 +}
7545 +
7546 +static struct vm_operations_struct pax_vm_ops = {
7547 +       .close = pax_syscall_close,
7548 +       .nopage = pax_syscall_nopage,
7549 +};
7550 +
7551 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
7552 +{
7553 +       int ret;
7554 +
7555 +       memset(vma, 0, sizeof(*vma));
7556 +       vma->vm_mm = current->mm;
7557 +       vma->vm_start = addr;
7558 +       vma->vm_end = addr + PAGE_SIZE;
7559 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
7560 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
7561 +       vma->vm_ops = &pax_vm_ops;
7562 +
7563 +       ret = insert_vm_struct(current->mm, vma);
7564 +       if (ret)
7565 +               return ret;
7566 +
7567 +       ++current->mm->total_vm;
7568 +       return 0;
7569 +}
7570 +#endif
7571 +
7572 +#ifdef CONFIG_PAX_PAGEEXEC
7573 +/*
7574 + * PaX: decide what to do with offenders (regs->nip = fault address)
7575 + *
7576 + * returns 1 when task should be killed
7577 + *         2 when patched GOT trampoline was detected
7578 + *         3 when patched PLT trampoline was detected
7579 + *         4 when unpatched PLT trampoline was detected
7580 + *         5 when sigreturn trampoline was detected
7581 + *         6 when rt_sigreturn trampoline was detected
7582 + */
7583 +static int pax_handle_fetch_fault(struct pt_regs *regs)
7584 +{
7585 +
7586 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
7587 +       int err;
7588 +#endif
7589 +
7590 +#ifdef CONFIG_PAX_EMUPLT
7591 +       do { /* PaX: patched GOT emulation */
7592 +               unsigned int blrl;
7593 +
7594 +               err = get_user(blrl, (unsigned int*)regs->nip);
7595 +
7596 +               if (!err && blrl == 0x4E800021U) {
7597 +                       unsigned long temp = regs->nip;
7598 +
7599 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
7600 +                       regs->link = temp + 4UL;
7601 +                       return 2;
7602 +               }
7603 +       } while (0);
7604 +
7605 +       do { /* PaX: patched PLT emulation #1 */
7606 +               unsigned int b;
7607 +
7608 +               err = get_user(b, (unsigned int *)regs->nip);
7609 +
7610 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
7611 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
7612 +                       return 3;
7613 +               }
7614 +       } while (0);
7615 +
7616 +       do { /* PaX: unpatched PLT emulation #1 */
7617 +               unsigned int li, b;
7618 +
7619 +               err = get_user(li, (unsigned int *)regs->nip);
7620 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
7621 +
7622 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7623 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7624 +                       unsigned long addr = b | 0xFC000000UL;
7625 +
7626 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7627 +                       err = get_user(rlwinm, (unsigned int*)addr);
7628 +                       err |= get_user(add, (unsigned int*)(addr+4));
7629 +                       err |= get_user(li2, (unsigned int*)(addr+8));
7630 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
7631 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
7632 +                       err |= get_user(li3, (unsigned int*)(addr+20));
7633 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
7634 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
7635 +
7636 +                       if (err)
7637 +                               break;
7638 +
7639 +                       if (rlwinm == 0x556C083CU &&
7640 +                           add == 0x7D6C5A14U &&
7641 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
7642 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7643 +                           mtctr == 0x7D8903A6U &&
7644 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
7645 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7646 +                           bctr == 0x4E800420U)
7647 +                       {
7648 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7649 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7650 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7651 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7652 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
7653 +                               regs->nip = regs->ctr;
7654 +                               return 4;
7655 +                       }
7656 +               }
7657 +       } while (0);
7658 +
7659 +#if 0
7660 +       do { /* PaX: unpatched PLT emulation #2 */
7661 +               unsigned int lis, lwzu, b, bctr;
7662 +
7663 +               err = get_user(lis, (unsigned int *)regs->nip);
7664 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
7665 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
7666 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
7667 +
7668 +               if (err)
7669 +                       break;
7670 +
7671 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
7672 +                   (lwzu & 0xU) == 0xU &&
7673 +                   (b & 0xFC000003U) == 0x48000000U &&
7674 +                   bctr == 0x4E800420U)
7675 +               {
7676 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
7677 +                       unsigned long addr = b | 0xFC000000UL;
7678 +
7679 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7680 +                       err = get_user(addis, (unsigned int*)addr);
7681 +                       err |= get_user(addi, (unsigned int*)(addr+4));
7682 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
7683 +                       err |= get_user(add, (unsigned int*)(addr+12));
7684 +                       err |= get_user(li2, (unsigned int*)(addr+16));
7685 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
7686 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
7687 +                       err |= get_user(li3, (unsigned int*)(addr+28));
7688 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
7689 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
7690 +
7691 +                       if (err)
7692 +                               break;
7693 +
7694 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7695 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
7696 +                           rlwinm == 0x556C083CU &&
7697 +                           add == 0x7D6C5A14U &&
7698 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
7699 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
7700 +                           mtctr == 0x7D8903A6U &&
7701 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
7702 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
7703 +                           bctr == 0x4E800420U)
7704 +                       {
7705 +                               regs->gpr[PT_R11] = 
7706 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7707 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7708 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
7709 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7710 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
7711 +                               regs->nip = regs->ctr;
7712 +                               return 4;
7713 +                       }
7714 +               }
7715 +       } while (0);
7716 +#endif
7717 +
7718 +       do { /* PaX: unpatched PLT emulation #3 */
7719 +               unsigned int li, b;
7720 +
7721 +               err = get_user(li, (unsigned int *)regs->nip);
7722 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
7723 +
7724 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
7725 +                       unsigned int addis, lwz, mtctr, bctr;
7726 +                       unsigned long addr = b | 0xFC000000UL;
7727 +
7728 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
7729 +                       err = get_user(addis, (unsigned int*)addr);
7730 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
7731 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
7732 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
7733 +
7734 +                       if (err)
7735 +                               break;
7736 +
7737 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
7738 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
7739 +                           mtctr == 0x7D6903A6U &&
7740 +                           bctr == 0x4E800420U)
7741 +                       {
7742 +                               unsigned int r11;
7743 +
7744 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7745 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
7746 +
7747 +                               err = get_user(r11, (unsigned int*)addr);
7748 +                               if (err)
7749 +                                       break;
7750 +
7751 +                               regs->gpr[PT_R11] = r11;
7752 +                               regs->ctr = r11;
7753 +                               regs->nip = r11;
7754 +                               return 4;
7755 +                       }
7756 +               }
7757 +       } while (0);
7758 +#endif
7759 +
7760 +#ifdef CONFIG_PAX_EMUSIGRT
7761 +       do { /* PaX: sigreturn emulation */
7762 +               unsigned int li, sc;
7763 +
7764 +               err = get_user(li, (unsigned int *)regs->nip);
7765 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
7766 +
7767 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
7768 +                       struct vm_area_struct *vma;
7769 +                       unsigned long call_syscall;
7770 +
7771 +                       down_read(&current->mm->mmap_sem);
7772 +                       call_syscall = current->mm->call_syscall;
7773 +                       up_read(&current->mm->mmap_sem);
7774 +                       if (likely(call_syscall))
7775 +                               goto emulate;
7776 +
7777 +                       vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
7778 +
7779 +                       down_write(&current->mm->mmap_sem);
7780 +                       if (current->mm->call_syscall) {
7781 +                               call_syscall = current->mm->call_syscall;
7782 +                               up_write(&current->mm->mmap_sem);
7783 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7784 +                               goto emulate;
7785 +                       }
7786 +
7787 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7788 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
7789 +                               up_write(&current->mm->mmap_sem);
7790 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7791 +                               return 1;
7792 +                       }
7793 +
7794 +                       if (pax_insert_vma(vma, call_syscall)) {
7795 +                               up_write(&current->mm->mmap_sem);
7796 +                               kmem_cache_free(vm_area_cachep, vma);
7797 +                               return 1;
7798 +                       }
7799 +
7800 +                       current->mm->call_syscall = call_syscall;
7801 +                       up_write(&current->mm->mmap_sem);
7802 +
7803 +emulate:
7804 +                       regs->gpr[PT_R0] = __NR_sigreturn;
7805 +                       regs->nip = call_syscall;
7806 +                       return 5;
7807 +               }
7808 +       } while (0);
7809 +
7810 +       do { /* PaX: rt_sigreturn emulation */
7811 +               unsigned int li, sc;
7812 +
7813 +               err = get_user(li, (unsigned int *)regs->nip);
7814 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
7815 +
7816 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
7817 +                       struct vm_area_struct *vma;
7818 +                       unsigned int call_syscall;
7819 +
7820 +                       down_read(&current->mm->mmap_sem);
7821 +                       call_syscall = current->mm->call_syscall;
7822 +                       up_read(&current->mm->mmap_sem);
7823 +                       if (likely(call_syscall))
7824 +                               goto rt_emulate;
7825 +
7826 +                       vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
7827 +
7828 +                       down_write(&current->mm->mmap_sem);
7829 +                       if (current->mm->call_syscall) {
7830 +                               call_syscall = current->mm->call_syscall;
7831 +                               up_write(&current->mm->mmap_sem);
7832 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7833 +                               goto rt_emulate;
7834 +                       }
7835 +
7836 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
7837 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
7838 +                               up_write(&current->mm->mmap_sem);
7839 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
7840 +                               return 1;
7841 +                       }
7842 +
7843 +                       if (pax_insert_vma(vma, call_syscall)) {
7844 +                               up_write(&current->mm->mmap_sem);
7845 +                               kmem_cache_free(vm_area_cachep, vma);
7846 +                               return 1;
7847 +                       }
7848 +
7849 +                       current->mm->call_syscall = call_syscall;
7850 +                       up_write(&current->mm->mmap_sem);
7851 +
7852 +rt_emulate:
7853 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
7854 +                       regs->nip = call_syscall;
7855 +                       return 6;
7856 +               }
7857 +       } while (0);
7858 +#endif
7859 +
7860 +       return 1;
7861 +}
7862 +
7863 +void pax_report_insns(void *pc, void *sp)
7864 +{
7865 +       unsigned long i;
7866 +
7867 +       printk(KERN_ERR "PAX: bytes at PC: ");
7868 +       for (i = 0; i < 5; i++) {
7869 +               unsigned int c;
7870 +               if (get_user(c, (unsigned int*)pc+i))
7871 +                       printk("???????? ");
7872 +               else
7873 +                       printk("%08x ", c);
7874 +       }
7875 +       printk("\n");
7876 +}
7877 +#endif
7878 +
7879  /*
7880   * Check whether the instruction at regs->nip is a store using
7881   * an update addressing form which will update r1.
7882 @@ -168,7 +532,7 @@ int __kprobes do_page_fault(struct pt_re
7883          * indicate errors in DSISR but can validly be set in SRR1.
7884          */
7885         if (trap == 0x400)
7886 -               error_code &= 0x48200000;
7887 +               error_code &= 0x58200000;
7888         else
7889                 is_write = error_code & DSISR_ISSTORE;
7890  #else
7891 @@ -295,9 +659,9 @@ good_area:
7892                 /* protection fault */
7893                 if (error_code & DSISR_PROTFAULT)
7894                         goto bad_area;
7895 +#endif
7896                 if (!(vma->vm_flags & VM_EXEC))
7897                         goto bad_area;
7898 -#endif
7899  #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
7900                 pte_t *ptep;
7901                 pmd_t *pmdp;
7902 @@ -368,6 +732,37 @@ bad_area:
7903  bad_area_nosemaphore:
7904         /* User mode accesses cause a SIGSEGV */
7905         if (user_mode(regs)) {
7906 +
7907 +#ifdef CONFIG_PAX_PAGEEXEC
7908 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
7909 +#ifdef CONFIG_PPC64
7910 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
7911 +#else
7912 +                       if (is_exec && regs->nip == address) {
7913 +#endif
7914 +                               switch (pax_handle_fetch_fault(regs)) {
7915 +
7916 +#ifdef CONFIG_PAX_EMUPLT
7917 +                               case 2:
7918 +                               case 3:
7919 +                               case 4:
7920 +                                       return 0;
7921 +#endif
7922 +
7923 +#ifdef CONFIG_PAX_EMUSIGRT
7924 +                               case 5:
7925 +                               case 6:
7926 +                                       return 0;
7927 +#endif
7928 +
7929 +                               }
7930 +
7931 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[PT_R1]);
7932 +                               do_exit(SIGKILL);
7933 +                       }
7934 +               }
7935 +#endif
7936 +
7937                 _exception(SIGSEGV, regs, code, address);
7938                 return 0;
7939         }
7940 diff -urNp linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c
7941 --- linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c        2007-03-13 14:27:08.000000000 -0400
7942 +++ linux-2.6.20.3/arch/powerpc/mm/hugetlbpage.c        2007-03-23 08:10:06.000000000 -0400
7943 @@ -568,6 +568,10 @@ unsigned long arch_get_unmapped_area(str
7944         if (len > TASK_SIZE)
7945                 return -ENOMEM;
7946  
7947 +#ifdef CONFIG_PAX_RANDMMAP
7948 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
7949 +#endif
7950 +
7951         if (addr) {
7952                 addr = PAGE_ALIGN(addr);
7953                 vma = find_vma(mm, addr);
7954 @@ -579,7 +583,7 @@ unsigned long arch_get_unmapped_area(str
7955         if (len > mm->cached_hole_size) {
7956                 start_addr = addr = mm->free_area_cache;
7957         } else {
7958 -               start_addr = addr = TASK_UNMAPPED_BASE;
7959 +               start_addr = addr = mm->mmap_base;
7960                 mm->cached_hole_size = 0;
7961         }
7962  
7963 @@ -612,8 +616,8 @@ full_search:
7964         }
7965  
7966         /* Make sure we didn't miss any holes */
7967 -       if (start_addr != TASK_UNMAPPED_BASE) {
7968 -               start_addr = addr = TASK_UNMAPPED_BASE;
7969 +       if (start_addr != mm->mmap_base) {
7970 +               start_addr = addr = mm->mmap_base;
7971                 mm->cached_hole_size = 0;
7972                 goto full_search;
7973         }
7974 @@ -648,6 +652,11 @@ arch_get_unmapped_area_topdown(struct fi
7975                 mm->free_area_cache = base;
7976  
7977         /* requesting a specific address */
7978 +
7979 +#ifdef CONFIG_PAX_RANDMMAP
7980 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
7981 +#endif
7982 +
7983         if (addr) {
7984                 addr = PAGE_ALIGN(addr);
7985                 vma = find_vma(mm, addr);
7986 @@ -727,12 +736,20 @@ fail:
7987          * can happen with large stack limits and large mmap()
7988          * allocations.
7989          */
7990 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
7991 +       mm->mmap_base = TASK_UNMAPPED_BASE;
7992 +
7993 +#ifdef CONFIG_PAX_RANDMMAP
7994 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
7995 +               mm->mmap_base += mm->delta_mmap;
7996 +#endif
7997 +
7998 +       mm->free_area_cache = mm->mmap_base;
7999         mm->cached_hole_size = ~0UL;
8000         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
8001         /*
8002          * Restore the topdown base:
8003          */
8004 +       mm->mmap_base = base;
8005         mm->free_area_cache = base;
8006         mm->cached_hole_size = ~0UL;
8007  
8008 diff -urNp linux-2.6.20.3/arch/powerpc/mm/mmap.c linux-2.6.20.3/arch/powerpc/mm/mmap.c
8009 --- linux-2.6.20.3/arch/powerpc/mm/mmap.c       2007-03-13 14:27:08.000000000 -0400
8010 +++ linux-2.6.20.3/arch/powerpc/mm/mmap.c       2007-03-23 08:10:06.000000000 -0400
8011 @@ -74,10 +74,22 @@ void arch_pick_mmap_layout(struct mm_str
8012          */
8013         if (mmap_is_legacy()) {
8014                 mm->mmap_base = TASK_UNMAPPED_BASE;
8015 +
8016 +#ifdef CONFIG_PAX_RANDMMAP
8017 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
8018 +                       mm->mmap_base += mm->delta_mmap;
8019 +#endif
8020 +
8021                 mm->get_unmapped_area = arch_get_unmapped_area;
8022                 mm->unmap_area = arch_unmap_area;
8023         } else {
8024                 mm->mmap_base = mmap_base();
8025 +
8026 +#ifdef CONFIG_PAX_RANDMMAP
8027 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
8028 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
8029 +#endif
8030 +
8031                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
8032                 mm->unmap_area = arch_unmap_area_topdown;
8033         }
8034 diff -urNp linux-2.6.20.3/arch/ppc/mm/fault.c linux-2.6.20.3/arch/ppc/mm/fault.c
8035 --- linux-2.6.20.3/arch/ppc/mm/fault.c  2007-03-13 14:27:08.000000000 -0400
8036 +++ linux-2.6.20.3/arch/ppc/mm/fault.c  2007-03-23 08:10:06.000000000 -0400
8037 @@ -25,6 +25,11 @@
8038  #include <linux/interrupt.h>
8039  #include <linux/highmem.h>
8040  #include <linux/module.h>
8041 +#include <linux/slab.h>
8042 +#include <linux/pagemap.h>
8043 +#include <linux/compiler.h>
8044 +#include <linux/binfmts.h>
8045 +#include <linux/unistd.h>
8046  
8047  #include <asm/page.h>
8048  #include <asm/pgtable.h>
8049 @@ -48,6 +53,364 @@ unsigned long pte_misses;   /* updated by 
8050  unsigned long pte_errors;      /* updated by do_page_fault() */
8051  unsigned int probingmem;
8052  
8053 +#ifdef CONFIG_PAX_EMUSIGRT
8054 +void pax_syscall_close(struct vm_area_struct * vma)
8055 +{
8056 +       vma->vm_mm->call_syscall = 0UL;
8057 +}
8058 +
8059 +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8060 +{
8061 +       struct page* page;
8062 +       unsigned int *kaddr;
8063 +
8064 +       page = alloc_page(GFP_HIGHUSER);
8065 +       if (!page)
8066 +               return NOPAGE_OOM;
8067 +
8068 +       kaddr = kmap(page);
8069 +       memset(kaddr, 0, PAGE_SIZE);
8070 +       kaddr[0] = 0x44000002U; /* sc */
8071 +       __flush_dcache_icache(kaddr);
8072 +       kunmap(page);
8073 +       if (type)
8074 +               *type = VM_FAULT_MAJOR;
8075 +       return page;
8076 +}
8077 +
8078 +static struct vm_operations_struct pax_vm_ops = {
8079 +       .close = pax_syscall_close,
8080 +       .nopage = pax_syscall_nopage,
8081 +};
8082 +
8083 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8084 +{
8085 +       int ret;
8086 +
8087 +       memset(vma, 0, sizeof(*vma));
8088 +       vma->vm_mm = current->mm;
8089 +       vma->vm_start = addr;
8090 +       vma->vm_end = addr + PAGE_SIZE;
8091 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8092 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
8093 +       vma->vm_ops = &pax_vm_ops;
8094 +
8095 +       ret = insert_vm_struct(current->mm, vma);
8096 +       if (ret)
8097 +               return ret;
8098 +
8099 +       ++current->mm->total_vm;
8100 +       return 0;
8101 +}
8102 +#endif
8103 +
8104 +#ifdef CONFIG_PAX_PAGEEXEC
8105 +/*
8106 + * PaX: decide what to do with offenders (regs->nip = fault address)
8107 + *
8108 + * returns 1 when task should be killed
8109 + *         2 when patched GOT trampoline was detected
8110 + *         3 when patched PLT trampoline was detected
8111 + *         4 when unpatched PLT trampoline was detected
8112 + *         5 when sigreturn trampoline was detected
8113 + *         6 when rt_sigreturn trampoline was detected
8114 + */
8115 +static int pax_handle_fetch_fault(struct pt_regs *regs)
8116 +{
8117 +
8118 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
8119 +       int err;
8120 +#endif
8121 +
8122 +#ifdef CONFIG_PAX_EMUPLT
8123 +       do { /* PaX: patched GOT emulation */
8124 +               unsigned int blrl;
8125 +
8126 +               err = get_user(blrl, (unsigned int*)regs->nip);
8127 +
8128 +               if (!err && blrl == 0x4E800021U) {
8129 +                       unsigned long temp = regs->nip;
8130 +
8131 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
8132 +                       regs->link = temp + 4UL;
8133 +                       return 2;
8134 +               }
8135 +       } while (0);
8136 +
8137 +       do { /* PaX: patched PLT emulation #1 */
8138 +               unsigned int b;
8139 +
8140 +               err = get_user(b, (unsigned int *)regs->nip);
8141 +
8142 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
8143 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
8144 +                       return 3;
8145 +               }
8146 +       } while (0);
8147 +
8148 +       do { /* PaX: unpatched PLT emulation #1 */
8149 +               unsigned int li, b;
8150 +
8151 +               err = get_user(li, (unsigned int *)regs->nip);
8152 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
8153 +
8154 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8155 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8156 +                       unsigned long addr = b | 0xFC000000UL;
8157 +
8158 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8159 +                       err = get_user(rlwinm, (unsigned int*)addr);
8160 +                       err |= get_user(add, (unsigned int*)(addr+4));
8161 +                       err |= get_user(li2, (unsigned int*)(addr+8));
8162 +                       err |= get_user(addis2, (unsigned int*)(addr+12));
8163 +                       err |= get_user(mtctr, (unsigned int*)(addr+16));
8164 +                       err |= get_user(li3, (unsigned int*)(addr+20));
8165 +                       err |= get_user(addis3, (unsigned int*)(addr+24));
8166 +                       err |= get_user(bctr, (unsigned int*)(addr+28));
8167 +
8168 +                       if (err)
8169 +                               break;
8170 +
8171 +                       if (rlwinm == 0x556C083CU &&
8172 +                           add == 0x7D6C5A14U &&
8173 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
8174 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8175 +                           mtctr == 0x7D8903A6U &&
8176 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
8177 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8178 +                           bctr == 0x4E800420U)
8179 +                       {
8180 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8181 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8182 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8183 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8184 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
8185 +                               regs->nip = regs->ctr;
8186 +                               return 4;
8187 +                       }
8188 +               }
8189 +       } while (0);
8190 +
8191 +#if 0
8192 +       do { /* PaX: unpatched PLT emulation #2 */
8193 +               unsigned int lis, lwzu, b, bctr;
8194 +
8195 +               err = get_user(lis, (unsigned int *)regs->nip);
8196 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
8197 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
8198 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
8199 +
8200 +               if (err)
8201 +                       break;
8202 +
8203 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
8204 +                   (lwzu & 0xU) == 0xU &&
8205 +                   (b & 0xFC000003U) == 0x48000000U &&
8206 +                   bctr == 0x4E800420U)
8207 +               {
8208 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
8209 +                       unsigned long addr = b | 0xFC000000UL;
8210 +
8211 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8212 +                       err = get_user(addis, (unsigned int*)addr);
8213 +                       err |= get_user(addi, (unsigned int*)(addr+4));
8214 +                       err |= get_user(rlwinm, (unsigned int*)(addr+8));
8215 +                       err |= get_user(add, (unsigned int*)(addr+12));
8216 +                       err |= get_user(li2, (unsigned int*)(addr+16));
8217 +                       err |= get_user(addis2, (unsigned int*)(addr+20));
8218 +                       err |= get_user(mtctr, (unsigned int*)(addr+24));
8219 +                       err |= get_user(li3, (unsigned int*)(addr+28));
8220 +                       err |= get_user(addis3, (unsigned int*)(addr+32));
8221 +                       err |= get_user(bctr, (unsigned int*)(addr+36));
8222 +
8223 +                       if (err)
8224 +                               break;
8225 +
8226 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8227 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
8228 +                           rlwinm == 0x556C083CU &&
8229 +                           add == 0x7D6C5A14U &&
8230 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
8231 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
8232 +                           mtctr == 0x7D8903A6U &&
8233 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
8234 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
8235 +                           bctr == 0x4E800420U)
8236 +                       {
8237 +                               regs->gpr[PT_R11] = 
8238 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8239 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8240 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
8241 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8242 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
8243 +                               regs->nip = regs->ctr;
8244 +                               return 4;
8245 +                       }
8246 +               }
8247 +       } while (0);
8248 +#endif
8249 +
8250 +       do { /* PaX: unpatched PLT emulation #3 */
8251 +               unsigned int li, b;
8252 +
8253 +               err = get_user(li, (unsigned int *)regs->nip);
8254 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
8255 +
8256 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
8257 +                       unsigned int addis, lwz, mtctr, bctr;
8258 +                       unsigned long addr = b | 0xFC000000UL;
8259 +
8260 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
8261 +                       err = get_user(addis, (unsigned int*)addr);
8262 +                       err |= get_user(lwz, (unsigned int*)(addr+4));
8263 +                       err |= get_user(mtctr, (unsigned int*)(addr+8));
8264 +                       err |= get_user(bctr, (unsigned int*)(addr+12));
8265 +
8266 +                       if (err)
8267 +                               break;
8268 +
8269 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
8270 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
8271 +                           mtctr == 0x7D6903A6U &&
8272 +                           bctr == 0x4E800420U)
8273 +                       {
8274 +                               unsigned int r11;
8275 +
8276 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8277 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
8278 +
8279 +                               err = get_user(r11, (unsigned int*)addr);
8280 +                               if (err)
8281 +                                       break;
8282 +
8283 +                               regs->gpr[PT_R11] = r11;
8284 +                               regs->ctr = r11;
8285 +                               regs->nip = r11;
8286 +                               return 4;
8287 +                       }
8288 +               }
8289 +       } while (0);
8290 +#endif
8291 +
8292 +#ifdef CONFIG_PAX_EMUSIGRT
8293 +       do { /* PaX: sigreturn emulation */
8294 +               unsigned int li, sc;
8295 +
8296 +               err = get_user(li, (unsigned int *)regs->nip);
8297 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
8298 +
8299 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
8300 +                       struct vm_area_struct *vma;
8301 +                       unsigned long call_syscall;
8302 +
8303 +                       down_read(&current->mm->mmap_sem);
8304 +                       call_syscall = current->mm->call_syscall;
8305 +                       up_read(&current->mm->mmap_sem);
8306 +                       if (likely(call_syscall))
8307 +                               goto emulate;
8308 +
8309 +                       vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8310 +
8311 +                       down_write(&current->mm->mmap_sem);
8312 +                       if (current->mm->call_syscall) {
8313 +                               call_syscall = current->mm->call_syscall;
8314 +                               up_write(&current->mm->mmap_sem);
8315 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
8316 +                               goto emulate;
8317 +                       }
8318 +
8319 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8320 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
8321 +                               up_write(&current->mm->mmap_sem);
8322 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
8323 +                               return 1;
8324 +                       }
8325 +
8326 +                       if (pax_insert_vma(vma, call_syscall)) {
8327 +                               up_write(&current->mm->mmap_sem);
8328 +                               kmem_cache_free(vm_area_cachep, vma);
8329 +                               return 1;
8330 +                       }
8331 +
8332 +                       current->mm->call_syscall = call_syscall;
8333 +                       up_write(&current->mm->mmap_sem);
8334 +
8335 +emulate:
8336 +                       regs->gpr[PT_R0] = __NR_sigreturn;
8337 +                       regs->nip = call_syscall;
8338 +                       return 5;
8339 +               }
8340 +       } while (0);
8341 +
8342 +       do { /* PaX: rt_sigreturn emulation */
8343 +               unsigned int li, sc;
8344 +
8345 +               err = get_user(li, (unsigned int *)regs->nip);
8346 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
8347 +
8348 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
8349 +                       struct vm_area_struct *vma;
8350 +                       unsigned int call_syscall;
8351 +
8352 +                       down_read(&current->mm->mmap_sem);
8353 +                       call_syscall = current->mm->call_syscall;
8354 +                       up_read(&current->mm->mmap_sem);
8355 +                       if (likely(call_syscall))
8356 +                               goto rt_emulate;
8357 +
8358 +                       vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8359 +
8360 +                       down_write(&current->mm->mmap_sem);
8361 +                       if (current->mm->call_syscall) {
8362 +                               call_syscall = current->mm->call_syscall;
8363 +                               up_write(&current->mm->mmap_sem);
8364 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
8365 +                               goto rt_emulate;
8366 +                       }
8367 +
8368 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8369 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
8370 +                               up_write(&current->mm->mmap_sem);
8371 +                               if (vma) kmem_cache_free(vm_area_cachep, vma);
8372 +                               return 1;
8373 +                       }
8374 +
8375 +                       if (pax_insert_vma(vma, call_syscall)) {
8376 +                               up_write(&current->mm->mmap_sem);
8377 +                               kmem_cache_free(vm_area_cachep, vma);
8378 +                               return 1;
8379 +                       }
8380 +
8381 +                       current->mm->call_syscall = call_syscall;
8382 +                       up_write(&current->mm->mmap_sem);
8383 +
8384 +rt_emulate:
8385 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
8386 +                       regs->nip = call_syscall;
8387 +                       return 6;
8388 +               }
8389 +       } while (0);
8390 +#endif
8391 +
8392 +       return 1;
8393 +}
8394 +
8395 +void pax_report_insns(void *pc, void *sp)
8396 +{
8397 +       unsigned long i;
8398 +
8399 +       printk(KERN_ERR "PAX: bytes at PC: ");
8400 +       for (i = 0; i < 5; i++) {
8401 +               unsigned int c;
8402 +               if (get_user(c, (unsigned int*)pc+i))
8403 +                       printk("???????? ");
8404 +               else
8405 +                       printk("%08x ", c);
8406 +       }
8407 +       printk("\n");
8408 +}
8409 +#endif
8410 +
8411  /*
8412   * Check whether the instruction at regs->nip is a store using
8413   * an update addressing form which will update r1.
8414 @@ -108,7 +471,7 @@ int do_page_fault(struct pt_regs *regs, 
8415          * indicate errors in DSISR but can validly be set in SRR1.
8416          */
8417         if (TRAP(regs) == 0x400)
8418 -               error_code &= 0x48200000;
8419 +               error_code &= 0x58200000;
8420         else
8421                 is_write = error_code & 0x02000000;
8422  #endif /* CONFIG_4xx || CONFIG_BOOKE */
8423 @@ -203,15 +566,14 @@ good_area:
8424                 pte_t *ptep;
8425                 pmd_t *pmdp;
8426  
8427 -#if 0
8428 +#if 1
8429                 /* It would be nice to actually enforce the VM execute
8430                    permission on CPUs which can do so, but far too
8431                    much stuff in userspace doesn't get the permissions
8432                    right, so we let any page be executed for now. */
8433                 if (! (vma->vm_flags & VM_EXEC))
8434                         goto bad_area;
8435 -#endif
8436 -
8437 +#else
8438                 /* Since 4xx/Book-E supports per-page execute permission,
8439                  * we lazily flush dcache to icache. */
8440                 ptep = NULL;
8441 @@ -234,6 +596,7 @@ good_area:
8442                         pte_unmap_unlock(ptep, ptl);
8443                 }
8444  #endif
8445 +#endif
8446         /* a read */
8447         } else {
8448                 /* protection fault */
8449 @@ -279,6 +642,33 @@ bad_area:
8450  
8451         /* User mode accesses cause a SIGSEGV */
8452         if (user_mode(regs)) {
8453 +
8454 +#ifdef CONFIG_PAX_PAGEEXEC
8455 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
8456 +                       if ((TRAP(regs) == 0x400) && (regs->nip == address)) {
8457 +                               switch (pax_handle_fetch_fault(regs)) {
8458 +
8459 +#ifdef CONFIG_PAX_EMUPLT
8460 +                               case 2:
8461 +                               case 3:
8462 +                               case 4:
8463 +                                       return 0;
8464 +#endif
8465 +
8466 +#ifdef CONFIG_PAX_EMUSIGRT
8467 +                               case 5:
8468 +                               case 6:
8469 +                                       return 0;
8470 +#endif
8471 +
8472 +                               }
8473 +
8474 +                               pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]);
8475 +                               do_exit(SIGKILL);
8476 +                       }
8477 +               }
8478 +#endif
8479 +
8480                 _exception(SIGSEGV, regs, code, address);
8481                 return 0;
8482         }
8483 diff -urNp linux-2.6.20.3/arch/s390/kernel/module.c linux-2.6.20.3/arch/s390/kernel/module.c
8484 --- linux-2.6.20.3/arch/s390/kernel/module.c    2007-03-13 14:27:08.000000000 -0400
8485 +++ linux-2.6.20.3/arch/s390/kernel/module.c    2007-03-23 08:10:06.000000000 -0400
8486 @@ -164,11 +164,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
8487  
8488         /* Increase core size by size of got & plt and set start
8489            offsets for got and plt. */
8490 -       me->core_size = ALIGN(me->core_size, 4);
8491 -       me->arch.got_offset = me->core_size;
8492 -       me->core_size += me->arch.got_size;
8493 -       me->arch.plt_offset = me->core_size;
8494 -       me->core_size += me->arch.plt_size;
8495 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
8496 +       me->arch.got_offset = me->core_size_rw;
8497 +       me->core_size_rw += me->arch.got_size;
8498 +       me->arch.plt_offset = me->core_size_rx;
8499 +       me->core_size_rx += me->arch.plt_size;
8500         return 0;
8501  }
8502  
8503 @@ -254,7 +254,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8504                 if (info->got_initialized == 0) {
8505                         Elf_Addr *gotent;
8506  
8507 -                       gotent = me->module_core + me->arch.got_offset +
8508 +                       gotent = me->module_core_rw + me->arch.got_offset +
8509                                 info->got_offset;
8510                         *gotent = val;
8511                         info->got_initialized = 1;
8512 @@ -278,7 +278,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8513                 else if (r_type == R_390_GOTENT ||
8514                          r_type == R_390_GOTPLTENT)
8515                         *(unsigned int *) loc =
8516 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
8517 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
8518                 else if (r_type == R_390_GOT64 ||
8519                          r_type == R_390_GOTPLT64)
8520                         *(unsigned long *) loc = val;
8521 @@ -292,7 +292,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8522         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
8523                 if (info->plt_initialized == 0) {
8524                         unsigned int *ip;
8525 -                       ip = me->module_core + me->arch.plt_offset +
8526 +                       ip = me->module_core_rx + me->arch.plt_offset +
8527                                 info->plt_offset;
8528  #ifndef CONFIG_64BIT
8529                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
8530 @@ -314,7 +314,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8531                         val = me->arch.plt_offset - me->arch.got_offset +
8532                                 info->plt_offset + rela->r_addend;
8533                 else
8534 -                       val =  (Elf_Addr) me->module_core +
8535 +                       val =  (Elf_Addr) me->module_core_rx +
8536                                 me->arch.plt_offset + info->plt_offset + 
8537                                 rela->r_addend - loc;
8538                 if (r_type == R_390_PLT16DBL)
8539 @@ -334,7 +334,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8540         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
8541         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
8542                 val = val + rela->r_addend -
8543 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
8544 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
8545                 if (r_type == R_390_GOTOFF16)
8546                         *(unsigned short *) loc = val;
8547                 else if (r_type == R_390_GOTOFF32)
8548 @@ -344,7 +344,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
8549                 break;
8550         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
8551         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
8552 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
8553 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
8554                         rela->r_addend - loc;
8555                 if (r_type == R_390_GOTPC)
8556                         *(unsigned int *) loc = val;
8557 diff -urNp linux-2.6.20.3/arch/sparc/kernel/ptrace.c linux-2.6.20.3/arch/sparc/kernel/ptrace.c
8558 --- linux-2.6.20.3/arch/sparc/kernel/ptrace.c   2007-03-13 14:27:08.000000000 -0400
8559 +++ linux-2.6.20.3/arch/sparc/kernel/ptrace.c   2007-03-23 08:11:18.000000000 -0400
8560 @@ -20,6 +20,7 @@
8561  #include <linux/security.h>
8562  #include <linux/signal.h>
8563  #include <linux/vs_base.h>
8564 +#include <linux/grsecurity.h>
8565  
8566  #include <asm/pgtable.h>
8567  #include <asm/system.h>
8568 @@ -308,6 +309,11 @@ asmlinkage void do_ptrace(struct pt_regs
8569                 goto out_tsk;
8570         }
8571  
8572 +       if (gr_handle_ptrace(child, request)) {
8573 +               pt_error_return(regs, EPERM);
8574 +               goto out_tsk;
8575 +       }
8576 +
8577         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
8578             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
8579                 if (ptrace_attach(child)) {
8580 diff -urNp linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c
8581 --- linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c        2007-03-13 14:27:08.000000000 -0400
8582 +++ linux-2.6.20.3/arch/sparc/kernel/sys_sparc.c        2007-03-23 08:10:06.000000000 -0400
8583 @@ -57,7 +57,7 @@ unsigned long arch_get_unmapped_area(str
8584         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
8585                 return -ENOMEM;
8586         if (!addr)
8587 -               addr = TASK_UNMAPPED_BASE;
8588 +               addr = current->mm->mmap_base;
8589  
8590         if (flags & MAP_SHARED)
8591                 addr = COLOUR_ALIGN(addr);
8592 diff -urNp linux-2.6.20.3/arch/sparc/Makefile linux-2.6.20.3/arch/sparc/Makefile
8593 --- linux-2.6.20.3/arch/sparc/Makefile  2007-03-13 14:27:08.000000000 -0400
8594 +++ linux-2.6.20.3/arch/sparc/Makefile  2007-03-23 08:11:18.000000000 -0400
8595 @@ -36,7 +36,7 @@ drivers-$(CONFIG_OPROFILE)    += arch/sparc
8596  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
8597  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
8598  CORE_Y         := $(core-y)
8599 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
8600 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
8601  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
8602  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
8603  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
8604 diff -urNp linux-2.6.20.3/arch/sparc/mm/fault.c linux-2.6.20.3/arch/sparc/mm/fault.c
8605 --- linux-2.6.20.3/arch/sparc/mm/fault.c        2007-03-13 14:27:08.000000000 -0400
8606 +++ linux-2.6.20.3/arch/sparc/mm/fault.c        2007-03-23 08:10:06.000000000 -0400
8607 @@ -21,6 +21,10 @@
8608  #include <linux/smp_lock.h>
8609  #include <linux/interrupt.h>
8610  #include <linux/module.h>
8611 +#include <linux/slab.h>
8612 +#include <linux/pagemap.h>
8613 +#include <linux/compiler.h>
8614 +#include <linux/binfmts.h>
8615  
8616  #include <asm/system.h>
8617  #include <asm/page.h>
8618 @@ -217,6 +221,252 @@ static unsigned long compute_si_addr(str
8619         return safe_compute_effective_address(regs, insn);
8620  }
8621  
8622 +#ifdef CONFIG_PAX_PAGEEXEC
8623 +void pax_emuplt_close(struct vm_area_struct * vma)
8624 +{
8625 +       vma->vm_mm->call_dl_resolve = 0UL;
8626 +}
8627 +
8628 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
8629 +{
8630 +       struct page* page;
8631 +       unsigned int *kaddr;
8632 +
8633 +       page = alloc_page(GFP_HIGHUSER);
8634 +       if (!page)
8635 +               return NOPAGE_OOM;
8636 +
8637 +       kaddr = kmap(page);
8638 +       memset(kaddr, 0, PAGE_SIZE);
8639 +       kaddr[0] = 0x9DE3BFA8U; /* save */
8640 +       flush_dcache_page(page);
8641 +       kunmap(page);
8642 +       if (type)
8643 +               *type = VM_FAULT_MAJOR;
8644 +
8645 +       return page;
8646 +}
8647 +
8648 +static struct vm_operations_struct pax_vm_ops = {
8649 +       .close = pax_emuplt_close,
8650 +       .nopage = pax_emuplt_nopage,
8651 +};
8652 +
8653 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
8654 +{
8655 +       int ret;
8656 +
8657 +       memset(vma, 0, sizeof(*vma));
8658 +       vma->vm_mm = current->mm;
8659 +       vma->vm_start = addr;
8660 +       vma->vm_end = addr + PAGE_SIZE;
8661 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
8662 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
8663 +       vma->vm_ops = &pax_vm_ops;
8664 +
8665 +       ret = insert_vm_struct(current->mm, vma);
8666 +       if (ret)
8667 +               return ret;
8668 +
8669 +       ++current->mm->total_vm;
8670 +       return 0;
8671 +}
8672 +
8673 +/*
8674 + * PaX: decide what to do with offenders (regs->pc = fault address)
8675 + *
8676 + * returns 1 when task should be killed
8677 + *         2 when patched PLT trampoline was detected
8678 + *         3 when unpatched PLT trampoline was detected
8679 + */
8680 +static int pax_handle_fetch_fault(struct pt_regs *regs)
8681 +{
8682 +
8683 +#ifdef CONFIG_PAX_EMUPLT
8684 +       int err;
8685 +
8686 +       do { /* PaX: patched PLT emulation #1 */
8687 +               unsigned int sethi1, sethi2, jmpl;
8688 +
8689 +               err = get_user(sethi1, (unsigned int*)regs->pc);
8690 +               err |= get_user(sethi2, (unsigned int*)(regs->pc+4));
8691 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+8));
8692 +
8693 +               if (err)
8694 +                       break;
8695 +
8696 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
8697 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
8698 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
8699 +               {
8700 +                       unsigned int addr;
8701 +
8702 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
8703 +                       addr = regs->u_regs[UREG_G1];
8704 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
8705 +                       regs->pc = addr;
8706 +                       regs->npc = addr+4;
8707 +                       return 2;
8708 +               }
8709 +       } while (0);
8710 +
8711 +       { /* PaX: patched PLT emulation #2 */
8712 +               unsigned int ba;
8713 +
8714 +               err = get_user(ba, (unsigned int*)regs->pc);
8715 +
8716 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
8717 +                       unsigned int addr;
8718 +
8719 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
8720 +                       regs->pc = addr;
8721 +                       regs->npc = addr+4;
8722 +                       return 2;
8723 +               }
8724 +       }
8725 +
8726 +       do { /* PaX: patched PLT emulation #3 */
8727 +               unsigned int sethi, jmpl, nop;
8728 +
8729 +               err = get_user(sethi, (unsigned int*)regs->pc);
8730 +               err |= get_user(jmpl, (unsigned int*)(regs->pc+4));
8731 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
8732 +
8733 +               if (err)
8734 +                       break;
8735 +
8736 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
8737 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
8738 +                   nop == 0x01000000U)
8739 +               {
8740 +                       unsigned int addr;
8741 +
8742 +                       addr = (sethi & 0x003FFFFFU) << 10;
8743 +                       regs->u_regs[UREG_G1] = addr;
8744 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
8745 +                       regs->pc = addr;
8746 +                       regs->npc = addr+4;
8747 +                       return 2;
8748 +               }
8749 +       } while (0);
8750 +
8751 +       do { /* PaX: unpatched PLT emulation step 1 */
8752 +               unsigned int sethi, ba, nop;
8753 +
8754 +               err = get_user(sethi, (unsigned int*)regs->pc);
8755 +               err |= get_user(ba, (unsigned int*)(regs->pc+4));
8756 +               err |= get_user(nop, (unsigned int*)(regs->pc+8));
8757 +
8758 +               if (err)
8759 +                       break;
8760 +
8761 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
8762 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
8763 +                   nop == 0x01000000U)
8764 +               {
8765 +                       unsigned int addr, save, call;
8766 +
8767 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
8768 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
8769 +                       else
8770 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
8771 +
8772 +                       err = get_user(save, (unsigned int*)addr);
8773 +                       err |= get_user(call, (unsigned int*)(addr+4));
8774 +                       err |= get_user(nop, (unsigned int*)(addr+8));
8775 +                       if (err)
8776 +                               break;
8777 +
8778 +                       if (save == 0x9DE3BFA8U &&
8779 +                           (call & 0xC0000000U) == 0x40000000U &&
8780 +                           nop == 0x01000000U)
8781 +                       {
8782 +                               struct vm_area_struct *vma;
8783 +                               unsigned long call_dl_resolve;
8784 +
8785 +                               down_read(&current->mm->mmap_sem);
8786 +                               call_dl_resolve = current->mm->call_dl_resolve;
8787 +                               up_read(&current->mm->mmap_sem);
8788 +                               if (likely(call_dl_resolve))
8789 +                                       goto emulate;
8790 +
8791 +                               vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
8792 +
8793 +                               down_write(&current->mm->mmap_sem);
8794 +                               if (current->mm->call_dl_resolve) {
8795 +                                       call_dl_resolve = current->mm->call_dl_resolve;
8796 +                                       up_write(&current->mm->mmap_sem);
8797 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
8798 +                                       goto emulate;
8799 +                               }
8800 +
8801 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
8802 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
8803 +                                       up_write(&current->mm->mmap_sem);
8804 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
8805 +                                       return 1;
8806 +                               }
8807 +
8808 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
8809 +                                       up_write(&current->mm->mmap_sem);
8810 +                                       kmem_cache_free(vm_area_cachep, vma);
8811 +                                       return 1;
8812 +                               }
8813 +
8814 +                               current->mm->call_dl_resolve = call_dl_resolve;
8815 +                               up_write(&current->mm->mmap_sem);
8816 +
8817 +emulate:
8818 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
8819 +                               regs->pc = call_dl_resolve;
8820 +                               regs->npc = addr+4;
8821 +                               return 3;
8822 +                       }
8823 +               }
8824 +       } while (0);
8825 +
8826 +       do { /* PaX: unpatched PLT emulation step 2 */
8827 +               unsigned int save, call, nop;
8828 +
8829 +               err = get_user(save, (unsigned int*)(regs->pc-4));
8830 +               err |= get_user(call, (unsigned int*)regs->pc);
8831 +               err |= get_user(nop, (unsigned int*)(regs->pc+4));
8832 +               if (err)
8833 +                       break;
8834 +
8835 +               if (save == 0x9DE3BFA8U &&
8836 +                   (call & 0xC0000000U) == 0x40000000U &&
8837 +                   nop == 0x01000000U)
8838 +               {
8839 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
8840 +
8841 +                       regs->u_regs[UREG_RETPC] = regs->pc;
8842 +                       regs->pc = dl_resolve;
8843 +                       regs->npc = dl_resolve+4;
8844 +                       return 3;
8845 +               }
8846 +       } while (0);
8847 +#endif
8848 +
8849 +       return 1;
8850 +}
8851 +
8852 +void pax_report_insns(void *pc, void *sp)
8853 +{
8854 +       unsigned long i;
8855 +
8856 +       printk(KERN_ERR "PAX: bytes at PC: ");
8857 +       for (i = 0; i < 5; i++) {
8858 +               unsigned int c;
8859 +               if (get_user(c, (unsigned int*)pc+i))
8860 +                       printk("???????? ");
8861 +               else
8862 +                       printk("%08x ", c);
8863 +       }
8864 +       printk("\n");
8865 +}
8866 +#endif
8867 +
8868  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
8869                                unsigned long address)
8870  {
8871 @@ -280,6 +530,24 @@ good_area:
8872                 if(!(vma->vm_flags & VM_WRITE))
8873                         goto bad_area;
8874         } else {
8875 +
8876 +#ifdef CONFIG_PAX_PAGEEXEC
8877 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
8878 +                       up_read(&mm->mmap_sem);
8879 +                       switch (pax_handle_fetch_fault(regs)) {
8880 +
8881 +#ifdef CONFIG_PAX_EMUPLT
8882 +                       case 2:
8883 +                       case 3:
8884 +                               return;
8885 +#endif
8886 +
8887 +                       }
8888 +                       pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]);
8889 +                       do_exit(SIGKILL);
8890 +               }
8891 +#endif
8892 +
8893                 /* Allow reads even for write-only mappings */
8894                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
8895                         goto bad_area;
8896 diff -urNp linux-2.6.20.3/arch/sparc/mm/init.c linux-2.6.20.3/arch/sparc/mm/init.c
8897 --- linux-2.6.20.3/arch/sparc/mm/init.c 2007-03-13 14:27:08.000000000 -0400
8898 +++ linux-2.6.20.3/arch/sparc/mm/init.c 2007-03-23 08:10:06.000000000 -0400
8899 @@ -333,17 +333,17 @@ void __init paging_init(void)
8900  
8901         /* Initialize the protection map with non-constant, MMU dependent values. */
8902         protection_map[0] = PAGE_NONE;
8903 -       protection_map[1] = PAGE_READONLY;
8904 -       protection_map[2] = PAGE_COPY;
8905 -       protection_map[3] = PAGE_COPY;
8906 +       protection_map[1] = PAGE_READONLY_NOEXEC;
8907 +       protection_map[2] = PAGE_COPY_NOEXEC;
8908 +       protection_map[3] = PAGE_COPY_NOEXEC;
8909         protection_map[4] = PAGE_READONLY;
8910         protection_map[5] = PAGE_READONLY;
8911         protection_map[6] = PAGE_COPY;
8912         protection_map[7] = PAGE_COPY;
8913         protection_map[8] = PAGE_NONE;
8914 -       protection_map[9] = PAGE_READONLY;
8915 -       protection_map[10] = PAGE_SHARED;
8916 -       protection_map[11] = PAGE_SHARED;
8917 +       protection_map[9] = PAGE_READONLY_NOEXEC;
8918 +       protection_map[10] = PAGE_SHARED_NOEXEC;
8919 +       protection_map[11] = PAGE_SHARED_NOEXEC;
8920         protection_map[12] = PAGE_READONLY;
8921         protection_map[13] = PAGE_READONLY;
8922         protection_map[14] = PAGE_SHARED;
8923 diff -urNp linux-2.6.20.3/arch/sparc/mm/srmmu.c linux-2.6.20.3/arch/sparc/mm/srmmu.c
8924 --- linux-2.6.20.3/arch/sparc/mm/srmmu.c        2007-03-13 14:27:08.000000000 -0400
8925 +++ linux-2.6.20.3/arch/sparc/mm/srmmu.c        2007-03-23 08:10:06.000000000 -0400
8926 @@ -2160,6 +2160,13 @@ void __init ld_mmu_srmmu(void)
8927         BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED));
8928         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
8929         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
8930 +
8931 +#ifdef CONFIG_PAX_PAGEEXEC
8932 +       BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC));
8933 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
8934 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
8935 +#endif
8936 +
8937         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
8938         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
8939  
8940 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/Makefile linux-2.6.20.3/arch/sparc64/kernel/Makefile
8941 --- linux-2.6.20.3/arch/sparc64/kernel/Makefile 2007-03-13 14:27:08.000000000 -0400
8942 +++ linux-2.6.20.3/arch/sparc64/kernel/Makefile 2007-03-23 08:10:06.000000000 -0400
8943 @@ -3,7 +3,7 @@
8944  #
8945  
8946  EXTRA_AFLAGS := -ansi
8947 -EXTRA_CFLAGS := -Werror
8948 +#EXTRA_CFLAGS := -Werror
8949  
8950  extra-y                := head.o init_task.o vmlinux.lds
8951  
8952 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c
8953 --- linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c      2007-03-13 14:27:08.000000000 -0400
8954 +++ linux-2.6.20.3/arch/sparc64/kernel/pci_iommu.c      2007-03-23 08:10:06.000000000 -0400
8955 @@ -64,7 +64,7 @@ static void __iommu_flushall(struct pci_
8956  #define IOPTE_IS_DUMMY(iommu, iopte)   \
8957         ((iopte_val(*iopte) & IOPTE_PAGE) == (iommu)->dummy_page_pa)
8958  
8959 -static void inline iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
8960 +inline static void iopte_make_dummy(struct pci_iommu *iommu, iopte_t *iopte)
8961  {
8962         unsigned long val = iopte_val(*iopte);
8963  
8964 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/ptrace.c linux-2.6.20.3/arch/sparc64/kernel/ptrace.c
8965 --- linux-2.6.20.3/arch/sparc64/kernel/ptrace.c 2007-03-13 14:27:08.000000000 -0400
8966 +++ linux-2.6.20.3/arch/sparc64/kernel/ptrace.c 2007-03-23 08:11:31.000000000 -0400
8967 @@ -23,6 +23,7 @@
8968  #include <linux/audit.h>
8969  #include <linux/signal.h>
8970  #include <linux/vs_base.h>
8971 +#include <linux/grsecurity.h>
8972  
8973  #include <asm/asi.h>
8974  #include <asm/pgtable.h>
8975 @@ -221,6 +222,11 @@ asmlinkage void do_ptrace(struct pt_regs
8976                 goto out_tsk;
8977         }
8978  
8979 +       if (gr_handle_ptrace(child, (long)request)) {
8980 +               pt_error_return(regs, EPERM);
8981 +               goto out_tsk;
8982 +       }
8983 +
8984         if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
8985             || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
8986                 if (ptrace_attach(child)) {
8987 diff -urNp linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c
8988 --- linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c      2007-03-13 14:27:08.000000000 -0400
8989 +++ linux-2.6.20.3/arch/sparc64/kernel/sys_sparc.c      2007-03-23 08:10:06.000000000 -0400
8990 @@ -140,6 +140,10 @@ unsigned long arch_get_unmapped_area(str
8991         if (filp || (flags & MAP_SHARED))
8992                 do_color_align = 1;
8993  
8994 +#ifdef CONFIG_PAX_RANDMMAP
8995 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
8996 +#endif
8997 +
8998         if (addr) {
8999                 if (do_color_align)
9000                         addr = COLOUR_ALIGN(addr, pgoff);
9001 @@ -153,9 +157,9 @@ unsigned long arch_get_unmapped_area(str
9002         }
9003  
9004         if (len > mm->cached_hole_size) {
9005 -               start_addr = addr = mm->free_area_cache;
9006 +               start_addr = addr = mm->free_area_cache;
9007         } else {
9008 -               start_addr = addr = TASK_UNMAPPED_BASE;
9009 +               start_addr = addr = mm->mmap_base;
9010                 mm->cached_hole_size = 0;
9011         }
9012  
9013 @@ -175,8 +179,8 @@ full_search:
9014                         vma = find_vma(mm, VA_EXCLUDE_END);
9015                 }
9016                 if (unlikely(task_size < addr)) {
9017 -                       if (start_addr != TASK_UNMAPPED_BASE) {
9018 -                               start_addr = addr = TASK_UNMAPPED_BASE;
9019 +                       if (start_addr != mm->mmap_base) {
9020 +                               start_addr = addr = mm->mmap_base;
9021                                 mm->cached_hole_size = 0;
9022                                 goto full_search;
9023                         }
9024 @@ -379,6 +383,12 @@ void arch_pick_mmap_layout(struct mm_str
9025             current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
9026             sysctl_legacy_va_layout) {
9027                 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
9028 +
9029 +#ifdef CONFIG_PAX_RANDMMAP
9030 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
9031 +                       mm->mmap_base += mm->delta_mmap;
9032 +#endif
9033 +
9034                 mm->get_unmapped_area = arch_get_unmapped_area;
9035                 mm->unmap_area = arch_unmap_area;
9036         } else {
9037 @@ -393,6 +403,12 @@ void arch_pick_mmap_layout(struct mm_str
9038                         gap = (task_size / 6 * 5);
9039  
9040                 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
9041 +
9042 +#ifdef CONFIG_PAX_RANDMMAP
9043 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
9044 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9045 +#endif
9046 +
9047                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9048                 mm->unmap_area = arch_unmap_area_topdown;
9049         }
9050 diff -urNp linux-2.6.20.3/arch/sparc64/mm/fault.c linux-2.6.20.3/arch/sparc64/mm/fault.c
9051 --- linux-2.6.20.3/arch/sparc64/mm/fault.c      2007-03-13 14:27:08.000000000 -0400
9052 +++ linux-2.6.20.3/arch/sparc64/mm/fault.c      2007-03-23 08:10:06.000000000 -0400
9053 @@ -20,6 +20,10 @@
9054  #include <linux/interrupt.h>
9055  #include <linux/kprobes.h>
9056  #include <linux/kallsyms.h>
9057 +#include <linux/slab.h>
9058 +#include <linux/pagemap.h>
9059 +#include <linux/compiler.h>
9060 +#include <linux/binfmts.h>
9061  
9062  #include <asm/page.h>
9063  #include <asm/pgtable.h>
9064 @@ -290,6 +294,369 @@ cannot_handle:
9065         unhandled_fault (address, current, regs);
9066  }
9067  
9068 +#ifdef CONFIG_PAX_PAGEEXEC
9069 +#ifdef CONFIG_PAX_EMUPLT
9070 +static void pax_emuplt_close(struct vm_area_struct * vma)
9071 +{
9072 +       vma->vm_mm->call_dl_resolve = 0UL;
9073 +}
9074 +
9075 +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int *type)
9076 +{
9077 +       struct page* page;
9078 +       unsigned int *kaddr;
9079 +
9080 +       page = alloc_page(GFP_HIGHUSER);
9081 +       if (!page)
9082 +               return NOPAGE_OOM;
9083 +
9084 +       kaddr = kmap(page);
9085 +       memset(kaddr, 0, PAGE_SIZE);
9086 +       kaddr[0] = 0x9DE3BFA8U; /* save */
9087 +       flush_dcache_page(page);
9088 +       kunmap(page);
9089 +       if (type)
9090 +               *type = VM_FAULT_MAJOR;
9091 +       return page;
9092 +}
9093 +
9094 +static struct vm_operations_struct pax_vm_ops = {
9095 +       .close = pax_emuplt_close,
9096 +       .nopage = pax_emuplt_nopage,
9097 +};
9098 +
9099 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
9100 +{
9101 +       int ret;
9102 +
9103 +       memset(vma, 0, sizeof(*vma));
9104 +       vma->vm_mm = current->mm;
9105 +       vma->vm_start = addr;
9106 +       vma->vm_end = addr + PAGE_SIZE;
9107 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
9108 +       vma->vm_page_prot = protection_map[vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
9109 +       vma->vm_ops = &pax_vm_ops;
9110 +
9111 +       ret = insert_vm_struct(current->mm, vma);
9112 +       if (ret)
9113 +               return ret;
9114 +
9115 +       ++current->mm->total_vm;
9116 +       return 0;
9117 +}
9118 +#endif
9119 +
9120 +/*
9121 + * PaX: decide what to do with offenders (regs->tpc = fault address)
9122 + *
9123 + * returns 1 when task should be killed
9124 + *         2 when patched PLT trampoline was detected
9125 + *         3 when unpatched PLT trampoline was detected
9126 + */
9127 +static int pax_handle_fetch_fault(struct pt_regs *regs)
9128 +{
9129 +
9130 +#ifdef CONFIG_PAX_EMUPLT
9131 +       int err;
9132 +
9133 +       do { /* PaX: patched PLT emulation #1 */
9134 +               unsigned int sethi1, sethi2, jmpl;
9135 +
9136 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
9137 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
9138 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+8));
9139 +
9140 +               if (err)
9141 +                       break;
9142 +
9143 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9144 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
9145 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
9146 +               {
9147 +                       unsigned long addr;
9148 +
9149 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
9150 +                       addr = regs->u_regs[UREG_G1];
9151 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9152 +                       regs->tpc = addr;
9153 +                       regs->tnpc = addr+4;
9154 +                       return 2;
9155 +               }
9156 +       } while (0);
9157 +
9158 +       { /* PaX: patched PLT emulation #2 */
9159 +               unsigned int ba;
9160 +
9161 +               err = get_user(ba, (unsigned int*)regs->tpc);
9162 +
9163 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
9164 +                       unsigned long addr;
9165 +
9166 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9167 +                       regs->tpc = addr;
9168 +                       regs->tnpc = addr+4;
9169 +                       return 2;
9170 +               }
9171 +       }
9172 +
9173 +       do { /* PaX: patched PLT emulation #3 */
9174 +               unsigned int sethi, jmpl, nop;
9175 +
9176 +               err = get_user(sethi, (unsigned int*)regs->tpc);
9177 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+4));
9178 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
9179 +
9180 +               if (err)
9181 +                       break;
9182 +
9183 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
9184 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
9185 +                   nop == 0x01000000U)
9186 +               {
9187 +                       unsigned long addr;
9188 +
9189 +                       addr = (sethi & 0x003FFFFFU) << 10;
9190 +                       regs->u_regs[UREG_G1] = addr;
9191 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
9192 +                       regs->tpc = addr;
9193 +                       regs->tnpc = addr+4;
9194 +                       return 2;
9195 +               }
9196 +       } while (0);
9197 +
9198 +       do { /* PaX: patched PLT emulation #4 */
9199 +               unsigned int mov1, call, mov2;
9200 +
9201 +               err = get_user(mov1, (unsigned int*)regs->tpc);
9202 +               err |= get_user(call, (unsigned int*)(regs->tpc+4));
9203 +               err |= get_user(mov2, (unsigned int*)(regs->tpc+8));
9204 +
9205 +               if (err)
9206 +                       break;
9207 +
9208 +               if (mov1 == 0x8210000FU &&
9209 +                   (call & 0xC0000000U) == 0x40000000U &&
9210 +                   mov2 == 0x9E100001U)
9211 +               {
9212 +                       unsigned long addr;
9213 +
9214 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
9215 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
9216 +                       regs->tpc = addr;
9217 +                       regs->tnpc = addr+4;
9218 +                       return 2;
9219 +               }
9220 +       } while (0);
9221 +
9222 +       do { /* PaX: patched PLT emulation #5 */
9223 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
9224 +
9225 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
9226 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
9227 +               err |= get_user(or1, (unsigned int*)(regs->tpc+8));
9228 +               err |= get_user(or2, (unsigned int*)(regs->tpc+12));
9229 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+16));
9230 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+20));
9231 +               err |= get_user(nop, (unsigned int*)(regs->tpc+24));
9232 +
9233 +               if (err)
9234 +                       break;
9235 +
9236 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9237 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
9238 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
9239 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
9240 +                   sllx == 0x83287020 &&
9241 +                   jmpl == 0x81C04005U &&
9242 +                   nop == 0x01000000U)
9243 +               {
9244 +                       unsigned long addr;
9245 +
9246 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
9247 +                       regs->u_regs[UREG_G1] <<= 32;
9248 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
9249 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
9250 +                       regs->tpc = addr;
9251 +                       regs->tnpc = addr+4;
9252 +                       return 2;
9253 +               }
9254 +       } while (0);
9255 +
9256 +       do { /* PaX: patched PLT emulation #6 */
9257 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
9258 +
9259 +               err = get_user(sethi1, (unsigned int*)regs->tpc);
9260 +               err |= get_user(sethi2, (unsigned int*)(regs->tpc+4));
9261 +               err |= get_user(sllx, (unsigned int*)(regs->tpc+8));
9262 +               err |= get_user(or, (unsigned int*)(regs->tpc+12));
9263 +               err |= get_user(jmpl, (unsigned int*)(regs->tpc+16));
9264 +               err |= get_user(nop, (unsigned int*)(regs->tpc+20));
9265 +
9266 +               if (err)
9267 +                       break;
9268 +
9269 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
9270 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
9271 +                   sllx == 0x83287020 &&
9272 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
9273 +                   jmpl == 0x81C04005U &&
9274 +                   nop == 0x01000000U)
9275 +               {
9276 +                       unsigned long addr;
9277 +
9278 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
9279 +                       regs->u_regs[UREG_G1] <<= 32;
9280 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
9281 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
9282 +                       regs->tpc = addr;
9283 +                       regs->tnpc = addr+4;
9284 +                       return 2;
9285 +               }
9286 +       } while (0);
9287 +
9288 +       do { /* PaX: patched PLT emulation #7 */
9289 +               unsigned int sethi, ba, nop;
9290 +
9291 +               err = get_user(sethi, (unsigned int*)regs->tpc);
9292 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
9293 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
9294 +
9295 +               if (err)
9296 +                       break;
9297 +
9298 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
9299 +                   (ba & 0xFFF00000U) == 0x30600000U &&
9300 +                   nop == 0x01000000U)
9301 +               {
9302 +                       unsigned long addr;
9303 +
9304 +                       addr = (sethi & 0x003FFFFFU) << 10;
9305 +                       regs->u_regs[UREG_G1] = addr;
9306 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
9307 +                       regs->tpc = addr;
9308 +                       regs->tnpc = addr+4;
9309 +                       return 2;
9310 +               }
9311 +       } while (0);
9312 +
9313 +       do { /* PaX: unpatched PLT emulation step 1 */
9314 +               unsigned int sethi, ba, nop;
9315 +
9316 +               err = get_user(sethi, (unsigned int*)regs->tpc);
9317 +               err |= get_user(ba, (unsigned int*)(regs->tpc+4));
9318 +               err |= get_user(nop, (unsigned int*)(regs->tpc+8));
9319 +
9320 +               if (err)
9321 +                       break;
9322 +
9323 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
9324 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
9325 +                   nop == 0x01000000U)
9326 +               {
9327 +                       unsigned long addr;
9328 +                       unsigned int save, call;
9329 +
9330 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
9331 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
9332 +                       else
9333 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
9334 +
9335 +                       err = get_user(save, (unsigned int*)addr);
9336 +                       err |= get_user(call, (unsigned int*)(addr+4));
9337 +                       err |= get_user(nop, (unsigned int*)(addr+8));
9338 +                       if (err)
9339 +                               break;
9340 +
9341 +                       if (save == 0x9DE3BFA8U &&
9342 +                           (call & 0xC0000000U) == 0x40000000U &&
9343 +                           nop == 0x01000000U)
9344 +                       {
9345 +                               struct vm_area_struct *vma;
9346 +                               unsigned long call_dl_resolve;
9347 +
9348 +                               down_read(&current->mm->mmap_sem);
9349 +                               call_dl_resolve = current->mm->call_dl_resolve;
9350 +                               up_read(&current->mm->mmap_sem);
9351 +                               if (likely(call_dl_resolve))
9352 +                                       goto emulate;
9353 +
9354 +                               vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9355 +
9356 +                               down_write(&current->mm->mmap_sem);
9357 +                               if (current->mm->call_dl_resolve) {
9358 +                                       call_dl_resolve = current->mm->call_dl_resolve;
9359 +                                       up_write(&current->mm->mmap_sem);
9360 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
9361 +                                       goto emulate;
9362 +                               }
9363 +
9364 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
9365 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
9366 +                                       up_write(&current->mm->mmap_sem);
9367 +                                       if (vma) kmem_cache_free(vm_area_cachep, vma);
9368 +                                       return 1;
9369 +                               }
9370 +
9371 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
9372 +                                       up_write(&current->mm->mmap_sem);
9373 +                                       kmem_cache_free(vm_area_cachep, vma);
9374 +                                       return 1;
9375 +                               }
9376 +
9377 +                               current->mm->call_dl_resolve = call_dl_resolve;
9378 +                               up_write(&current->mm->mmap_sem);
9379 +
9380 +emulate:
9381 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
9382 +                               regs->tpc = call_dl_resolve;
9383 +                               regs->tnpc = addr+4;
9384 +                               return 3;
9385 +                       }
9386 +               }
9387 +       } while (0);
9388 +
9389 +       do { /* PaX: unpatched PLT emulation step 2 */
9390 +               unsigned int save, call, nop;
9391 +
9392 +               err = get_user(save, (unsigned int*)(regs->tpc-4));
9393 +               err |= get_user(call, (unsigned int*)regs->tpc);
9394 +               err |= get_user(nop, (unsigned int*)(regs->tpc+4));
9395 +               if (err)
9396 +                       break;
9397 +
9398 +               if (save == 0x9DE3BFA8U &&
9399 +                   (call & 0xC0000000U) == 0x40000000U &&
9400 +                   nop == 0x01000000U)
9401 +               {
9402 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
9403 +
9404 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
9405 +                       regs->tpc = dl_resolve;
9406 +                       regs->tnpc = dl_resolve+4;
9407 +                       return 3;
9408 +               }
9409 +       } while (0);
9410 +#endif
9411 +
9412 +       return 1;
9413 +}
9414 +
9415 +void pax_report_insns(void *pc, void *sp)
9416 +{
9417 +       unsigned long i;
9418 +
9419 +       printk(KERN_ERR "PAX: bytes at PC: ");
9420 +       for (i = 0; i < 5; i++) {
9421 +               unsigned int c;
9422 +               if (get_user(c, (unsigned int*)pc+i))
9423 +                       printk("???????? ");
9424 +               else
9425 +                       printk("%08x ", c);
9426 +       }
9427 +       printk("\n");
9428 +}
9429 +#endif
9430 +
9431  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
9432  {
9433         struct mm_struct *mm = current->mm;
9434 @@ -332,8 +699,10 @@ asmlinkage void __kprobes do_sparc64_fau
9435                 goto intr_or_no_mm;
9436  
9437         if (test_thread_flag(TIF_32BIT)) {
9438 -               if (!(regs->tstate & TSTATE_PRIV))
9439 +               if (!(regs->tstate & TSTATE_PRIV)) {
9440                         regs->tpc &= 0xffffffff;
9441 +                       regs->tnpc &= 0xffffffff;
9442 +               }
9443                 address &= 0xffffffff;
9444         }
9445  
9446 @@ -350,6 +719,29 @@ asmlinkage void __kprobes do_sparc64_fau
9447         if (!vma)
9448                 goto bad_area;
9449  
9450 +#ifdef CONFIG_PAX_PAGEEXEC
9451 +       /* PaX: detect ITLB misses on non-exec pages */
9452 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
9453 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
9454 +       {
9455 +               if (address != regs->tpc)
9456 +                       goto good_area;
9457 +
9458 +               up_read(&mm->mmap_sem);
9459 +               switch (pax_handle_fetch_fault(regs)) {
9460 +
9461 +#ifdef CONFIG_PAX_EMUPLT
9462 +               case 2:
9463 +               case 3:
9464 +                       return;
9465 +#endif
9466 +
9467 +               }
9468 +               pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS));
9469 +               do_exit(SIGKILL);
9470 +       }
9471 +#endif
9472 +
9473         /* Pure DTLB misses do not tell us whether the fault causing
9474          * load/store/atomic was a write or not, it only says that there
9475          * was no match.  So in such a case we (carefully) read the
9476 diff -urNp linux-2.6.20.3/arch/sparc64/mm/Makefile linux-2.6.20.3/arch/sparc64/mm/Makefile
9477 --- linux-2.6.20.3/arch/sparc64/mm/Makefile     2007-03-13 14:27:08.000000000 -0400
9478 +++ linux-2.6.20.3/arch/sparc64/mm/Makefile     2007-03-23 08:10:06.000000000 -0400
9479 @@ -3,7 +3,7 @@
9480  #
9481  
9482  EXTRA_AFLAGS := -ansi
9483 -EXTRA_CFLAGS := -Werror
9484 +#EXTRA_CFLAGS := -Werror
9485  
9486  obj-y    := ultra.o tlb.o tsb.o fault.o init.o generic.o
9487  
9488 diff -urNp linux-2.6.20.3/arch/v850/kernel/module.c linux-2.6.20.3/arch/v850/kernel/module.c
9489 --- linux-2.6.20.3/arch/v850/kernel/module.c    2007-03-13 14:27:08.000000000 -0400
9490 +++ linux-2.6.20.3/arch/v850/kernel/module.c    2007-03-23 08:10:06.000000000 -0400
9491 @@ -150,8 +150,8 @@ static uint32_t do_plt_call (void *locat
9492         tramp[1] = ((val >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */
9493  
9494         /* Init, or core PLT? */
9495 -       if (location >= mod->module_core
9496 -           && location < mod->module_core + mod->core_size)
9497 +       if (location >= mod->module_core_rx
9498 +           && location < mod->module_core_rx + mod->core_size_rx)
9499                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
9500         else
9501                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
9502 diff -urNp linux-2.6.20.3/arch/x86_64/boot/compressed/head.S linux-2.6.20.3/arch/x86_64/boot/compressed/head.S
9503 --- linux-2.6.20.3/arch/x86_64/boot/compressed/head.S   2007-03-13 14:27:08.000000000 -0400
9504 +++ linux-2.6.20.3/arch/x86_64/boot/compressed/head.S   2007-03-23 08:10:06.000000000 -0400
9505 @@ -41,11 +41,13 @@ startup_32:
9506         movl %eax,%gs
9507  
9508         lss stack_start,%esp
9509 +       movl 0x000000,%ecx
9510         xorl %eax,%eax
9511  1:     incl %eax               # check that A20 really IS enabled
9512         movl %eax,0x000000      # loop forever if it isn't
9513         cmpl %eax,0x100000
9514         je 1b
9515 +       movl %ecx,0x000000
9516  
9517  /*
9518   * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
9519 diff -urNp linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c
9520 --- linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c       2007-03-13 14:27:08.000000000 -0400
9521 +++ linux-2.6.20.3/arch/x86_64/ia32/ia32_binfmt.c       2007-03-23 08:10:06.000000000 -0400
9522 @@ -141,6 +141,17 @@ struct elf_prpsinfo
9523  //#include <asm/ia32.h>
9524  #include <linux/elf.h>
9525  
9526 +#ifdef CONFIG_PAX_ASLR
9527 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x08048000UL
9528 +
9529 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
9530 +#define PAX_DELTA_MMAP_LEN(tsk)                16
9531 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
9532 +#define PAX_DELTA_EXEC_LEN(tsk)                16
9533 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
9534 +#define PAX_DELTA_STACK_LEN(tsk)       16
9535 +#endif
9536 +
9537  typedef struct user_i387_ia32_struct elf_fpregset_t;
9538  typedef struct user32_fxsr_struct elf_fpxregset_t;
9539  
9540 diff -urNp linux-2.6.20.3/arch/x86_64/ia32/mmap32.c linux-2.6.20.3/arch/x86_64/ia32/mmap32.c
9541 --- linux-2.6.20.3/arch/x86_64/ia32/mmap32.c    2007-03-13 14:27:08.000000000 -0400
9542 +++ linux-2.6.20.3/arch/x86_64/ia32/mmap32.c    2007-03-23 08:10:06.000000000 -0400
9543 @@ -68,10 +68,22 @@ void ia32_pick_mmap_layout(struct mm_str
9544                         (current->personality & ADDR_COMPAT_LAYOUT) ||
9545                         current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY) {
9546                 mm->mmap_base = TASK_UNMAPPED_BASE;
9547 +
9548 +#ifdef CONFIG_PAX_RANDMMAP
9549 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
9550 +                       mm->mmap_base += mm->delta_mmap;
9551 +#endif
9552 +
9553                 mm->get_unmapped_area = arch_get_unmapped_area;
9554                 mm->unmap_area = arch_unmap_area;
9555         } else {
9556                 mm->mmap_base = mmap_base(mm);
9557 +
9558 +#ifdef CONFIG_PAX_RANDMMAP
9559 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
9560 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
9561 +#endif
9562 +
9563                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
9564                 mm->unmap_area = arch_unmap_area_topdown;
9565         }
9566 diff -urNp linux-2.6.20.3/arch/x86_64/ia32/syscall32.c linux-2.6.20.3/arch/x86_64/ia32/syscall32.c
9567 --- linux-2.6.20.3/arch/x86_64/ia32/syscall32.c 2007-03-13 14:27:08.000000000 -0400
9568 +++ linux-2.6.20.3/arch/x86_64/ia32/syscall32.c 2007-03-23 08:10:06.000000000 -0400
9569 @@ -49,16 +49,21 @@ int syscall32_setup_pages(struct linux_b
9570         struct mm_struct *mm = current->mm;
9571         int ret;
9572  
9573 -       vma = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
9574 +       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
9575         if (!vma)
9576                 return -ENOMEM;
9577  
9578 -       memset(vma, 0, sizeof(struct vm_area_struct));
9579         /* Could randomize here */
9580         vma->vm_start = VSYSCALL32_BASE;
9581         vma->vm_end = VSYSCALL32_END;
9582         /* MAYWRITE to allow gdb to COW and set breakpoints */
9583         vma->vm_flags = VM_READ|VM_EXEC|VM_MAYREAD|VM_MAYEXEC|VM_MAYWRITE;
9584 +
9585 +#ifdef CONFIG_PAX_MPROTECT
9586 +       if (mm->pax_flags & MF_PAX_MPROTECT)
9587 +               vma->vm_flags &= ~VM_MAYWRITE;
9588 +#endif
9589 +
9590         /*
9591          * Make sure the vDSO gets into every core dump.
9592          * Dumping its contents makes post-mortem fully interpretable later
9593 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/ioport.c linux-2.6.20.3/arch/x86_64/kernel/ioport.c
9594 --- linux-2.6.20.3/arch/x86_64/kernel/ioport.c  2007-03-13 14:27:08.000000000 -0400
9595 +++ linux-2.6.20.3/arch/x86_64/kernel/ioport.c  2007-03-23 08:11:31.000000000 -0400
9596 @@ -41,8 +41,16 @@ asmlinkage long sys_ioperm(unsigned long
9597  
9598         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
9599                 return -EINVAL;
9600 +
9601 +#ifdef CONFIG_GRKERNSEC_IO
9602 +       if (turn_on) {
9603 +               gr_handle_ioperm();
9604 +               return -EPERM;
9605 +       }
9606 +#else
9607         if (turn_on && !capable(CAP_SYS_RAWIO))
9608                 return -EPERM;
9609 +#endif
9610  
9611         /*
9612          * If it's the first ioperm() call in this thread's lifetime, set the
9613 @@ -111,8 +119,13 @@ asmlinkage long sys_iopl(unsigned int le
9614                 return -EINVAL;
9615         /* Trying to gain more privileges? */
9616         if (level > old) {
9617 +#ifdef CONFIG_GRKERNSEC_IO
9618 +               gr_handle_iopl();
9619 +               return -EPERM;
9620 +#else
9621                 if (!capable(CAP_SYS_RAWIO))
9622                         return -EPERM;
9623 +#endif
9624         }
9625         regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
9626         return 0;
9627 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/process.c linux-2.6.20.3/arch/x86_64/kernel/process.c
9628 --- linux-2.6.20.3/arch/x86_64/kernel/process.c 2007-03-13 14:27:08.000000000 -0400
9629 +++ linux-2.6.20.3/arch/x86_64/kernel/process.c 2007-03-23 08:10:06.000000000 -0400
9630 @@ -878,10 +878,3 @@ int dump_task_regs(struct task_struct *t
9631   
9632         return 1;
9633  }
9634 -
9635 -unsigned long arch_align_stack(unsigned long sp)
9636 -{
9637 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
9638 -               sp -= get_random_int() % 8192;
9639 -       return sp & ~0xf;
9640 -}
9641 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/ptrace.c linux-2.6.20.3/arch/x86_64/kernel/ptrace.c
9642 --- linux-2.6.20.3/arch/x86_64/kernel/ptrace.c  2007-03-13 14:27:08.000000000 -0400
9643 +++ linux-2.6.20.3/arch/x86_64/kernel/ptrace.c  2007-03-23 08:11:31.000000000 -0400
9644 @@ -19,6 +19,7 @@
9645  #include <linux/audit.h>
9646  #include <linux/seccomp.h>
9647  #include <linux/signal.h>
9648 +#include <linux/grsecurity.h>
9649  
9650  #include <asm/uaccess.h>
9651  #include <asm/pgtable.h>
9652 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/setup64.c linux-2.6.20.3/arch/x86_64/kernel/setup64.c
9653 --- linux-2.6.20.3/arch/x86_64/kernel/setup64.c 2007-03-13 14:27:08.000000000 -0400
9654 +++ linux-2.6.20.3/arch/x86_64/kernel/setup64.c 2007-03-23 08:10:06.000000000 -0400
9655 @@ -38,7 +38,6 @@ char boot_cpu_stack[IRQSTACKSIZE] __attr
9656  
9657  unsigned long __supported_pte_mask __read_mostly = ~0UL;
9658  EXPORT_SYMBOL(__supported_pte_mask);
9659 -static int do_not_nx __cpuinitdata = 0;
9660  
9661  /* noexec=on|off
9662  Control non executable mappings for 64bit processes.
9663 @@ -52,16 +51,14 @@ static int __init nonx_setup(char *str)
9664                 return -EINVAL;
9665         if (!strncmp(str, "on", 2)) {
9666                  __supported_pte_mask |= _PAGE_NX; 
9667 -               do_not_nx = 0; 
9668         } else if (!strncmp(str, "off", 3)) {
9669 -               do_not_nx = 1;
9670                 __supported_pte_mask &= ~_PAGE_NX;
9671          }
9672         return 0;
9673  } 
9674  early_param("noexec", nonx_setup);
9675  
9676 -int force_personality32 = 0; 
9677 +int force_personality32;
9678  
9679  /* noexec32=on|off
9680  Control non executable heap for 32bit processes.
9681 @@ -175,7 +172,7 @@ void __cpuinit check_efer(void)
9682         unsigned long efer;
9683  
9684         rdmsrl(MSR_EFER, efer); 
9685 -        if (!(efer & EFER_NX) || do_not_nx) { 
9686 +        if (!(efer & EFER_NX)) { 
9687                  __supported_pte_mask &= ~_PAGE_NX; 
9688          }       
9689  }
9690 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/signal.c linux-2.6.20.3/arch/x86_64/kernel/signal.c
9691 --- linux-2.6.20.3/arch/x86_64/kernel/signal.c  2007-03-13 14:27:08.000000000 -0400
9692 +++ linux-2.6.20.3/arch/x86_64/kernel/signal.c  2007-03-23 08:10:06.000000000 -0400
9693 @@ -254,8 +254,8 @@ static int setup_rt_frame(int sig, struc
9694         err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
9695         err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
9696         if (sizeof(*set) == 16) { 
9697 -               __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
9698 -               __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 
9699 +               err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
9700 +               err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 
9701         } else
9702                 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
9703  
9704 diff -urNp linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c
9705 --- linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c      2007-03-13 14:27:08.000000000 -0400
9706 +++ linux-2.6.20.3/arch/x86_64/kernel/sys_x86_64.c      2007-03-23 08:10:06.000000000 -0400
9707 @@ -65,8 +65,8 @@ out:
9708         return error;
9709  }
9710  
9711 -static void find_start_end(unsigned long flags, unsigned long *begin,
9712 -                          unsigned long *end)
9713 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
9714 +                          unsigned long *begin, unsigned long *end)
9715  {
9716         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
9717                 /* This is usually used needed to map code in small
9718 @@ -79,7 +79,7 @@ static void find_start_end(unsigned long
9719                 *begin = 0x40000000; 
9720                 *end = 0x80000000;              
9721         } else {
9722 -               *begin = TASK_UNMAPPED_BASE;
9723 +               *begin = mm->mmap_base;
9724                 *end = TASK_SIZE; 
9725         }
9726  } 
9727 @@ -93,11 +93,15 @@ arch_get_unmapped_area(struct file *filp
9728         unsigned long start_addr;
9729         unsigned long begin, end;
9730         
9731 -       find_start_end(flags, &begin, &end); 
9732 +       find_start_end(mm, flags, &begin, &end); 
9733  
9734         if (len > end)
9735                 return -ENOMEM;
9736  
9737 +#ifdef CONFIG_PAX_RANDMMAP
9738 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
9739 +#endif
9740 +
9741         if (addr) {
9742                 addr = PAGE_ALIGN(addr);
9743                 vma = find_vma(mm, addr);
9744 diff -urNp linux-2.6.20.3/arch/x86_64/mm/fault.c linux-2.6.20.3/arch/x86_64/mm/fault.c
9745 --- linux-2.6.20.3/arch/x86_64/mm/fault.c       2007-03-13 14:27:08.000000000 -0400
9746 +++ linux-2.6.20.3/arch/x86_64/mm/fault.c       2007-03-23 08:10:06.000000000 -0400
9747 @@ -24,6 +24,7 @@
9748  #include <linux/module.h>
9749  #include <linux/kprobes.h>
9750  #include <linux/uaccess.h>
9751 +#include <linux/binfmts.h>
9752  
9753  #include <asm/system.h>
9754  #include <asm/pgalloc.h>
9755 @@ -322,6 +323,33 @@ static int vmalloc_fault(unsigned long a
9756         return 0;
9757  }
9758  
9759 +#ifdef CONFIG_PAX_PAGEEXEC
9760 +void pax_report_insns(void *pc, void *sp)
9761 +{
9762 +       long i;
9763 +
9764 +       printk(KERN_ERR "PAX: bytes at PC: ");
9765 +       for (i = 0; i < 20; i++) {
9766 +               unsigned char c;
9767 +               if (get_user(c, (unsigned char __user *)pc+i))
9768 +                       printk("?? ");
9769 +               else
9770 +                       printk("%02x ", c);
9771 +       }
9772 +       printk("\n");
9773 +
9774 +       printk(KERN_ERR "PAX: bytes at SP-8: ");
9775 +       for (i = -1; i < 10; i++) {
9776 +               unsigned long c;
9777 +               if (get_user(c, (unsigned long __user *)sp+i))
9778 +                       printk("???????????????? ");
9779 +               else
9780 +                       printk("%016lx ", c);
9781 +       }
9782 +       printk("\n");
9783 +}
9784 +#endif
9785 +
9786  int page_fault_trace = 0;
9787  int exception_trace = 1;
9788  
9789 @@ -453,6 +481,8 @@ asmlinkage void __kprobes do_page_fault(
9790  good_area:
9791         info.si_code = SEGV_ACCERR;
9792         write = 0;
9793 +       if ((error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
9794 +               goto bad_area;
9795         switch (error_code & (PF_PROT|PF_WRITE)) {
9796                 default:        /* 3: write, present */
9797                         /* fall through */
9798 @@ -519,7 +549,14 @@ bad_area_nosemaphore:
9799                                         tsk->comm, tsk->pid, tsk->xid, address,
9800                                         regs->rip, regs->rsp, error_code);
9801                 }
9802 -       
9803 +
9804 +#ifdef CONFIG_PAX_PAGEEXEC
9805 +               if (mm && (mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16)) {
9806 +                       pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp);
9807 +                       do_exit(SIGKILL);
9808 +               }
9809 +#endif
9810 +
9811                 tsk->thread.cr2 = address;
9812                 /* Kernel addresses are always protection faults */
9813                 tsk->thread.error_code = error_code | (address >= TASK_SIZE);
9814 diff -urNp linux-2.6.20.3/arch/x86_64/mm/mmap.c linux-2.6.20.3/arch/x86_64/mm/mmap.c
9815 --- linux-2.6.20.3/arch/x86_64/mm/mmap.c        2007-03-13 14:27:08.000000000 -0400
9816 +++ linux-2.6.20.3/arch/x86_64/mm/mmap.c        2007-03-23 08:10:06.000000000 -0400
9817 @@ -23,6 +23,12 @@ void arch_pick_mmap_layout(struct mm_str
9818                 unsigned rnd = get_random_int() & 0xfffffff;
9819                 mm->mmap_base += ((unsigned long)rnd) << PAGE_SHIFT;
9820         }
9821 +
9822 +#ifdef CONFIG_PAX_RANDMMAP
9823 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
9824 +               mm->mmap_base += mm->delta_mmap;
9825 +#endif
9826 +
9827         mm->get_unmapped_area = arch_get_unmapped_area;
9828         mm->unmap_area = arch_unmap_area;
9829  }
9830 diff -urNp linux-2.6.20.3/crypto/lrw.c linux-2.6.20.3/crypto/lrw.c
9831 --- linux-2.6.20.3/crypto/lrw.c 2007-03-13 14:27:08.000000000 -0400
9832 +++ linux-2.6.20.3/crypto/lrw.c 2007-03-23 08:10:06.000000000 -0400
9833 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
9834         struct priv *ctx = crypto_tfm_ctx(parent);
9835         struct crypto_cipher *child = ctx->child;
9836         int err, i;
9837 -       be128 tmp = { 0 };
9838 +       be128 tmp = { 0, 0 };
9839         int bsize = crypto_cipher_blocksize(child);
9840  
9841         crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
9842 diff -urNp linux-2.6.20.3/Documentation/dontdiff linux-2.6.20.3/Documentation/dontdiff
9843 --- linux-2.6.20.3/Documentation/dontdiff       2007-03-13 14:27:08.000000000 -0400
9844 +++ linux-2.6.20.3/Documentation/dontdiff       2007-03-23 08:10:05.000000000 -0400
9845 @@ -55,7 +55,7 @@ aic7*seq.h*
9846  aicasm
9847  aicdb.h*
9848  asm
9849 -asm-offsets.*
9850 +asm-offsets.h
9851  asm_offsets.*
9852  autoconf.h*
9853  bbootsect
9854 @@ -127,6 +127,7 @@ pss_boot.h
9855  raid6altivec*.c
9856  raid6int*.c
9857  raid6tables.c
9858 +relocs
9859  setup
9860  sim710_d.h*
9861  sm_tbl*
9862 @@ -139,8 +140,11 @@ utsrelease.h*
9863  version.h*
9864  vmlinux
9865  vmlinux-*
9866 +vmlinux.bin.all
9867  vmlinux.lds
9868 +vmlinux.relocs
9869  vsyscall.lds
9870  wanxlfw.inc
9871  uImage
9872 +utsrelease.h
9873  zImage
9874 diff -urNp linux-2.6.20.3/drivers/acpi/blacklist.c linux-2.6.20.3/drivers/acpi/blacklist.c
9875 --- linux-2.6.20.3/drivers/acpi/blacklist.c     2007-03-13 14:27:08.000000000 -0400
9876 +++ linux-2.6.20.3/drivers/acpi/blacklist.c     2007-03-23 08:10:06.000000000 -0400
9877 @@ -70,7 +70,7 @@ static struct acpi_blacklist_item acpi_b
9878         {"ASUS\0\0", "P2B-S   ", 0, ACPI_DSDT, all_versions,
9879          "Bogus PCI routing", 1},
9880  
9881 -       {""}
9882 +       {"", "", 0, 0, 0, all_versions, 0}
9883  };
9884  
9885  #if    CONFIG_ACPI_BLACKLIST_YEAR
9886 diff -urNp linux-2.6.20.3/drivers/acpi/glue.c linux-2.6.20.3/drivers/acpi/glue.c
9887 --- linux-2.6.20.3/drivers/acpi/glue.c  2007-03-13 14:27:08.000000000 -0400
9888 +++ linux-2.6.20.3/drivers/acpi/glue.c  2007-03-23 08:10:06.000000000 -0400
9889 @@ -16,7 +16,7 @@
9890  #if ACPI_GLUE_DEBUG
9891  #define DBG(x...) printk(PREFIX x)
9892  #else
9893 -#define DBG(x...)
9894 +#define DBG(x...) do {} while (0)
9895  #endif
9896  static LIST_HEAD(bus_type_list);
9897  static DECLARE_RWSEM(bus_type_sem);
9898 diff -urNp linux-2.6.20.3/drivers/acpi/processor_core.c linux-2.6.20.3/drivers/acpi/processor_core.c
9899 --- linux-2.6.20.3/drivers/acpi/processor_core.c        2007-03-13 14:27:08.000000000 -0400
9900 +++ linux-2.6.20.3/drivers/acpi/processor_core.c        2007-03-23 08:10:06.000000000 -0400
9901 @@ -531,7 +531,7 @@ static int __cpuinit acpi_processor_star
9902                 return 0;
9903         }
9904  
9905 -       BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0));
9906 +       BUG_ON(pr->id >= NR_CPUS);
9907  
9908         /*
9909          * Buggy BIOS check
9910 diff -urNp linux-2.6.20.3/drivers/acpi/processor_idle.c linux-2.6.20.3/drivers/acpi/processor_idle.c
9911 --- linux-2.6.20.3/drivers/acpi/processor_idle.c        2007-03-13 14:27:08.000000000 -0400
9912 +++ linux-2.6.20.3/drivers/acpi/processor_idle.c        2007-03-23 08:10:06.000000000 -0400
9913 @@ -153,7 +153,7 @@ static struct dmi_system_id __cpuinitdat
9914           DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
9915           DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
9916          (void *)2},
9917 -       {},
9918 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
9919  };
9920  
9921  static inline u32 ticks_elapsed(u32 t1, u32 t2)
9922 diff -urNp linux-2.6.20.3/drivers/acpi/sleep/main.c linux-2.6.20.3/drivers/acpi/sleep/main.c
9923 --- linux-2.6.20.3/drivers/acpi/sleep/main.c    2007-03-13 14:27:08.000000000 -0400
9924 +++ linux-2.6.20.3/drivers/acpi/sleep/main.c    2007-03-23 08:10:06.000000000 -0400
9925 @@ -197,7 +197,7 @@ static struct dmi_system_id __initdata a
9926          .ident = "Toshiba Satellite 4030cdt",
9927          .matches = {DMI_MATCH(DMI_PRODUCT_NAME, "S4030CDT/4.3"),},
9928          },
9929 -       {},
9930 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
9931  };
9932  
9933  static int __init acpi_sleep_init(void)
9934 diff -urNp linux-2.6.20.3/drivers/ata/ata_piix.c linux-2.6.20.3/drivers/ata/ata_piix.c
9935 --- linux-2.6.20.3/drivers/ata/ata_piix.c       2007-03-13 14:27:08.000000000 -0400
9936 +++ linux-2.6.20.3/drivers/ata/ata_piix.c       2007-03-23 08:10:06.000000000 -0400
9937 @@ -247,7 +247,7 @@ static const struct pci_device_id piix_p
9938         /* SATA Controller IDE (ICH9M) */
9939         { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
9940  
9941 -       { }     /* terminate list */
9942 +       { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
9943  };
9944  
9945  static struct pci_driver piix_pci_driver = {
9946 @@ -574,7 +574,7 @@ static const struct ich_laptop ich_lapto
9947         /* devid, subvendor, subdev */
9948         { 0x27DF, 0x0005, 0x0280 },     /* ICH7 on Acer 5602WLMi */
9949         /* end marker */
9950 -       { 0, }
9951 +       { 0, 0, 0 }
9952  };
9953  
9954  /**
9955 diff -urNp linux-2.6.20.3/drivers/ata/libata-core.c linux-2.6.20.3/drivers/ata/libata-core.c
9956 --- linux-2.6.20.3/drivers/ata/libata-core.c    2007-03-13 14:27:08.000000000 -0400
9957 +++ linux-2.6.20.3/drivers/ata/libata-core.c    2007-03-23 08:10:06.000000000 -0400
9958 @@ -460,7 +460,7 @@ static const struct ata_xfer_ent {
9959         { ATA_SHIFT_PIO, ATA_BITS_PIO, XFER_PIO_0 },
9960         { ATA_SHIFT_MWDMA, ATA_BITS_MWDMA, XFER_MW_DMA_0 },
9961         { ATA_SHIFT_UDMA, ATA_BITS_UDMA, XFER_UDMA_0 },
9962 -       { -1, },
9963 +       { -1, 0, 0 },
9964  };
9965  
9966  /**
9967 @@ -2226,7 +2226,7 @@ static const struct ata_timing ata_timin
9968  
9969  /*     { XFER_PIO_SLOW, 120, 290, 240, 960, 290, 240, 960,   0 }, */
9970  
9971 -       { 0xFF }
9972 +       { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
9973  };
9974  
9975  #define ENOUGH(v,unit)         (((v)-1)/(unit)+1)
9976 @@ -3321,7 +3321,7 @@ static const struct ata_blacklist_entry 
9977         /* Devices with NCQ limits */
9978  
9979         /* End Marker */
9980 -       { }
9981 +       { NULL, NULL, 0 }
9982  };
9983  
9984  static int ata_strim(char *s, size_t len)
9985 diff -urNp linux-2.6.20.3/drivers/char/agp/frontend.c linux-2.6.20.3/drivers/char/agp/frontend.c
9986 --- linux-2.6.20.3/drivers/char/agp/frontend.c  2007-03-13 14:27:08.000000000 -0400
9987 +++ linux-2.6.20.3/drivers/char/agp/frontend.c  2007-03-23 08:10:06.000000000 -0400
9988 @@ -818,7 +818,7 @@ static int agpioc_reserve_wrap(struct ag
9989         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
9990                 return -EFAULT;
9991  
9992 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
9993 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
9994                 return -EFAULT;
9995  
9996         client = agp_find_client_by_pid(reserve.pid);
9997 diff -urNp linux-2.6.20.3/drivers/char/agp/intel-agp.c linux-2.6.20.3/drivers/char/agp/intel-agp.c
9998 --- linux-2.6.20.3/drivers/char/agp/intel-agp.c 2007-03-13 14:27:08.000000000 -0400
9999 +++ linux-2.6.20.3/drivers/char/agp/intel-agp.c 2007-03-23 08:10:06.000000000 -0400
10000 @@ -2026,7 +2026,7 @@ static struct pci_device_id agp_intel_pc
10001         ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
10002         ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
10003         ID(PCI_DEVICE_ID_INTEL_82965G_HB),
10004 -       { }
10005 +       { 0, 0, 0, 0, 0, 0, 0 }
10006  };
10007  
10008  MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
10009 diff -urNp linux-2.6.20.3/drivers/char/drm/drm_drawable.c linux-2.6.20.3/drivers/char/drm/drm_drawable.c
10010 --- linux-2.6.20.3/drivers/char/drm/drm_drawable.c      2007-03-13 14:27:08.000000000 -0400
10011 +++ linux-2.6.20.3/drivers/char/drm/drm_drawable.c      2007-03-23 08:10:06.000000000 -0400
10012 @@ -234,7 +234,7 @@ int drm_update_drawable_info(DRM_IOCTL_A
10013         idx = id / (8 * sizeof(*bitfield));
10014         shift = id % (8 * sizeof(*bitfield));
10015  
10016 -       if (idx < 0 || idx >= bitfield_length ||
10017 +       if (idx >= bitfield_length ||
10018             !(bitfield[idx] & (1 << shift))) {
10019                 DRM_ERROR("No such drawable %d\n", update.handle);
10020                 return DRM_ERR(EINVAL);
10021 @@ -319,7 +319,7 @@ drm_drawable_info_t *drm_get_drawable_in
10022         idx = id / (8 * sizeof(*bitfield));
10023         shift = id % (8 * sizeof(*bitfield));
10024  
10025 -       if (idx < 0 || idx >= dev->drw_bitfield_length ||
10026 +       if (idx >= dev->drw_bitfield_length ||
10027             !(bitfield[idx] & (1 << shift))) {
10028                 DRM_DEBUG("No such drawable %d\n", id);
10029                 return NULL;
10030 diff -urNp linux-2.6.20.3/drivers/char/drm/drm_pciids.h linux-2.6.20.3/drivers/char/drm/drm_pciids.h
10031 --- linux-2.6.20.3/drivers/char/drm/drm_pciids.h        2007-03-13 14:27:08.000000000 -0400
10032 +++ linux-2.6.20.3/drivers/char/drm/drm_pciids.h        2007-03-23 08:10:06.000000000 -0400
10033 @@ -239,7 +239,7 @@
10034         {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10035         {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10036         {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10037 -       {0, 0, 0}
10038 +       {0, 0, 0, 0, 0, 0, 0 }
10039  
10040  #define i830_PCI_IDS \
10041         {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
10042 diff -urNp linux-2.6.20.3/drivers/char/hpet.c linux-2.6.20.3/drivers/char/hpet.c
10043 --- linux-2.6.20.3/drivers/char/hpet.c  2007-03-13 14:27:08.000000000 -0400
10044 +++ linux-2.6.20.3/drivers/char/hpet.c  2007-03-23 08:10:06.000000000 -0400
10045 @@ -1008,7 +1008,7 @@ static struct acpi_driver hpet_acpi_driv
10046                 },
10047  };
10048  
10049 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
10050 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
10051  
10052  static int __init hpet_init(void)
10053  {
10054 diff -urNp linux-2.6.20.3/drivers/char/hw_random/intel-rng.c linux-2.6.20.3/drivers/char/hw_random/intel-rng.c
10055 --- linux-2.6.20.3/drivers/char/hw_random/intel-rng.c   2007-03-13 14:27:08.000000000 -0400
10056 +++ linux-2.6.20.3/drivers/char/hw_random/intel-rng.c   2007-03-23 08:10:06.000000000 -0400
10057 @@ -139,7 +139,7 @@ static const struct pci_device_id pci_tb
10058  /* E
10059         { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
10060         { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E  */
10061 -       { 0, }, /* terminate list */
10062 +       { 0, 0, 0, 0, 0, 0, 0 },        /* terminate list */
10063  };
10064  MODULE_DEVICE_TABLE(pci, pci_tbl);
10065  
10066 diff -urNp linux-2.6.20.3/drivers/char/keyboard.c linux-2.6.20.3/drivers/char/keyboard.c
10067 --- linux-2.6.20.3/drivers/char/keyboard.c      2007-03-13 14:27:08.000000000 -0400
10068 +++ linux-2.6.20.3/drivers/char/keyboard.c      2007-03-23 08:11:31.000000000 -0400
10069 @@ -203,7 +203,7 @@ int setkeycode(unsigned int scancode, un
10070  
10071         if (scancode >= dev->keycodemax)
10072                 return -EINVAL;
10073 -       if (keycode < 0 || keycode > KEY_MAX)
10074 +       if (keycode > KEY_MAX)
10075                 return -EINVAL;
10076         if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
10077                 return -EINVAL;
10078 @@ -628,6 +628,16 @@ static void k_spec(struct vc_data *vc, u
10079              kbd->kbdmode == VC_MEDIUMRAW) &&
10080              value != KVAL(K_SAK))
10081                 return;         /* SAK is allowed even in raw mode */
10082 +
10083 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
10084 +       {
10085 +               void *func = fn_handler[value];
10086 +               if (func == fn_show_state || func == fn_show_ptregs ||
10087 +                   func == fn_show_mem)
10088 +                       return;
10089 +       }
10090 +#endif
10091 +
10092         fn_handler[value](vc);
10093  }
10094  
10095 @@ -1354,7 +1364,7 @@ static const struct input_device_id kbd_
10096                  .evbit = { BIT(EV_SND) },
10097          },
10098  
10099 -       { },    /* Terminating entry */
10100 +       { 0 },    /* Terminating entry */
10101  };
10102  
10103  MODULE_DEVICE_TABLE(input, kbd_ids);
10104 diff -urNp linux-2.6.20.3/drivers/char/mem.c linux-2.6.20.3/drivers/char/mem.c
10105 --- linux-2.6.20.3/drivers/char/mem.c   2007-03-13 14:27:08.000000000 -0400
10106 +++ linux-2.6.20.3/drivers/char/mem.c   2007-03-23 08:11:31.000000000 -0400
10107 @@ -27,6 +27,7 @@
10108  #include <linux/bootmem.h>
10109  #include <linux/pipe_fs_i.h>
10110  #include <linux/pfn.h>
10111 +#include <linux/grsecurity.h>
10112  
10113  #include <asm/uaccess.h>
10114  #include <asm/io.h>
10115 @@ -35,6 +36,10 @@
10116  # include <linux/efi.h>
10117  #endif
10118  
10119 +#ifdef CONFIG_GRKERNSEC
10120 +extern struct file_operations grsec_fops;
10121 +#endif
10122 +
10123  /*
10124   * Architectures vary in how they handle caching for addresses
10125   * outside of main memory.
10126 @@ -174,6 +179,11 @@ static ssize_t write_mem(struct file * f
10127         if (!valid_phys_addr_range(p, count))
10128                 return -EFAULT;
10129  
10130 +#ifdef CONFIG_GRKERNSEC_KMEM
10131 +       gr_handle_mem_write();
10132 +       return -EPERM;
10133 +#endif
10134 +
10135         written = 0;
10136  
10137  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
10138 @@ -275,6 +285,11 @@ static int mmap_mem(struct file * file, 
10139         if (!private_mapping_ok(vma))
10140                 return -ENOSYS;
10141  
10142 +#ifdef CONFIG_GRKERNSEC_KMEM
10143 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
10144 +               return -EPERM;
10145 +#endif
10146 +
10147         vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
10148                                                  size,
10149                                                  vma->vm_page_prot);
10150 @@ -506,6 +521,11 @@ static ssize_t write_kmem(struct file * 
10151         ssize_t written;
10152         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
10153  
10154 +#ifdef CONFIG_GRKERNSEC_KMEM
10155 +       gr_handle_kmem_write();
10156 +       return -EPERM;
10157 +#endif
10158 +
10159         if (p < (unsigned long) high_memory) {
10160  
10161                 wrote = count;
10162 @@ -645,8 +665,24 @@ static inline size_t read_zero_pagealign
10163                 if (count > size)
10164                         count = size;
10165  
10166 +#ifdef CONFIG_PAX_SEGMEXEC
10167 +               if (vma->vm_flags & VM_MIRROR) {
10168 +                       unsigned long addr_m;
10169 +                       struct vm_area_struct * vma_m;
10170 +
10171 +                       addr_m = vma->vm_start + vma->vm_mirror;
10172 +                       vma_m = find_vma(mm, addr_m);
10173 +                       if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) {
10174 +                               addr_m = addr + vma->vm_mirror;
10175 +                               zap_page_range(vma_m, addr_m, count, NULL);
10176 +                       } else
10177 +                               printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n",
10178 +                                      addr, vma->vm_start);
10179 +               }
10180 +#endif
10181 +
10182                 zap_page_range(vma, addr, count, NULL);
10183 -               if (zeromap_page_range(vma, addr, count, PAGE_COPY))
10184 +               if (zeromap_page_range(vma, addr, count, vma->vm_page_prot))
10185                         break;
10186  
10187                 size -= count;
10188 @@ -799,6 +835,16 @@ static loff_t memory_lseek(struct file *
10189  
10190  static int open_port(struct inode * inode, struct file * filp)
10191  {
10192 +#ifdef CONFIG_GRKERNSEC_KMEM
10193 +       gr_handle_open_port();
10194 +       return -EPERM;
10195 +#endif
10196 +
10197 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
10198 +}
10199 +
10200 +static int open_mem(struct inode * inode, struct file * filp)
10201 +{
10202         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
10203  }
10204  
10205 @@ -806,7 +852,6 @@ static int open_port(struct inode * inod
10206  #define full_lseek      null_lseek
10207  #define write_zero     write_null
10208  #define read_full       read_zero
10209 -#define open_mem       open_port
10210  #define open_kmem      open_mem
10211  #define open_oldmem    open_mem
10212  
10213 @@ -939,6 +984,11 @@ static int memory_open(struct inode * in
10214                         filp->f_op = &oldmem_fops;
10215                         break;
10216  #endif
10217 +#ifdef CONFIG_GRKERNSEC
10218 +               case 13:
10219 +                       filp->f_op = &grsec_fops;
10220 +                       break;
10221 +#endif
10222                 default:
10223                         return -ENXIO;
10224         }
10225 @@ -971,6 +1021,9 @@ static const struct {
10226  #ifdef CONFIG_CRASH_DUMP
10227         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
10228  #endif
10229 +#ifdef CONFIG_GRKERNSEC
10230 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
10231 +#endif
10232  };
10233  
10234  static struct class *mem_class;
10235 diff -urNp linux-2.6.20.3/drivers/char/n_tty.c linux-2.6.20.3/drivers/char/n_tty.c
10236 --- linux-2.6.20.3/drivers/char/n_tty.c 2007-03-13 14:27:08.000000000 -0400
10237 +++ linux-2.6.20.3/drivers/char/n_tty.c 2007-03-23 08:10:06.000000000 -0400
10238 @@ -1559,6 +1559,8 @@ struct tty_ldisc tty_ldisc_N_TTY = {
10239         normal_poll,            /* poll */
10240         NULL,                   /* hangup */
10241         n_tty_receive_buf,      /* receive_buf */
10242 -       n_tty_write_wakeup      /* write_wakeup */
10243 +       n_tty_write_wakeup,     /* write_wakeup */
10244 +       NULL,                   /* owner */
10245 +       0                       /* refcount */
10246  };
10247  
10248 diff -urNp linux-2.6.20.3/drivers/char/nvram.c linux-2.6.20.3/drivers/char/nvram.c
10249 --- linux-2.6.20.3/drivers/char/nvram.c 2007-03-13 14:27:08.000000000 -0400
10250 +++ linux-2.6.20.3/drivers/char/nvram.c 2007-03-23 08:10:06.000000000 -0400
10251 @@ -450,7 +450,10 @@ static const struct file_operations nvra
10252  static struct miscdevice nvram_dev = {
10253         NVRAM_MINOR,
10254         "nvram",
10255 -       &nvram_fops
10256 +       &nvram_fops,
10257 +       {NULL, NULL},
10258 +       NULL,
10259 +       NULL
10260  };
10261  
10262  static int __init
10263 diff -urNp linux-2.6.20.3/drivers/char/random.c linux-2.6.20.3/drivers/char/random.c
10264 --- linux-2.6.20.3/drivers/char/random.c        2007-03-13 14:27:08.000000000 -0400
10265 +++ linux-2.6.20.3/drivers/char/random.c        2007-03-23 08:43:07.000000000 -0400
10266 @@ -248,8 +248,13 @@
10267  /*
10268   * Configuration information
10269   */
10270 +#ifdef CONFIG_GRKERNSEC_RANDNET
10271 +#define INPUT_POOL_WORDS 512
10272 +#define OUTPUT_POOL_WORDS 128
10273 +#else
10274  #define INPUT_POOL_WORDS 128
10275  #define OUTPUT_POOL_WORDS 32
10276 +#endif
10277  #define SEC_XFER_SIZE 512
10278  
10279  /*
10280 @@ -286,10 +291,17 @@ static struct poolinfo {
10281         int poolwords;
10282         int tap1, tap2, tap3, tap4, tap5;
10283  } poolinfo_table[] = {
10284 +#ifdef CONFIG_GRKERNSEC_RANDNET
10285 +       /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
10286 +       { 512,  411,    308,    208,    104,    1 },
10287 +       /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
10288 +       { 128,  103,    76,     51,     25,     1 },
10289 +#else
10290         /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
10291         { 128,  103,    76,     51,     25,     1 },
10292         /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
10293         { 32,   26,     20,     14,     7,      1 },
10294 +#endif
10295  #if 0
10296         /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
10297         { 2048, 1638,   1231,   819,    411,    1 },
10298 @@ -1662,3 +1674,25 @@ randomize_range(unsigned long start, uns
10299                 return 0;
10300         return PAGE_ALIGN(get_random_int() % range + start);
10301  }
10302 +
10303 +#if defined(CONFIG_PAX_ASLR) || defined(CONFIG_GRKERNSEC)
10304 +unsigned long pax_get_random_long(void)
10305 +{
10306 +       static time_t   rekey_time;
10307 +       static __u32    secret[12];
10308 +       time_t          t;
10309 +
10310 +       /*
10311 +        * Pick a random secret every REKEY_INTERVAL seconds.
10312 +        */
10313 +       t = get_seconds();
10314 +       if (!rekey_time || (t - rekey_time) > REKEY_INTERVAL) {
10315 +               rekey_time = t;
10316 +               get_random_bytes(secret, sizeof(secret));
10317 +       }
10318 +
10319 +       secret[1] = half_md4_transform(secret+8, secret);
10320 +       secret[0] = half_md4_transform(secret+8, secret);
10321 +       return *(unsigned long *)secret;
10322 +}
10323 +#endif
10324 diff -urNp linux-2.6.20.3/drivers/char/vt_ioctl.c linux-2.6.20.3/drivers/char/vt_ioctl.c
10325 --- linux-2.6.20.3/drivers/char/vt_ioctl.c      2007-03-13 14:27:08.000000000 -0400
10326 +++ linux-2.6.20.3/drivers/char/vt_ioctl.c      2007-03-23 08:11:31.000000000 -0400
10327 @@ -95,6 +95,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
10328         case KDSKBENT:
10329                 if (!perm)
10330                         return -EPERM;
10331 +
10332 +#ifdef CONFIG_GRKERNSEC
10333 +               if (!capable(CAP_SYS_TTY_CONFIG))
10334 +                       return -EPERM;
10335 +#endif
10336 +
10337                 if (!i && v == K_NOSUCHMAP) {
10338                         /* deallocate map */
10339                         key_map = key_maps[s];
10340 @@ -235,6 +241,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
10341                         goto reterr;
10342                 }
10343  
10344 +#ifdef CONFIG_GRKERNSEC
10345 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
10346 +                       ret = -EPERM;
10347 +                       goto reterr;
10348 +               }
10349 +#endif
10350 +
10351                 q = func_table[i];
10352                 first_free = funcbufptr + (funcbufsize - funcbufleft);
10353                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
10354 diff -urNp linux-2.6.20.3/drivers/edac/edac_mc.h linux-2.6.20.3/drivers/edac/edac_mc.h
10355 --- linux-2.6.20.3/drivers/edac/edac_mc.h       2007-03-13 14:27:08.000000000 -0400
10356 +++ linux-2.6.20.3/drivers/edac/edac_mc.h       2007-03-23 08:10:06.000000000 -0400
10357 @@ -71,11 +71,11 @@ extern int edac_debug_level;
10358  
10359  #else  /* !CONFIG_EDAC_DEBUG */
10360  
10361 -#define debugf0( ... )
10362 -#define debugf1( ... )
10363 -#define debugf2( ... )
10364 -#define debugf3( ... )
10365 -#define debugf4( ... )
10366 +#define debugf0( ... ) do {} while (0)
10367 +#define debugf1( ... ) do {} while (0)
10368 +#define debugf2( ... ) do {} while (0)
10369 +#define debugf3( ... ) do {} while (0)
10370 +#define debugf4( ... ) do {} while (0)
10371  
10372  #endif  /* !CONFIG_EDAC_DEBUG */
10373  
10374 diff -urNp linux-2.6.20.3/drivers/hwmon/fscpos.c linux-2.6.20.3/drivers/hwmon/fscpos.c
10375 --- linux-2.6.20.3/drivers/hwmon/fscpos.c       2007-03-13 14:27:08.000000000 -0400
10376 +++ linux-2.6.20.3/drivers/hwmon/fscpos.c       2007-03-23 08:10:06.000000000 -0400
10377 @@ -231,7 +231,6 @@ static ssize_t set_pwm(struct i2c_client
10378         unsigned long v = simple_strtoul(buf, NULL, 10);
10379  
10380         /* Range: 0..255 */
10381 -       if (v < 0) v = 0;
10382         if (v > 255) v = 255;
10383  
10384         mutex_lock(&data->update_lock);
10385 diff -urNp linux-2.6.20.3/drivers/hwmon/k8temp.c linux-2.6.20.3/drivers/hwmon/k8temp.c
10386 --- linux-2.6.20.3/drivers/hwmon/k8temp.c       2007-03-13 14:27:08.000000000 -0400
10387 +++ linux-2.6.20.3/drivers/hwmon/k8temp.c       2007-03-23 08:10:06.000000000 -0400
10388 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
10389  
10390  static struct pci_device_id k8temp_ids[] = {
10391         { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
10392 -       { 0 },
10393 +       { 0, 0, 0, 0, 0, 0, 0 },
10394  };
10395  
10396  MODULE_DEVICE_TABLE(pci, k8temp_ids);
10397 diff -urNp linux-2.6.20.3/drivers/hwmon/sis5595.c linux-2.6.20.3/drivers/hwmon/sis5595.c
10398 --- linux-2.6.20.3/drivers/hwmon/sis5595.c      2007-03-13 14:27:08.000000000 -0400
10399 +++ linux-2.6.20.3/drivers/hwmon/sis5595.c      2007-03-23 08:10:06.000000000 -0400
10400 @@ -757,7 +757,7 @@ static struct sis5595_data *sis5595_upda
10401  
10402  static struct pci_device_id sis5595_pci_ids[] = {
10403         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
10404 -       { 0, }
10405 +       { 0, 0, 0, 0, 0, 0, 0 }
10406  };
10407  
10408  MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
10409 diff -urNp linux-2.6.20.3/drivers/hwmon/via686a.c linux-2.6.20.3/drivers/hwmon/via686a.c
10410 --- linux-2.6.20.3/drivers/hwmon/via686a.c      2007-03-13 14:27:08.000000000 -0400
10411 +++ linux-2.6.20.3/drivers/hwmon/via686a.c      2007-03-23 08:10:06.000000000 -0400
10412 @@ -814,7 +814,7 @@ static struct via686a_data *via686a_upda
10413  
10414  static struct pci_device_id via686a_pci_ids[] = {
10415         { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
10416 -       { 0, }
10417 +       { 0, 0, 0, 0, 0, 0, 0 }
10418  };
10419  
10420  MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
10421 diff -urNp linux-2.6.20.3/drivers/hwmon/vt8231.c linux-2.6.20.3/drivers/hwmon/vt8231.c
10422 --- linux-2.6.20.3/drivers/hwmon/vt8231.c       2007-03-13 14:27:08.000000000 -0400
10423 +++ linux-2.6.20.3/drivers/hwmon/vt8231.c       2007-03-23 08:10:06.000000000 -0400
10424 @@ -666,7 +666,7 @@ static struct i2c_driver vt8231_driver =
10425  
10426  static struct pci_device_id vt8231_pci_ids[] = {
10427         { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
10428 -       { 0, }
10429 +       { 0, 0, 0, 0, 0, 0, 0 }
10430  };
10431  
10432  MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
10433 diff -urNp linux-2.6.20.3/drivers/hwmon/w83791d.c linux-2.6.20.3/drivers/hwmon/w83791d.c
10434 --- linux-2.6.20.3/drivers/hwmon/w83791d.c      2007-03-13 14:27:08.000000000 -0400
10435 +++ linux-2.6.20.3/drivers/hwmon/w83791d.c      2007-03-23 08:10:06.000000000 -0400
10436 @@ -289,8 +289,8 @@ static int w83791d_attach_adapter(struct
10437  static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind);
10438  static int w83791d_detach_client(struct i2c_client *client);
10439  
10440 -static int w83791d_read(struct i2c_client *client, u8 register);
10441 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
10442 +static int w83791d_read(struct i2c_client *client, u8 reg);
10443 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
10444  static struct w83791d_data *w83791d_update_device(struct device *dev);
10445  
10446  #ifdef DEBUG
10447 diff -urNp linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c
10448 --- linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c        2007-03-13 14:27:08.000000000 -0400
10449 +++ linux-2.6.20.3/drivers/i2c/busses/i2c-i801.c        2007-03-23 08:10:06.000000000 -0400
10450 @@ -459,7 +459,7 @@ static struct pci_device_id i801_ids[] =
10451         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) },
10452         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) },
10453         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_6) },
10454 -       { 0, }
10455 +       { 0, 0, 0, 0, 0, 0, 0 }
10456  };
10457  
10458  MODULE_DEVICE_TABLE (pci, i801_ids);
10459 diff -urNp linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c
10460 --- linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c        2007-03-13 14:27:08.000000000 -0400
10461 +++ linux-2.6.20.3/drivers/i2c/busses/i2c-i810.c        2007-03-23 08:10:06.000000000 -0400
10462 @@ -196,7 +196,7 @@ static struct pci_device_id i810_ids[] _
10463         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810E_IG) },
10464         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC) },
10465         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG) },
10466 -       { 0, },
10467 +       { 0, 0, 0, 0, 0, 0, 0 },
10468  };
10469  
10470  MODULE_DEVICE_TABLE (pci, i810_ids);
10471 diff -urNp linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c
10472 --- linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c       2007-03-13 14:27:08.000000000 -0400
10473 +++ linux-2.6.20.3/drivers/i2c/busses/i2c-piix4.c       2007-03-23 08:10:06.000000000 -0400
10474 @@ -113,7 +113,7 @@ static struct dmi_system_id __devinitdat
10475                 .ident = "IBM",
10476                 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
10477         },
10478 -       { },
10479 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
10480  };
10481  
10482  static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
10483 @@ -408,7 +408,7 @@ static struct pci_device_id piix4_ids[] 
10484           .driver_data = 3 },
10485         { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),
10486           .driver_data = 0 },
10487 -       { 0, }
10488 +       { 0, 0, 0, 0, 0, 0, 0 }
10489  };
10490  
10491  MODULE_DEVICE_TABLE (pci, piix4_ids);
10492 diff -urNp linux-2.6.20.3/drivers/i2c/i2c-core.c linux-2.6.20.3/drivers/i2c/i2c-core.c
10493 --- linux-2.6.20.3/drivers/i2c/i2c-core.c       2007-03-13 14:27:08.000000000 -0400
10494 +++ linux-2.6.20.3/drivers/i2c/i2c-core.c       2007-03-23 08:10:06.000000000 -0400
10495 @@ -113,7 +113,7 @@ static ssize_t i2c_adapter_show_name(str
10496  
10497  static struct class_device_attribute i2c_adapter_attrs[] = {
10498         __ATTR(name, S_IRUGO, i2c_adapter_show_name, NULL),
10499 -       { },
10500 +       { {NULL, NULL, 0}, NULL, NULL },
10501  };
10502  
10503  struct class i2c_adapter_class = {
10504 diff -urNp linux-2.6.20.3/drivers/ide/ide-cd.c linux-2.6.20.3/drivers/ide/ide-cd.c
10505 --- linux-2.6.20.3/drivers/ide/ide-cd.c 2007-03-13 14:27:08.000000000 -0400
10506 +++ linux-2.6.20.3/drivers/ide/ide-cd.c 2007-03-23 08:10:06.000000000 -0400
10507 @@ -457,8 +457,6 @@ void cdrom_analyze_sense_data(ide_drive_
10508                         sector &= ~(bio_sectors -1);
10509                         valid = (sector - failed_command->sector) << 9;
10510  
10511 -                       if (valid < 0)
10512 -                               valid = 0;
10513                         if (sector < get_capacity(info->disk) &&
10514                                 drive->probed_capacity - sector < 4 * 75) {
10515                                 set_capacity(info->disk, sector);
10516 diff -urNp linux-2.6.20.3/drivers/ieee1394/dv1394.c linux-2.6.20.3/drivers/ieee1394/dv1394.c
10517 --- linux-2.6.20.3/drivers/ieee1394/dv1394.c    2007-03-13 14:27:08.000000000 -0400
10518 +++ linux-2.6.20.3/drivers/ieee1394/dv1394.c    2007-03-23 08:10:06.000000000 -0400
10519 @@ -740,7 +740,7 @@ static void frame_prepare(struct video_c
10520         based upon DIF section and sequence
10521  */
10522  
10523 -static void inline
10524 +static inline void
10525  frame_put_packet (struct frame *f, struct packet *p)
10526  {
10527         int section_type = p->data[0] >> 5;           /* section type is in bits 5 - 7 */
10528 @@ -919,7 +919,7 @@ static int do_dv1394_init(struct video_c
10529                 /* default SYT offset is 3 cycles */
10530                 init->syt_offset = 3;
10531  
10532 -       if ( (init->channel > 63) || (init->channel < 0) )
10533 +       if (init->channel > 63)
10534                 init->channel = 63;
10535  
10536         chan_mask = (u64)1 << init->channel;
10537 @@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
10538                 .specifier_id   = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
10539                 .version        = AVC_SW_VERSION_ENTRY & 0xffffff
10540         },
10541 -       { }
10542 +       { 0, 0, 0, 0, 0, 0 }
10543  };
10544  
10545  MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
10546 diff -urNp linux-2.6.20.3/drivers/ieee1394/eth1394.c linux-2.6.20.3/drivers/ieee1394/eth1394.c
10547 --- linux-2.6.20.3/drivers/ieee1394/eth1394.c   2007-03-13 14:27:08.000000000 -0400
10548 +++ linux-2.6.20.3/drivers/ieee1394/eth1394.c   2007-03-23 08:10:06.000000000 -0400
10549 @@ -468,7 +468,7 @@ static struct ieee1394_device_id eth1394
10550                 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
10551                 .version = ETHER1394_GASP_VERSION,
10552         },
10553 -       {}
10554 +       { 0, 0, 0, 0, 0, 0 }
10555  };
10556  
10557  MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
10558 diff -urNp linux-2.6.20.3/drivers/ieee1394/hosts.c linux-2.6.20.3/drivers/ieee1394/hosts.c
10559 --- linux-2.6.20.3/drivers/ieee1394/hosts.c     2007-03-13 14:27:08.000000000 -0400
10560 +++ linux-2.6.20.3/drivers/ieee1394/hosts.c     2007-03-23 08:10:06.000000000 -0400
10561 @@ -79,6 +79,7 @@ static int dummy_isoctl(struct hpsb_iso 
10562  }
10563  
10564  static struct hpsb_host_driver dummy_driver = {
10565 +       .name =            "dummy",
10566         .transmit_packet = dummy_transmit_packet,
10567         .devctl =          dummy_devctl,
10568         .isoctl =          dummy_isoctl
10569 diff -urNp linux-2.6.20.3/drivers/ieee1394/ohci1394.c linux-2.6.20.3/drivers/ieee1394/ohci1394.c
10570 --- linux-2.6.20.3/drivers/ieee1394/ohci1394.c  2007-03-13 14:27:08.000000000 -0400
10571 +++ linux-2.6.20.3/drivers/ieee1394/ohci1394.c  2007-03-23 08:10:06.000000000 -0400
10572 @@ -161,9 +161,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
10573  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
10574  
10575  /* Module Parameters */
10576 -static int phys_dma = 1;
10577 +static int phys_dma = 0;
10578  module_param(phys_dma, int, 0444);
10579 -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
10580 +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0).");
10581  
10582  static void dma_trm_tasklet(unsigned long data);
10583  static void dma_trm_reset(struct dma_trm_ctx *d);
10584 @@ -3645,7 +3645,7 @@ static struct pci_device_id ohci1394_pci
10585                 .subvendor =    PCI_ANY_ID,
10586                 .subdevice =    PCI_ANY_ID,
10587         },
10588 -       { 0, },
10589 +       { 0, 0, 0, 0, 0, 0, 0 },
10590  };
10591  
10592  MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
10593 diff -urNp linux-2.6.20.3/drivers/ieee1394/raw1394.c linux-2.6.20.3/drivers/ieee1394/raw1394.c
10594 --- linux-2.6.20.3/drivers/ieee1394/raw1394.c   2007-03-13 14:27:08.000000000 -0400
10595 +++ linux-2.6.20.3/drivers/ieee1394/raw1394.c   2007-03-23 08:10:06.000000000 -0400
10596 @@ -2981,7 +2981,7 @@ static struct ieee1394_device_id raw1394
10597          .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
10598          .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
10599          .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
10600 -       {}
10601 +       { 0, 0, 0, 0, 0, 0 }
10602  };
10603  
10604  MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
10605 diff -urNp linux-2.6.20.3/drivers/ieee1394/sbp2.c linux-2.6.20.3/drivers/ieee1394/sbp2.c
10606 --- linux-2.6.20.3/drivers/ieee1394/sbp2.c      2007-03-13 14:27:08.000000000 -0400
10607 +++ linux-2.6.20.3/drivers/ieee1394/sbp2.c      2007-03-23 08:10:06.000000000 -0400
10608 @@ -250,7 +250,7 @@ static struct ieee1394_device_id sbp2_id
10609          .match_flags   = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
10610          .specifier_id  = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
10611          .version       = SBP2_SW_VERSION_ENTRY & 0xffffff},
10612 -       {}
10613 +       { 0, 0, 0, 0, 0, 0 }
10614  };
10615  MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
10616  
10617 @@ -2118,7 +2118,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
10618  MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
10619  MODULE_LICENSE("GPL");
10620  
10621 -static int sbp2_module_init(void)
10622 +static int __init sbp2_module_init(void)
10623  {
10624         int ret;
10625  
10626 diff -urNp linux-2.6.20.3/drivers/ieee1394/video1394.c linux-2.6.20.3/drivers/ieee1394/video1394.c
10627 --- linux-2.6.20.3/drivers/ieee1394/video1394.c 2007-03-13 14:27:08.000000000 -0400
10628 +++ linux-2.6.20.3/drivers/ieee1394/video1394.c 2007-03-23 08:10:06.000000000 -0400
10629 @@ -894,7 +894,7 @@ static long video1394_ioctl(struct file 
10630                 if (unlikely(d == NULL))
10631                         return -EFAULT;
10632  
10633 -               if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
10634 +               if (unlikely(v.buffer>=d->num_desc - 1)) {
10635                         PRINT(KERN_ERR, ohci->host->id,
10636                               "Buffer %d out of range",v.buffer);
10637                         return -EINVAL;
10638 @@ -960,7 +960,7 @@ static long video1394_ioctl(struct file 
10639                 if (unlikely(d == NULL))
10640                         return -EFAULT;
10641  
10642 -               if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
10643 +               if (unlikely(v.buffer>d->num_desc - 1)) {
10644                         PRINT(KERN_ERR, ohci->host->id,
10645                               "Buffer %d out of range",v.buffer);
10646                         return -EINVAL;
10647 @@ -1031,7 +1031,7 @@ static long video1394_ioctl(struct file 
10648                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
10649                 if (d == NULL) return -EFAULT;
10650  
10651 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
10652 +               if (v.buffer>=d->num_desc - 1) {
10653                         PRINT(KERN_ERR, ohci->host->id,
10654                               "Buffer %d out of range",v.buffer);
10655                         return -EINVAL;
10656 @@ -1138,7 +1138,7 @@ static long video1394_ioctl(struct file 
10657                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
10658                 if (d == NULL) return -EFAULT;
10659  
10660 -               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
10661 +               if (v.buffer>=d->num_desc-1) {
10662                         PRINT(KERN_ERR, ohci->host->id,
10663                               "Buffer %d out of range",v.buffer);
10664                         return -EINVAL;
10665 @@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
10666                  .specifier_id   = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
10667                  .version        = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
10668          },
10669 -       { }
10670 +       { 0, 0, 0, 0, 0, 0 }
10671  };
10672  
10673  MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
10674 diff -urNp linux-2.6.20.3/drivers/input/keyboard/atkbd.c linux-2.6.20.3/drivers/input/keyboard/atkbd.c
10675 --- linux-2.6.20.3/drivers/input/keyboard/atkbd.c       2007-03-13 14:27:08.000000000 -0400
10676 +++ linux-2.6.20.3/drivers/input/keyboard/atkbd.c       2007-03-23 08:10:06.000000000 -0400
10677 @@ -1065,7 +1065,7 @@ static struct serio_device_id atkbd_seri
10678                 .id     = SERIO_ANY,
10679                 .extra  = SERIO_ANY,
10680         },
10681 -       { 0 }
10682 +       { 0, 0, 0, 0 }
10683  };
10684  
10685  MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
10686 diff -urNp linux-2.6.20.3/drivers/input/mouse/lifebook.c linux-2.6.20.3/drivers/input/mouse/lifebook.c
10687 --- linux-2.6.20.3/drivers/input/mouse/lifebook.c       2007-03-13 14:27:08.000000000 -0400
10688 +++ linux-2.6.20.3/drivers/input/mouse/lifebook.c       2007-03-23 08:10:06.000000000 -0400
10689 @@ -63,7 +63,7 @@ static struct dmi_system_id lifebook_dmi
10690                         DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
10691                 },
10692         },
10693 -       { }
10694 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
10695  };
10696  
10697  static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
10698 diff -urNp linux-2.6.20.3/drivers/input/mouse/psmouse-base.c linux-2.6.20.3/drivers/input/mouse/psmouse-base.c
10699 --- linux-2.6.20.3/drivers/input/mouse/psmouse-base.c   2007-03-13 14:27:08.000000000 -0400
10700 +++ linux-2.6.20.3/drivers/input/mouse/psmouse-base.c   2007-03-23 08:10:06.000000000 -0400
10701 @@ -1282,7 +1282,7 @@ static struct serio_device_id psmouse_se
10702                 .id     = SERIO_ANY,
10703                 .extra  = SERIO_ANY,
10704         },
10705 -       { 0 }
10706 +       { 0, 0, 0, 0 }
10707  };
10708  
10709  MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
10710 diff -urNp linux-2.6.20.3/drivers/input/mouse/synaptics.c linux-2.6.20.3/drivers/input/mouse/synaptics.c
10711 --- linux-2.6.20.3/drivers/input/mouse/synaptics.c      2007-03-13 14:27:08.000000000 -0400
10712 +++ linux-2.6.20.3/drivers/input/mouse/synaptics.c      2007-03-23 08:10:06.000000000 -0400
10713 @@ -380,7 +380,7 @@ static void synaptics_process_packet(str
10714                                 break;
10715                         case 2:
10716                                 if (SYN_MODEL_PEN(priv->model_id))
10717 -                                       ;   /* Nothing, treat a pen as a single finger */
10718 +                                       break;   /* Nothing, treat a pen as a single finger */
10719                                 break;
10720                         case 4 ... 15:
10721                                 if (SYN_CAP_PALMDETECT(priv->capabilities))
10722 @@ -617,7 +617,7 @@ static struct dmi_system_id toshiba_dmi_
10723                         DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
10724                 },
10725         },
10726 -       { }
10727 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10728  };
10729  #endif
10730  
10731 diff -urNp linux-2.6.20.3/drivers/input/mousedev.c linux-2.6.20.3/drivers/input/mousedev.c
10732 --- linux-2.6.20.3/drivers/input/mousedev.c     2007-03-13 14:27:08.000000000 -0400
10733 +++ linux-2.6.20.3/drivers/input/mousedev.c     2007-03-23 08:10:06.000000000 -0400
10734 @@ -731,7 +731,7 @@ static struct input_handler mousedev_han
10735  
10736  #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
10737  static struct miscdevice psaux_mouse = {
10738 -       PSMOUSE_MINOR, "psaux", &mousedev_fops
10739 +       PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
10740  };
10741  static int psaux_registered;
10742  #endif
10743 diff -urNp linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h
10744 --- linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h        2007-03-13 14:27:08.000000000 -0400
10745 +++ linux-2.6.20.3/drivers/input/serio/i8042-x86ia64io.h        2007-03-23 08:10:06.000000000 -0400
10746 @@ -92,7 +92,7 @@ static struct dmi_system_id __initdata i
10747                         DMI_MATCH(DMI_PRODUCT_VERSION, "00"),
10748                 },
10749         },
10750 -       { }
10751 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10752  };
10753  
10754  /*
10755 @@ -201,7 +201,7 @@ static struct dmi_system_id __initdata i
10756                         DMI_MATCH(DMI_PRODUCT_NAME, "M636/A737 platform"),
10757                 },
10758         },
10759 -       { }
10760 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
10761  };
10762  
10763  
10764 diff -urNp linux-2.6.20.3/drivers/input/serio/libps2.c linux-2.6.20.3/drivers/input/serio/libps2.c
10765 --- linux-2.6.20.3/drivers/input/serio/libps2.c 2007-03-13 14:27:08.000000000 -0400
10766 +++ linux-2.6.20.3/drivers/input/serio/libps2.c 2007-03-23 08:10:06.000000000 -0400
10767 @@ -97,7 +97,7 @@ EXPORT_SYMBOL(ps2_drain);
10768  
10769  int ps2_is_keyboard_id(char id_byte)
10770  {
10771 -       const static char keyboard_ids[] = {
10772 +       static const char keyboard_ids[] = {
10773                 0xab,   /* Regular keyboards            */
10774                 0xac,   /* NCD Sun keyboard             */
10775                 0x2b,   /* Trust keyboard, translated   */
10776 diff -urNp linux-2.6.20.3/drivers/input/serio/serio_raw.c linux-2.6.20.3/drivers/input/serio/serio_raw.c
10777 --- linux-2.6.20.3/drivers/input/serio/serio_raw.c      2007-03-13 14:27:08.000000000 -0400
10778 +++ linux-2.6.20.3/drivers/input/serio/serio_raw.c      2007-03-23 08:10:06.000000000 -0400
10779 @@ -369,7 +369,7 @@ static struct serio_device_id serio_raw_
10780                 .id     = SERIO_ANY,
10781                 .extra  = SERIO_ANY,
10782         },
10783 -       { 0 }
10784 +       { 0, 0, 0, 0 }
10785  };
10786  
10787  MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
10788 diff -urNp linux-2.6.20.3/drivers/kvm/kvm_main.c linux-2.6.20.3/drivers/kvm/kvm_main.c
10789 --- linux-2.6.20.3/drivers/kvm/kvm_main.c       2007-03-13 14:27:08.000000000 -0400
10790 +++ linux-2.6.20.3/drivers/kvm/kvm_main.c       2007-03-23 08:10:06.000000000 -0400
10791 @@ -50,19 +50,19 @@ static struct kvm_stats_debugfs_item {
10792         u32 *data;
10793         struct dentry *dentry;
10794  } debugfs_entries[] = {
10795 -       { "pf_fixed", &kvm_stat.pf_fixed },
10796 -       { "pf_guest", &kvm_stat.pf_guest },
10797 -       { "tlb_flush", &kvm_stat.tlb_flush },
10798 -       { "invlpg", &kvm_stat.invlpg },
10799 -       { "exits", &kvm_stat.exits },
10800 -       { "io_exits", &kvm_stat.io_exits },
10801 -       { "mmio_exits", &kvm_stat.mmio_exits },
10802 -       { "signal_exits", &kvm_stat.signal_exits },
10803 -       { "irq_window", &kvm_stat.irq_window_exits },
10804 -       { "halt_exits", &kvm_stat.halt_exits },
10805 -       { "request_irq", &kvm_stat.request_irq_exits },
10806 -       { "irq_exits", &kvm_stat.irq_exits },
10807 -       { 0, 0 }
10808 +       { "pf_fixed", &kvm_stat.pf_fixed, NULL },
10809 +       { "pf_guest", &kvm_stat.pf_guest, NULL },
10810 +       { "tlb_flush", &kvm_stat.tlb_flush, NULL },
10811 +       { "invlpg", &kvm_stat.invlpg, NULL },
10812 +       { "exits", &kvm_stat.exits, NULL },
10813 +       { "io_exits", &kvm_stat.io_exits, NULL },
10814 +       { "mmio_exits", &kvm_stat.mmio_exits, NULL },
10815 +       { "signal_exits", &kvm_stat.signal_exits, NULL },
10816 +       { "irq_window", &kvm_stat.irq_window_exits, NULL },
10817 +       { "halt_exits", &kvm_stat.halt_exits, NULL },
10818 +       { "request_irq", &kvm_stat.request_irq_exits, NULL },
10819 +       { "irq_exits", &kvm_stat.irq_exits, NULL },
10820 +       { 0, 0, NULL }
10821  };
10822  
10823  static struct dentry *debugfs_dir;
10824 @@ -1741,7 +1741,7 @@ static int kvm_dev_ioctl_interrupt(struc
10825  
10826         if (!valid_vcpu(irq->vcpu))
10827                 return -EINVAL;
10828 -       if (irq->irq < 0 || irq->irq >= 256)
10829 +       if (irq->irq >= 256)
10830                 return -EINVAL;
10831         vcpu = vcpu_load(kvm, irq->vcpu);
10832         if (!vcpu)
10833 @@ -2003,6 +2003,9 @@ static struct miscdevice kvm_dev = {
10834         MISC_DYNAMIC_MINOR,
10835         "kvm",
10836         &kvm_chardev_ops,
10837 +       {NULL, NULL},
10838 +       NULL,
10839 +       NULL
10840  };
10841  
10842  static int kvm_reboot(struct notifier_block *notifier, unsigned long val,
10843 diff -urNp linux-2.6.20.3/drivers/kvm/vmx.c linux-2.6.20.3/drivers/kvm/vmx.c
10844 --- linux-2.6.20.3/drivers/kvm/vmx.c    2007-03-13 14:27:08.000000000 -0400
10845 +++ linux-2.6.20.3/drivers/kvm/vmx.c    2007-03-23 08:10:06.000000000 -0400
10846 @@ -1860,7 +1860,7 @@ again:
10847         vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0;
10848  
10849  #ifndef CONFIG_X86_64
10850 -       asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
10851 +       asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
10852  #endif
10853  
10854         /*
10855 diff -urNp linux-2.6.20.3/drivers/md/bitmap.c linux-2.6.20.3/drivers/md/bitmap.c
10856 --- linux-2.6.20.3/drivers/md/bitmap.c  2007-03-13 14:27:08.000000000 -0400
10857 +++ linux-2.6.20.3/drivers/md/bitmap.c  2007-03-23 08:10:06.000000000 -0400
10858 @@ -57,7 +57,7 @@
10859  #  if DEBUG > 0
10860  #    define PRINTK(x...) printk(KERN_DEBUG x)
10861  #  else
10862 -#    define PRINTK(x...)
10863 +#    define PRINTK(x...) do {} while (0)
10864  #  endif
10865  #endif
10866  
10867 diff -urNp linux-2.6.20.3/drivers/mtd/devices/doc2001.c linux-2.6.20.3/drivers/mtd/devices/doc2001.c
10868 --- linux-2.6.20.3/drivers/mtd/devices/doc2001.c        2007-03-13 14:27:08.000000000 -0400
10869 +++ linux-2.6.20.3/drivers/mtd/devices/doc2001.c        2007-03-23 08:11:31.000000000 -0400
10870 @@ -401,6 +401,8 @@ static int doc_read (struct mtd_info *mt
10871         /* Don't allow read past end of device */
10872         if (from >= this->totlen)
10873                 return -EINVAL;
10874 +       if (!len)
10875 +               return -EINVAL;
10876  
10877         /* Don't allow a single read to cross a 512-byte block boundary */
10878         if (from + len > ((from | 0x1ff) + 1))
10879 diff -urNp linux-2.6.20.3/drivers/net/eepro100.c linux-2.6.20.3/drivers/net/eepro100.c
10880 --- linux-2.6.20.3/drivers/net/eepro100.c       2007-03-13 14:27:08.000000000 -0400
10881 +++ linux-2.6.20.3/drivers/net/eepro100.c       2007-03-23 08:10:06.000000000 -0400
10882 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
10883  # define rx_align(skb)         skb_reserve((skb), 2)
10884  # define RxFD_ALIGNMENT                __attribute__ ((aligned (2), packed))
10885  #else
10886 -# define rx_align(skb)
10887 +# define rx_align(skb) do {} while (0)
10888  # define RxFD_ALIGNMENT
10889  #endif
10890  
10891 @@ -2339,33 +2339,33 @@ static void __devexit eepro100_remove_on
10892  }
10893  
10894  static struct pci_device_id eepro100_pci_tbl[] = {
10895 -       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
10896 -       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
10897 -       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
10898 -       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
10899 -       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
10900 -       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
10901 -       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
10902 -       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
10903 -       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
10904 -       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
10905 -       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
10906 -       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
10907 -       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
10908 -       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
10909 -       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
10910 -       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
10911 -       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
10912 -       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
10913 -       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
10914 -       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
10915 -       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
10916 -       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
10917 -       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
10918 -       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
10919 -       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
10920 -       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
10921 -       { 0,}
10922 +       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10923 +       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10924 +       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10925 +       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10926 +       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10927 +       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10928 +       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10929 +       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10930 +       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10931 +       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10932 +       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10933 +       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10934 +       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10935 +       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10936 +       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10937 +       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10938 +       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10939 +       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10940 +       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10941 +       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10942 +       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10943 +       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10944 +       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10945 +       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10946 +       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10947 +       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
10948 +       { 0, 0, 0, 0, 0, 0, 0 }
10949  };
10950  MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
10951  
10952 diff -urNp linux-2.6.20.3/drivers/net/pcnet32.c linux-2.6.20.3/drivers/net/pcnet32.c
10953 --- linux-2.6.20.3/drivers/net/pcnet32.c        2007-03-13 14:27:08.000000000 -0400
10954 +++ linux-2.6.20.3/drivers/net/pcnet32.c        2007-03-23 08:10:06.000000000 -0400
10955 @@ -82,7 +82,7 @@ static int cards_found;
10956  /*
10957   * VLB I/O addresses
10958   */
10959 -static unsigned int pcnet32_portlist[] __initdata =
10960 +static unsigned int pcnet32_portlist[] __devinitdata =
10961      { 0x300, 0x320, 0x340, 0x360, 0 };
10962  
10963  static int pcnet32_debug = 0;
10964 diff -urNp linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c
10965 --- linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c        2007-03-13 14:27:08.000000000 -0400
10966 +++ linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv.c        2007-03-23 08:10:06.000000000 -0400
10967 @@ -58,7 +58,7 @@ static struct pcie_port_service_id aer_i
10968         .port_type      = PCIE_RC_PORT,
10969         .service_type   = PCIE_PORT_SERVICE_AER,
10970         },
10971 -       { /* end: all zeroes */ }
10972 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
10973  };
10974  
10975  static struct pci_error_handlers aer_error_handlers = {
10976 diff -urNp linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c
10977 --- linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c   2007-03-13 14:27:08.000000000 -0400
10978 +++ linux-2.6.20.3/drivers/pci/pcie/aer/aerdrv_core.c   2007-03-23 08:10:06.000000000 -0400
10979 @@ -647,7 +647,7 @@ static void aer_isr_one_error(struct pci
10980                 struct aer_err_source *e_src)
10981  {
10982         struct device *s_device;
10983 -       struct aer_err_info e_info = {0, 0, 0,};
10984 +       struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
10985         int i;
10986         u16 id;
10987  
10988 diff -urNp linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c
10989 --- linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c       2007-03-13 14:27:08.000000000 -0400
10990 +++ linux-2.6.20.3/drivers/pci/pcie/portdrv_pci.c       2007-03-23 08:10:06.000000000 -0400
10991 @@ -265,7 +265,7 @@ static void pcie_portdrv_err_resume(stru
10992  static const struct pci_device_id port_pci_ids[] = { {
10993         /* handle any PCI-Express port */
10994         PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
10995 -       }, { /* end: all zeroes */ }
10996 +       }, { 0, 0, 0, 0, 0, 0, 0 }
10997  };
10998  MODULE_DEVICE_TABLE(pci, port_pci_ids);
10999  
11000 diff -urNp linux-2.6.20.3/drivers/pci/proc.c linux-2.6.20.3/drivers/pci/proc.c
11001 --- linux-2.6.20.3/drivers/pci/proc.c   2007-03-13 14:27:08.000000000 -0400
11002 +++ linux-2.6.20.3/drivers/pci/proc.c   2007-03-23 08:11:31.000000000 -0400
11003 @@ -467,7 +467,15 @@ static int __init pci_proc_init(void)
11004  {
11005         struct proc_dir_entry *entry;
11006         struct pci_dev *dev = NULL;
11007 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
11008 +#ifdef CONFIG_GRKERNSEC_PROC_USER
11009 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR, proc_bus);
11010 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
11011 +       proc_bus_pci_dir = proc_mkdir_mode("pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, proc_bus);
11012 +#endif
11013 +#else
11014         proc_bus_pci_dir = proc_mkdir("pci", proc_bus);
11015 +#endif
11016         entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
11017         if (entry)
11018                 entry->proc_fops = &proc_bus_pci_dev_operations;
11019 diff -urNp linux-2.6.20.3/drivers/pcmcia/ti113x.h linux-2.6.20.3/drivers/pcmcia/ti113x.h
11020 --- linux-2.6.20.3/drivers/pcmcia/ti113x.h      2007-03-13 14:27:08.000000000 -0400
11021 +++ linux-2.6.20.3/drivers/pcmcia/ti113x.h      2007-03-23 08:10:06.000000000 -0400
11022 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
11023         DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
11024                 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
11025  
11026 -       {}
11027 +       { 0, 0, 0, 0, 0, 0, 0 }
11028  };
11029  
11030  static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
11031 diff -urNp linux-2.6.20.3/drivers/pcmcia/yenta_socket.c linux-2.6.20.3/drivers/pcmcia/yenta_socket.c
11032 --- linux-2.6.20.3/drivers/pcmcia/yenta_socket.c        2007-03-13 14:27:08.000000000 -0400
11033 +++ linux-2.6.20.3/drivers/pcmcia/yenta_socket.c        2007-03-23 08:10:06.000000000 -0400
11034 @@ -1359,7 +1359,7 @@ static struct pci_device_id yenta_table 
11035  
11036         /* match any cardbus bridge */
11037         CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
11038 -       { /* all zeroes */ }
11039 +       { 0, 0, 0, 0, 0, 0, 0 }
11040  };
11041  MODULE_DEVICE_TABLE(pci, yenta_table);
11042  
11043 diff -urNp linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c
11044 --- linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c      2007-03-13 14:27:08.000000000 -0400
11045 +++ linux-2.6.20.3/drivers/pnp/pnpbios/bioscalls.c      2007-03-23 08:10:06.000000000 -0400
11046 @@ -65,7 +65,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
11047  set_limit(gdt[(selname) >> 3], size); \
11048  } while(0)
11049  
11050 -static struct desc_struct bad_bios_desc = { 0, 0x00409200 };
11051 +static struct desc_struct bad_bios_desc = { 0, 0x00409300 };
11052  
11053  /*
11054   * At some point we want to use this stack frame pointer to unwind
11055 @@ -93,6 +93,10 @@ static inline u16 call_pnp_bios(u16 func
11056         struct desc_struct save_desc_40;
11057         int cpu;
11058  
11059 +#ifdef CONFIG_PAX_KERNEXEC
11060 +       unsigned long cr0;
11061 +#endif
11062 +
11063         /*
11064          * PnP BIOSes are generally not terribly re-entrant.
11065          * Also, don't rely on them to save everything correctly.
11066 @@ -107,6 +111,10 @@ static inline u16 call_pnp_bios(u16 func
11067         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
11068         spin_lock_irqsave(&pnp_bios_lock, flags);
11069  
11070 +#ifdef CONFIG_PAX_KERNEXEC
11071 +       pax_open_kernel(cr0);
11072 +#endif
11073 +
11074         /* The lock prevents us bouncing CPU here */
11075         if (ts1_size)
11076                 Q2_SET_SEL(smp_processor_id(), PNP_TS1, ts1_base, ts1_size);
11077 @@ -142,9 +150,14 @@ static inline u16 call_pnp_bios(u16 func
11078                   "i" (0)
11079                 : "memory"
11080         );
11081 -       spin_unlock_irqrestore(&pnp_bios_lock, flags);
11082  
11083         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
11084 +
11085 +#ifdef CONFIG_PAX_KERNEXEC
11086 +       pax_close_kernel(cr0);
11087 +#endif
11088 +
11089 +       spin_unlock_irqrestore(&pnp_bios_lock, flags);
11090         put_cpu();
11091  
11092         /* If we get here and this is set then the PnP BIOS faulted on us. */
11093 diff -urNp linux-2.6.20.3/drivers/pnp/quirks.c linux-2.6.20.3/drivers/pnp/quirks.c
11094 --- linux-2.6.20.3/drivers/pnp/quirks.c 2007-03-13 14:27:08.000000000 -0400
11095 +++ linux-2.6.20.3/drivers/pnp/quirks.c 2007-03-23 08:10:06.000000000 -0400
11096 @@ -126,7 +126,7 @@ static struct pnp_fixup pnp_fixups[] = {
11097         { "CTL0043", quirk_sb16audio_resources },
11098         { "CTL0044", quirk_sb16audio_resources },
11099         { "CTL0045", quirk_sb16audio_resources },
11100 -       { "" }
11101 +       { "", NULL }
11102  };
11103  
11104  void pnp_fixup_device(struct pnp_dev *dev)
11105 diff -urNp linux-2.6.20.3/drivers/pnp/resource.c linux-2.6.20.3/drivers/pnp/resource.c
11106 --- linux-2.6.20.3/drivers/pnp/resource.c       2007-03-13 14:27:08.000000000 -0400
11107 +++ linux-2.6.20.3/drivers/pnp/resource.c       2007-03-23 08:10:06.000000000 -0400
11108 @@ -364,7 +364,7 @@ int pnp_check_irq(struct pnp_dev * dev, 
11109                 return 1;
11110  
11111         /* check if the resource is valid */
11112 -       if (*irq < 0 || *irq > 15)
11113 +       if (*irq > 15)
11114                 return 0;
11115  
11116         /* check if the resource is reserved */
11117 @@ -430,7 +430,7 @@ int pnp_check_dma(struct pnp_dev * dev, 
11118                 return 1;
11119  
11120         /* check if the resource is valid */
11121 -       if (*dma < 0 || *dma == 4 || *dma > 7)
11122 +       if (*dma == 4 || *dma > 7)
11123                 return 0;
11124  
11125         /* check if the resource is reserved */
11126 diff -urNp linux-2.6.20.3/drivers/scsi/scsi_lib.c linux-2.6.20.3/drivers/scsi/scsi_lib.c
11127 --- linux-2.6.20.3/drivers/scsi/scsi_lib.c      2007-03-13 14:27:08.000000000 -0400
11128 +++ linux-2.6.20.3/drivers/scsi/scsi_lib.c      2007-03-23 08:10:06.000000000 -0400
11129 @@ -44,7 +44,7 @@ struct scsi_host_sg_pool {
11130  #error SCSI_MAX_PHYS_SEGMENTS is too small
11131  #endif
11132  
11133 -#define SP(x) { x, "sgpool-" #x } 
11134 +#define SP(x) { x, "sgpool-" #x, NULL, NULL }
11135  static struct scsi_host_sg_pool scsi_sg_pools[] = {
11136         SP(8),
11137         SP(16),
11138 diff -urNp linux-2.6.20.3/drivers/scsi/scsi_logging.h linux-2.6.20.3/drivers/scsi/scsi_logging.h
11139 --- linux-2.6.20.3/drivers/scsi/scsi_logging.h  2007-03-13 14:27:08.000000000 -0400
11140 +++ linux-2.6.20.3/drivers/scsi/scsi_logging.h  2007-03-23 08:10:06.000000000 -0400
11141 @@ -51,7 +51,7 @@ do {                                                          \
11142                 } while (0);                                    \
11143  } while (0)
11144  #else
11145 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
11146 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
11147  #endif /* CONFIG_SCSI_LOGGING */
11148  
11149  /*
11150 diff -urNp linux-2.6.20.3/drivers/serial/8250_pci.c linux-2.6.20.3/drivers/serial/8250_pci.c
11151 --- linux-2.6.20.3/drivers/serial/8250_pci.c    2007-03-13 14:27:08.000000000 -0400
11152 +++ linux-2.6.20.3/drivers/serial/8250_pci.c    2007-03-23 08:10:06.000000000 -0400
11153 @@ -2394,7 +2394,7 @@ static struct pci_device_id serial_pci_t
11154                 PCI_ANY_ID, PCI_ANY_ID,
11155                 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
11156                 0xffff00, pbn_default },
11157 -       { 0, }
11158 +       { 0, 0, 0, 0, 0, 0, 0 }
11159  };
11160  
11161  static struct pci_driver serial_pci_driver = {
11162 diff -urNp linux-2.6.20.3/drivers/usb/class/cdc-acm.c linux-2.6.20.3/drivers/usb/class/cdc-acm.c
11163 --- linux-2.6.20.3/drivers/usb/class/cdc-acm.c  2007-03-13 14:27:08.000000000 -0400
11164 +++ linux-2.6.20.3/drivers/usb/class/cdc-acm.c  2007-03-23 08:10:06.000000000 -0400
11165 @@ -1107,7 +1107,7 @@ static struct usb_device_id acm_ids[] = 
11166                 USB_CDC_ACM_PROTO_AT_CDMA) },
11167  
11168         /* NOTE:  COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
11169 -       { }
11170 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11171  };
11172  
11173  MODULE_DEVICE_TABLE (usb, acm_ids);
11174 diff -urNp linux-2.6.20.3/drivers/usb/class/usblp.c linux-2.6.20.3/drivers/usb/class/usblp.c
11175 --- linux-2.6.20.3/drivers/usb/class/usblp.c    2007-03-13 14:27:08.000000000 -0400
11176 +++ linux-2.6.20.3/drivers/usb/class/usblp.c    2007-03-23 08:10:06.000000000 -0400
11177 @@ -218,7 +218,7 @@ static const struct quirk_printer_struct
11178         { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */
11179         { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
11180         { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
11181 -       { 0, 0 }
11182 +       { 0, 0, 0 }
11183  };
11184  
11185  static int usblp_select_alts(struct usblp *usblp);
11186 @@ -1239,7 +1239,7 @@ static struct usb_device_id usblp_ids []
11187         { USB_INTERFACE_INFO(7, 1, 1) },
11188         { USB_INTERFACE_INFO(7, 1, 2) },
11189         { USB_INTERFACE_INFO(7, 1, 3) },
11190 -       { }                                             /* Terminating entry */
11191 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }                  /* Terminating entry */
11192  };
11193  
11194  MODULE_DEVICE_TABLE (usb, usblp_ids);
11195 diff -urNp linux-2.6.20.3/drivers/usb/core/hub.c linux-2.6.20.3/drivers/usb/core/hub.c
11196 --- linux-2.6.20.3/drivers/usb/core/hub.c       2007-03-13 14:27:08.000000000 -0400
11197 +++ linux-2.6.20.3/drivers/usb/core/hub.c       2007-03-23 08:10:06.000000000 -0400
11198 @@ -2861,7 +2861,7 @@ static struct usb_device_id hub_id_table
11199        .bDeviceClass = USB_CLASS_HUB},
11200      { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
11201        .bInterfaceClass = USB_CLASS_HUB},
11202 -    { }                                                /* Terminating entry */
11203 +    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }                                             /* Terminating entry */
11204  };
11205  
11206  MODULE_DEVICE_TABLE (usb, hub_id_table);
11207 diff -urNp linux-2.6.20.3/drivers/usb/host/ehci-pci.c linux-2.6.20.3/drivers/usb/host/ehci-pci.c
11208 --- linux-2.6.20.3/drivers/usb/host/ehci-pci.c  2007-03-13 14:27:08.000000000 -0400
11209 +++ linux-2.6.20.3/drivers/usb/host/ehci-pci.c  2007-03-23 08:10:06.000000000 -0400
11210 @@ -361,7 +361,7 @@ static const struct pci_device_id pci_id
11211         PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
11212         .driver_data =  (unsigned long) &ehci_pci_hc_driver,
11213         },
11214 -       { /* end: all zeroes */ }
11215 +       { 0, 0, 0, 0, 0, 0, 0 }
11216  };
11217  MODULE_DEVICE_TABLE(pci, pci_ids);
11218  
11219 diff -urNp linux-2.6.20.3/drivers/usb/host/uhci-hcd.c linux-2.6.20.3/drivers/usb/host/uhci-hcd.c
11220 --- linux-2.6.20.3/drivers/usb/host/uhci-hcd.c  2007-03-13 14:27:08.000000000 -0400
11221 +++ linux-2.6.20.3/drivers/usb/host/uhci-hcd.c  2007-03-23 08:10:06.000000000 -0400
11222 @@ -902,7 +902,7 @@ static const struct pci_device_id uhci_p
11223         /* handle any USB UHCI controller */
11224         PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
11225         .driver_data =  (unsigned long) &uhci_driver,
11226 -       }, { /* end: all zeroes */ }
11227 +       }, { 0, 0, 0, 0, 0, 0, 0 }
11228  };
11229  
11230  MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
11231 diff -urNp linux-2.6.20.3/drivers/usb/storage/debug.h linux-2.6.20.3/drivers/usb/storage/debug.h
11232 --- linux-2.6.20.3/drivers/usb/storage/debug.h  2007-03-13 14:27:08.000000000 -0400
11233 +++ linux-2.6.20.3/drivers/usb/storage/debug.h  2007-03-23 08:10:06.000000000 -0400
11234 @@ -56,9 +56,9 @@ void usb_stor_show_sense( unsigned char 
11235  #define US_DEBUGPX(x...) printk( x )
11236  #define US_DEBUG(x) x 
11237  #else
11238 -#define US_DEBUGP(x...)
11239 -#define US_DEBUGPX(x...)
11240 -#define US_DEBUG(x)
11241 +#define US_DEBUGP(x...) do {} while (0)
11242 +#define US_DEBUGPX(x...) do {} while (0)
11243 +#define US_DEBUG(x) do {} while (0)
11244  #endif
11245  
11246  #endif
11247 diff -urNp linux-2.6.20.3/drivers/usb/storage/usb.c linux-2.6.20.3/drivers/usb/storage/usb.c
11248 --- linux-2.6.20.3/drivers/usb/storage/usb.c    2007-03-13 14:27:08.000000000 -0400
11249 +++ linux-2.6.20.3/drivers/usb/storage/usb.c    2007-03-23 08:10:06.000000000 -0400
11250 @@ -141,7 +141,7 @@ static struct usb_device_id storage_usb_
11251  #undef UNUSUAL_DEV
11252  #undef USUAL_DEV
11253         /* Terminating entry */
11254 -       { }
11255 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
11256  };
11257  
11258  MODULE_DEVICE_TABLE (usb, storage_usb_ids);
11259 @@ -181,7 +181,7 @@ static struct us_unusual_dev us_unusual_
11260  #      undef USUAL_DEV
11261  
11262         /* Terminating entry */
11263 -       { NULL }
11264 +       { NULL, NULL, 0, 0, NULL }
11265  };
11266  
11267  
11268 diff -urNp linux-2.6.20.3/drivers/video/fbcmap.c linux-2.6.20.3/drivers/video/fbcmap.c
11269 --- linux-2.6.20.3/drivers/video/fbcmap.c       2007-03-13 14:27:08.000000000 -0400
11270 +++ linux-2.6.20.3/drivers/video/fbcmap.c       2007-03-23 08:10:06.000000000 -0400
11271 @@ -251,8 +251,7 @@ int fb_set_user_cmap(struct fb_cmap_user
11272         int rc, size = cmap->len * sizeof(u16);
11273         struct fb_cmap umap;
11274  
11275 -       if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
11276 -                               !info->fbops->fb_setcmap))
11277 +       if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
11278                 return -EINVAL;
11279  
11280         memset(&umap, 0, sizeof(struct fb_cmap));
11281 diff -urNp linux-2.6.20.3/drivers/video/fbmem.c linux-2.6.20.3/drivers/video/fbmem.c
11282 --- linux-2.6.20.3/drivers/video/fbmem.c        2007-03-13 14:27:08.000000000 -0400
11283 +++ linux-2.6.20.3/drivers/video/fbmem.c        2007-03-23 08:10:06.000000000 -0400
11284 @@ -936,9 +936,9 @@ fb_ioctl(struct inode *inode, struct fil
11285         case FBIOPUT_CON2FBMAP:
11286                 if (copy_from_user(&con2fb, argp, sizeof(con2fb)))
11287                         return - EFAULT;
11288 -               if (con2fb.console < 0 || con2fb.console > MAX_NR_CONSOLES)
11289 +               if (con2fb.console > MAX_NR_CONSOLES)
11290                     return -EINVAL;
11291 -               if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
11292 +               if (con2fb.framebuffer >= FB_MAX)
11293                     return -EINVAL;
11294  #ifdef CONFIG_KMOD
11295                 if (!registered_fb[con2fb.framebuffer])
11296 diff -urNp linux-2.6.20.3/drivers/video/fbmon.c linux-2.6.20.3/drivers/video/fbmon.c
11297 --- linux-2.6.20.3/drivers/video/fbmon.c        2007-03-13 14:27:08.000000000 -0400
11298 +++ linux-2.6.20.3/drivers/video/fbmon.c        2007-03-23 08:10:06.000000000 -0400
11299 @@ -45,7 +45,7 @@
11300  #ifdef DEBUG
11301  #define DPRINTK(fmt, args...) printk(fmt,## args)
11302  #else
11303 -#define DPRINTK(fmt, args...)
11304 +#define DPRINTK(fmt, args...) do {} while (0)
11305  #endif
11306  
11307  #define FBMON_FIX_HEADER 1
11308 diff -urNp linux-2.6.20.3/drivers/video/i810/i810_accel.c linux-2.6.20.3/drivers/video/i810/i810_accel.c
11309 --- linux-2.6.20.3/drivers/video/i810/i810_accel.c      2007-03-13 14:27:08.000000000 -0400
11310 +++ linux-2.6.20.3/drivers/video/i810/i810_accel.c      2007-03-23 08:10:06.000000000 -0400
11311 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct 
11312                 }
11313         }
11314         printk("ringbuffer lockup!!!\n");
11315 +       printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
11316         i810_report_error(mmio); 
11317         par->dev_flags |= LOCKUP;
11318         info->pixmap.scan_align = 1;
11319 diff -urNp linux-2.6.20.3/drivers/video/i810/i810_main.c linux-2.6.20.3/drivers/video/i810/i810_main.c
11320 --- linux-2.6.20.3/drivers/video/i810/i810_main.c       2007-03-13 14:27:08.000000000 -0400
11321 +++ linux-2.6.20.3/drivers/video/i810/i810_main.c       2007-03-23 08:11:31.000000000 -0400
11322 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
11323           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
11324         { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
11325           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
11326 -       { 0 },
11327 +       { 0, 0, 0, 0, 0, 0, 0 },
11328  };
11329  
11330  static struct pci_driver i810fb_driver = {
11331 @@ -1506,7 +1506,7 @@ static int i810fb_cursor(struct fb_info 
11332                 int size = ((cursor->image.width + 7) >> 3) *
11333                         cursor->image.height;
11334                 int i;
11335 -               u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
11336 +               u8 *data = kmalloc(64 * 8, GFP_KERNEL);
11337  
11338                 if (data == NULL)
11339                         return -ENOMEM;
11340 diff -urNp linux-2.6.20.3/drivers/video/modedb.c linux-2.6.20.3/drivers/video/modedb.c
11341 --- linux-2.6.20.3/drivers/video/modedb.c       2007-03-13 14:27:08.000000000 -0400
11342 +++ linux-2.6.20.3/drivers/video/modedb.c       2007-03-23 08:10:06.000000000 -0400
11343 @@ -38,228 +38,228 @@ static const struct fb_videomode modedb[
11344      {
11345         /* 640x400 @ 70 Hz, 31.5 kHz hsync */
11346         NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
11347 -       0, FB_VMODE_NONINTERLACED
11348 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11349      }, {
11350         /* 640x480 @ 60 Hz, 31.5 kHz hsync */
11351         NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
11352 -       0, FB_VMODE_NONINTERLACED
11353 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11354      }, {
11355         /* 800x600 @ 56 Hz, 35.15 kHz hsync */
11356         NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
11357 -       0, FB_VMODE_NONINTERLACED
11358 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11359      }, {
11360         /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
11361         NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
11362 -       0, FB_VMODE_INTERLACED
11363 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11364      }, {
11365         /* 640x400 @ 85 Hz, 37.86 kHz hsync */
11366         NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
11367 -       FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11368 +       FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11369      }, {
11370         /* 640x480 @ 72 Hz, 36.5 kHz hsync */
11371         NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
11372 -       0, FB_VMODE_NONINTERLACED
11373 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11374      }, {
11375         /* 640x480 @ 75 Hz, 37.50 kHz hsync */
11376         NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
11377 -       0, FB_VMODE_NONINTERLACED
11378 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11379      }, {
11380         /* 800x600 @ 60 Hz, 37.8 kHz hsync */
11381         NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
11382 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11383 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11384      }, {
11385         /* 640x480 @ 85 Hz, 43.27 kHz hsync */
11386         NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
11387 -       0, FB_VMODE_NONINTERLACED
11388 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11389      }, {
11390         /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
11391         NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
11392 -       0, FB_VMODE_INTERLACED
11393 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11394      }, {
11395         /* 800x600 @ 72 Hz, 48.0 kHz hsync */
11396         NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
11397 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11398 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11399      }, {
11400         /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
11401         NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
11402 -       0, FB_VMODE_NONINTERLACED
11403 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11404      }, {
11405         /* 640x480 @ 100 Hz, 53.01 kHz hsync */
11406         NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
11407 -       0, FB_VMODE_NONINTERLACED
11408 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11409      }, {
11410         /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
11411         NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
11412 -       0, FB_VMODE_NONINTERLACED
11413 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11414      }, {
11415         /* 800x600 @ 85 Hz, 55.84 kHz hsync */
11416         NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
11417 -       0, FB_VMODE_NONINTERLACED
11418 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11419      }, {
11420         /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
11421         NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
11422 -       0, FB_VMODE_NONINTERLACED
11423 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11424      }, {
11425         /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
11426         NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
11427 -       0, FB_VMODE_INTERLACED
11428 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
11429      }, {
11430         /* 800x600 @ 100 Hz, 64.02 kHz hsync */
11431         NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
11432 -       0, FB_VMODE_NONINTERLACED
11433 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11434      }, {
11435         /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
11436         NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
11437 -       0, FB_VMODE_NONINTERLACED
11438 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11439      }, {
11440         /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
11441         NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
11442 -       0, FB_VMODE_NONINTERLACED
11443 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11444      }, {
11445         /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
11446         NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
11447 -       0, FB_VMODE_NONINTERLACED
11448 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11449      }, {
11450         /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
11451         NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
11452 -       0, FB_VMODE_NONINTERLACED       
11453 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11454      }, {
11455         /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
11456         NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
11457 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11458 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11459      }, {
11460         /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
11461          NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
11462 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11463 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11464      }, {
11465         /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
11466         NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
11467 -       0, FB_VMODE_NONINTERLACED
11468 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11469      }, {
11470         /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
11471         NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
11472 -       0, FB_VMODE_NONINTERLACED
11473 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11474      }, {
11475         /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
11476         NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
11477 -       0, FB_VMODE_NONINTERLACED
11478 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11479      }, {
11480         /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
11481         NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
11482 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11483 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11484      }, {
11485         /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
11486         NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
11487 -       0, FB_VMODE_NONINTERLACED
11488 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11489      }, {
11490         /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
11491         NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
11492 -       0, FB_VMODE_NONINTERLACED
11493 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11494      }, {
11495         /* 1024x768 @ 100Hz, 80.21 kHz hsync */
11496         NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
11497 -       0, FB_VMODE_NONINTERLACED
11498 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11499      }, {
11500         /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
11501         NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
11502 -       0, FB_VMODE_NONINTERLACED
11503 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11504      }, {
11505         /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
11506         NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
11507 -       0, FB_VMODE_NONINTERLACED
11508 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11509      }, {
11510         /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
11511         NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
11512 -       0, FB_VMODE_NONINTERLACED
11513 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11514      }, {
11515         /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
11516         NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
11517 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11518 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11519      }, {
11520         /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
11521         NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
11522 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11523 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11524      }, {
11525         /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
11526         NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
11527 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11528 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11529      }, {
11530         /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
11531         NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
11532 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11533 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11534      }, {
11535         /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
11536         NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
11537 -       0, FB_VMODE_NONINTERLACED
11538 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11539      }, {
11540         /* 1800x1440 @ 64Hz, 96.15 kHz hsync  */
11541         NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
11542 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11543 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11544      }, {
11545         /* 1800x1440 @ 70Hz, 104.52 kHz hsync  */
11546         NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
11547 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11548 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11549      }, {
11550         /* 512x384 @ 78 Hz, 31.50 kHz hsync */
11551         NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
11552 -       0, FB_VMODE_NONINTERLACED
11553 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11554      }, {
11555         /* 512x384 @ 85 Hz, 34.38 kHz hsync */
11556         NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
11557 -       0, FB_VMODE_NONINTERLACED
11558 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11559      }, {
11560         /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
11561         NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
11562 -       0, FB_VMODE_DOUBLE
11563 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11564      }, {
11565         /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
11566         NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
11567 -       0, FB_VMODE_DOUBLE
11568 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11569      }, {
11570         /* 320x240 @ 72 Hz, 36.5 kHz hsync */
11571         NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
11572 -       0, FB_VMODE_DOUBLE
11573 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11574      }, {
11575         /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
11576         NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
11577 -       0, FB_VMODE_DOUBLE
11578 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11579      }, {
11580         /* 400x300 @ 60 Hz, 37.8 kHz hsync */
11581         NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
11582 -       0, FB_VMODE_DOUBLE
11583 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11584      }, {
11585         /* 400x300 @ 72 Hz, 48.0 kHz hsync */
11586         NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
11587 -       0, FB_VMODE_DOUBLE
11588 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11589      }, {
11590         /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
11591         NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
11592 -       0, FB_VMODE_DOUBLE
11593 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11594      }, {
11595         /* 480x300 @ 60 Hz, 37.8 kHz hsync */
11596         NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
11597 -       0, FB_VMODE_DOUBLE
11598 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11599      }, {
11600         /* 480x300 @ 63 Hz, 39.6 kHz hsync */
11601         NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
11602 -       0, FB_VMODE_DOUBLE
11603 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11604      }, {
11605         /* 480x300 @ 72 Hz, 48.0 kHz hsync */
11606         NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
11607 -       0, FB_VMODE_DOUBLE
11608 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
11609      }, {
11610         /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
11611         NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
11612         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
11613 -       FB_VMODE_NONINTERLACED
11614 +       FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11615      }, {
11616         /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
11617         NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6,
11618 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
11619 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11620      }, {
11621         /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
11622         NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
11623 -       0, FB_VMODE_NONINTERLACED
11624 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
11625      },
11626  };
11627  
11628 diff -urNp linux-2.6.20.3/drivers/video/vesafb.c linux-2.6.20.3/drivers/video/vesafb.c
11629 --- linux-2.6.20.3/drivers/video/vesafb.c       2007-03-13 14:27:08.000000000 -0400
11630 +++ linux-2.6.20.3/drivers/video/vesafb.c       2007-03-23 08:10:06.000000000 -0400
11631 @@ -266,7 +266,7 @@ static int __init vesafb_probe(struct pl
11632                 size_remap = size_total;
11633         vesafb_fix.smem_len = size_remap;
11634  
11635 -#ifndef __i386__
11636 +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC)
11637         screen_info.vesapm_seg = 0;
11638  #endif
11639  
11640 diff -urNp linux-2.6.20.3/fs/binfmt_aout.c linux-2.6.20.3/fs/binfmt_aout.c
11641 --- linux-2.6.20.3/fs/binfmt_aout.c     2007-03-13 14:27:08.000000000 -0400
11642 +++ linux-2.6.20.3/fs/binfmt_aout.c     2007-03-23 08:11:31.000000000 -0400
11643 @@ -25,6 +25,7 @@
11644  #include <linux/personality.h>
11645  #include <linux/init.h>
11646  #include <linux/vs_memory.h>
11647 +#include <linux/grsecurity.h>
11648  
11649  #include <asm/system.h>
11650  #include <asm/uaccess.h>
11651 @@ -123,10 +124,12 @@ static int aout_core_dump(long signr, st
11652  /* If the size of the dump file exceeds the rlimit, then see what would happen
11653     if we wrote the stack, but not the data area.  */
11654  #ifdef __sparc__
11655 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1);
11656         if ((dump.u_dsize+dump.u_ssize) >
11657             current->signal->rlim[RLIMIT_CORE].rlim_cur)
11658                 dump.u_dsize = 0;
11659  #else
11660 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1);
11661         if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE >
11662             current->signal->rlim[RLIMIT_CORE].rlim_cur)
11663                 dump.u_dsize = 0;
11664 @@ -134,10 +137,12 @@ static int aout_core_dump(long signr, st
11665  
11666  /* Make sure we have enough room to write the stack and data areas. */
11667  #ifdef __sparc__
11668 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
11669         if ((dump.u_ssize) >
11670             current->signal->rlim[RLIMIT_CORE].rlim_cur)
11671                 dump.u_ssize = 0;
11672  #else
11673 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1);
11674         if ((dump.u_ssize+1) * PAGE_SIZE >
11675             current->signal->rlim[RLIMIT_CORE].rlim_cur)
11676                 dump.u_ssize = 0;
11677 @@ -294,6 +299,8 @@ static int load_aout_binary(struct linux
11678         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
11679         if (rlim >= RLIM_INFINITY)
11680                 rlim = ~0;
11681 +
11682 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
11683         if (ex.a_data + ex.a_bss > rlim)
11684                 return -ENOMEM;
11685  
11686 @@ -326,6 +333,28 @@ static int load_aout_binary(struct linux
11687         current->mm->mmap = NULL;
11688         compute_creds(bprm);
11689         current->flags &= ~PF_FORKNOEXEC;
11690 +
11691 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
11692 +       current->mm->pax_flags = 0UL;
11693 +#endif
11694 +
11695 +#ifdef CONFIG_PAX_PAGEEXEC
11696 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
11697 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
11698 +
11699 +#ifdef CONFIG_PAX_EMUTRAMP
11700 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
11701 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
11702 +#endif
11703 +
11704 +#ifdef CONFIG_PAX_MPROTECT
11705 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
11706 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
11707 +#endif
11708 +
11709 +       }
11710 +#endif
11711 +
11712  #ifdef __sparc__
11713         if (N_MAGIC(ex) == NMAGIC) {
11714                 loff_t pos = fd_offset;
11715 @@ -421,7 +450,7 @@ static int load_aout_binary(struct linux
11716  
11717                 down_write(&current->mm->mmap_sem);
11718                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
11719 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
11720 +                               PROT_READ | PROT_WRITE,
11721                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
11722                                 fd_offset + ex.a_text);
11723                 up_write(&current->mm->mmap_sem);
11724 diff -urNp linux-2.6.20.3/fs/binfmt_elf.c linux-2.6.20.3/fs/binfmt_elf.c
11725 --- linux-2.6.20.3/fs/binfmt_elf.c      2007-03-13 14:27:08.000000000 -0400
11726 +++ linux-2.6.20.3/fs/binfmt_elf.c      2007-03-23 08:11:31.000000000 -0400
11727 @@ -40,10 +40,16 @@
11728  #include <linux/random.h>
11729  #include <linux/elf.h>
11730  #include <linux/vs_memory.h>
11731 +#include <linux/grsecurity.h>
11732 +
11733  #include <asm/uaccess.h>
11734  #include <asm/param.h>
11735  #include <asm/page.h>
11736  
11737 +#ifdef CONFIG_PAX_SEGMEXEC
11738 +#include <asm/desc.h>
11739 +#endif
11740 +
11741  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
11742  static int load_elf_library(struct file *);
11743  static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int);
11744 @@ -84,6 +90,8 @@ static struct linux_binfmt elf_format = 
11745  
11746  static int set_brk(unsigned long start, unsigned long end)
11747  {
11748 +       unsigned long e = end;
11749 +
11750         start = ELF_PAGEALIGN(start);
11751         end = ELF_PAGEALIGN(end);
11752         if (end > start) {
11753 @@ -94,7 +102,7 @@ static int set_brk(unsigned long start, 
11754                 if (BAD_ADDR(addr))
11755                         return addr;
11756         }
11757 -       current->mm->start_brk = current->mm->brk = end;
11758 +       current->mm->start_brk = current->mm->brk = e;
11759         return 0;
11760  }
11761  
11762 @@ -315,10 +323,9 @@ static unsigned long load_elf_interp(str
11763  {
11764         struct elf_phdr *elf_phdata;
11765         struct elf_phdr *eppnt;
11766 -       unsigned long load_addr = 0;
11767 -       int load_addr_set = 0;
11768 +       unsigned long load_addr = 0, min_addr, max_addr, task_size = TASK_SIZE;
11769         unsigned long last_bss = 0, elf_bss = 0;
11770 -       unsigned long error = ~0UL;
11771 +       unsigned long error = -EINVAL;
11772         int retval, i, size;
11773  
11774         /* First of all, some simple consistency checks */
11775 @@ -357,66 +364,86 @@ static unsigned long load_elf_interp(str
11776                 goto out_close;
11777         }
11778  
11779 +#ifdef CONFIG_PAX_SEGMEXEC
11780 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
11781 +               task_size = SEGMEXEC_TASK_SIZE;
11782 +#endif
11783 +
11784         eppnt = elf_phdata;
11785 +       min_addr = task_size;
11786 +       max_addr = 0;
11787 +       error = -ENOMEM;
11788 +
11789         for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
11790 -               if (eppnt->p_type == PT_LOAD) {
11791 -                       int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
11792 -                       int elf_prot = 0;
11793 -                       unsigned long vaddr = 0;
11794 -                       unsigned long k, map_addr;
11795 -
11796 -                       if (eppnt->p_flags & PF_R)
11797 -                               elf_prot = PROT_READ;
11798 -                       if (eppnt->p_flags & PF_W)
11799 -                               elf_prot |= PROT_WRITE;
11800 -                       if (eppnt->p_flags & PF_X)
11801 -                               elf_prot |= PROT_EXEC;
11802 -                       vaddr = eppnt->p_vaddr;
11803 -                       if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
11804 -                               elf_type |= MAP_FIXED;
11805 -
11806 -                       map_addr = elf_map(interpreter, load_addr + vaddr,
11807 -                                          eppnt, elf_prot, elf_type);
11808 -                       error = map_addr;
11809 -                       if (BAD_ADDR(map_addr))
11810 -                               goto out_close;
11811 -
11812 -                       if (!load_addr_set &&
11813 -                           interp_elf_ex->e_type == ET_DYN) {
11814 -                               load_addr = map_addr - ELF_PAGESTART(vaddr);
11815 -                               load_addr_set = 1;
11816 -                       }
11817 +               if (eppnt->p_type != PT_LOAD)
11818 +                       continue;
11819  
11820 -                       /*
11821 -                        * Check to see if the section's size will overflow the
11822 -                        * allowed task size. Note that p_filesz must always be
11823 -                        * <= p_memsize so it's only necessary to check p_memsz.
11824 -                        */
11825 -                       k = load_addr + eppnt->p_vaddr;
11826 -                       if (BAD_ADDR(k) ||
11827 -                           eppnt->p_filesz > eppnt->p_memsz ||
11828 -                           eppnt->p_memsz > TASK_SIZE ||
11829 -                           TASK_SIZE - eppnt->p_memsz < k) {
11830 -                               error = -ENOMEM;
11831 -                               goto out_close;
11832 -                       }
11833 +               /*
11834 +                * Check to see if the section's size will overflow the
11835 +                * allowed task size. Note that p_filesz must always be
11836 +                * <= p_memsize so it is only necessary to check p_memsz.
11837 +                */
11838 +               if (eppnt->p_filesz > eppnt->p_memsz || eppnt->p_vaddr >= eppnt->p_vaddr + eppnt->p_memsz)
11839 +                       goto out_close;
11840  
11841 -                       /*
11842 -                        * Find the end of the file mapping for this phdr, and
11843 -                        * keep track of the largest address we see for this.
11844 -                        */
11845 -                       k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
11846 -                       if (k > elf_bss)
11847 -                               elf_bss = k;
11848 +               if (min_addr > ELF_PAGESTART(eppnt->p_vaddr))
11849 +                       min_addr = ELF_PAGESTART(eppnt->p_vaddr);
11850 +               if (max_addr < ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz))
11851 +                       max_addr = ELF_PAGEALIGN(eppnt->p_vaddr + eppnt->p_memsz);
11852 +       }
11853 +       if (min_addr >= max_addr || max_addr > task_size)
11854 +               goto out_close;
11855  
11856 -                       /*
11857 -                        * Do the same thing for the memory mapping - between
11858 -                        * elf_bss and last_bss is the bss section.
11859 -                        */
11860 -                       k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
11861 -                       if (k > last_bss)
11862 -                               last_bss = k;
11863 -               }
11864 +       if (interp_elf_ex->e_type == ET_DYN) {
11865 +               load_addr = get_unmapped_area(interpreter, 0, max_addr - min_addr, 0, MAP_PRIVATE | MAP_EXECUTABLE);
11866 +
11867 +               if (load_addr >= task_size)
11868 +                       goto out_close;
11869 +
11870 +               load_addr -= min_addr;
11871 +       }
11872 +
11873 +       eppnt = elf_phdata;
11874 +       for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
11875 +               int elf_type = MAP_PRIVATE | MAP_DENYWRITE | MAP_FIXED;
11876 +               int elf_prot = 0;
11877 +               unsigned long vaddr = 0;
11878 +               unsigned long k, map_addr;
11879 +
11880 +               if (eppnt->p_type != PT_LOAD)
11881 +                       continue;
11882 +
11883 +               if (eppnt->p_flags & PF_R)
11884 +                       elf_prot = PROT_READ;
11885 +               if (eppnt->p_flags & PF_W)
11886 +                       elf_prot |= PROT_WRITE;
11887 +               if (eppnt->p_flags & PF_X)
11888 +                       elf_prot |= PROT_EXEC;
11889 +               vaddr = eppnt->p_vaddr;
11890 +
11891 +               map_addr = elf_map(interpreter, load_addr + vaddr,
11892 +                                  eppnt, elf_prot, elf_type);
11893 +               error = map_addr;
11894 +               if (BAD_ADDR(map_addr))
11895 +                       goto out_close;
11896 +
11897 +               k = load_addr + eppnt->p_vaddr;
11898 +
11899 +               /*
11900 +                * Find the end of the file mapping for this phdr, and
11901 +                * keep track of the largest address we see for this.
11902 +                */
11903 +               k = load_addr + eppnt->p_vaddr + eppnt->p_filesz;
11904 +               if (k > elf_bss)
11905 +                       elf_bss = k;
11906 +
11907 +               /*
11908 +                * Do the same thing for the memory mapping - between
11909 +                * elf_bss and last_bss is the bss section.
11910 +                */
11911 +               k = load_addr + eppnt->p_memsz + eppnt->p_vaddr;
11912 +               if (k > last_bss)
11913 +                       last_bss = k;
11914         }
11915  
11916         /*
11917 @@ -444,6 +471,8 @@ static unsigned long load_elf_interp(str
11918  
11919         *interp_load_addr = load_addr;
11920         error = ((unsigned long)interp_elf_ex->e_entry) + load_addr;
11921 +       if (BAD_ADDR(error))
11922 +               error = -EFAULT;
11923  
11924  out_close:
11925         kfree(elf_phdata);
11926 @@ -454,7 +483,7 @@ out:
11927  static unsigned long load_aout_interp(struct exec *interp_ex,
11928                 struct file *interpreter)
11929  {
11930 -       unsigned long text_data, elf_entry = ~0UL;
11931 +       unsigned long text_data, elf_entry = -EINVAL;
11932         char __user * addr;
11933         loff_t offset;
11934  
11935 @@ -497,6 +526,180 @@ out:
11936         return elf_entry;
11937  }
11938  
11939 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
11940 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
11941 +{
11942 +       unsigned long pax_flags = 0UL;
11943 +
11944 +#ifdef CONFIG_PAX_PAGEEXEC
11945 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
11946 +               pax_flags |= MF_PAX_PAGEEXEC;
11947 +#endif
11948 +
11949 +#ifdef CONFIG_PAX_SEGMEXEC
11950 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
11951 +               pax_flags |= MF_PAX_SEGMEXEC;
11952 +#endif
11953 +
11954 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
11955 +       if (pax_flags & MF_PAX_PAGEEXEC)
11956 +               pax_flags &= ~MF_PAX_SEGMEXEC;
11957 +#endif
11958 +
11959 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
11960 +       if (pax_flags & MF_PAX_SEGMEXEC)
11961 +               pax_flags &= ~MF_PAX_PAGEEXEC;
11962 +#endif
11963 +
11964 +#ifdef CONFIG_PAX_EMUTRAMP
11965 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
11966 +               pax_flags |= MF_PAX_EMUTRAMP;
11967 +#endif
11968 +
11969 +#ifdef CONFIG_PAX_MPROTECT
11970 +       if (elf_phdata->p_flags & PF_MPROTECT)
11971 +               pax_flags |= MF_PAX_MPROTECT;
11972 +#endif
11973 +
11974 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
11975 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
11976 +               pax_flags |= MF_PAX_RANDMMAP;
11977 +#endif
11978 +
11979 +       return pax_flags;
11980 +}
11981 +#endif
11982 +
11983 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
11984 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
11985 +{
11986 +       unsigned long pax_flags = 0UL;
11987 +
11988 +#ifdef CONFIG_PAX_PAGEEXEC
11989 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
11990 +               pax_flags |= MF_PAX_PAGEEXEC;
11991 +#endif
11992 +
11993 +#ifdef CONFIG_PAX_SEGMEXEC
11994 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
11995 +               pax_flags |= MF_PAX_SEGMEXEC;
11996 +#endif
11997 +
11998 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
11999 +       if (pax_flags & MF_PAX_PAGEEXEC)
12000 +               pax_flags &= ~MF_PAX_SEGMEXEC;
12001 +#endif
12002 +
12003 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
12004 +       if (pax_flags & MF_PAX_SEGMEXEC)
12005 +               pax_flags &= ~MF_PAX_PAGEEXEC;
12006 +#endif
12007 +
12008 +#ifdef CONFIG_PAX_EMUTRAMP
12009 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
12010 +               pax_flags |= MF_PAX_EMUTRAMP;
12011 +#endif
12012 +
12013 +#ifdef CONFIG_PAX_MPROTECT
12014 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
12015 +               pax_flags |= MF_PAX_MPROTECT;
12016 +#endif
12017 +
12018 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
12019 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
12020 +               pax_flags |= MF_PAX_RANDMMAP;
12021 +#endif
12022 +
12023 +       return pax_flags;
12024 +}
12025 +#endif
12026 +
12027 +#ifdef CONFIG_PAX_EI_PAX
12028 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
12029 +{
12030 +       unsigned long pax_flags = 0UL;
12031 +
12032 +#ifdef CONFIG_PAX_PAGEEXEC
12033 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
12034 +               pax_flags |= MF_PAX_PAGEEXEC;
12035 +#endif
12036 +
12037 +#ifdef CONFIG_PAX_SEGMEXEC
12038 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
12039 +               pax_flags |= MF_PAX_SEGMEXEC;
12040 +#endif
12041 +
12042 +#ifdef CONFIG_PAX_DEFAULT_PAGEEXEC
12043 +       if (pax_flags & MF_PAX_PAGEEXEC)
12044 +               pax_flags &= ~MF_PAX_SEGMEXEC;
12045 +#endif
12046 +
12047 +#ifdef CONFIG_PAX_DEFAULT_SEGMEXEC
12048 +       if (pax_flags & MF_PAX_SEGMEXEC)
12049 +               pax_flags &= ~MF_PAX_PAGEEXEC;
12050 +#endif
12051 +
12052 +#ifdef CONFIG_PAX_EMUTRAMP
12053 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
12054 +               pax_flags |= MF_PAX_EMUTRAMP;
12055 +#endif
12056 +
12057 +#ifdef CONFIG_PAX_MPROTECT
12058 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
12059 +               pax_flags |= MF_PAX_MPROTECT;
12060 +#endif
12061 +
12062 +#ifdef CONFIG_PAX_ASLR
12063 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
12064 +               pax_flags |= MF_PAX_RANDMMAP;
12065 +#endif
12066 +
12067 +       return pax_flags;
12068 +}
12069 +#endif
12070 +
12071 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12072 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
12073 +{
12074 +       unsigned long pax_flags = 0UL;
12075 +
12076 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
12077 +       unsigned long i;
12078 +#endif
12079 +
12080 +#ifdef CONFIG_PAX_EI_PAX
12081 +       pax_flags = pax_parse_ei_pax(elf_ex);
12082 +#endif
12083 +
12084 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
12085 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
12086 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
12087 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
12088 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
12089 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
12090 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
12091 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
12092 +                               return -EINVAL;
12093 +
12094 +#ifdef CONFIG_PAX_SOFTMODE
12095 +                       if (pax_softmode)
12096 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
12097 +                       else
12098 +#endif
12099 +
12100 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
12101 +                       break;
12102 +               }
12103 +#endif
12104 +
12105 +       if (0 > pax_check_flags(&pax_flags))
12106 +               return -EINVAL;
12107 +
12108 +       current->mm->pax_flags = pax_flags;
12109 +       return 0;
12110 +}
12111 +#endif
12112 +
12113  /*
12114   * These are the functions used to load ELF style executables and shared
12115   * libraries.  There is no binary dependent code anywhere else.
12116 @@ -534,7 +737,7 @@ static int load_elf_binary(struct linux_
12117         char * elf_interpreter = NULL;
12118         unsigned int interpreter_type = INTERPRETER_NONE;
12119         unsigned char ibcs2_interpreter = 0;
12120 -       unsigned long error;
12121 +       unsigned long error = 0;
12122         struct elf_phdr *elf_ppnt, *elf_phdata;
12123         unsigned long elf_bss, elf_brk;
12124         int elf_exec_fileno;
12125 @@ -552,6 +755,7 @@ static int load_elf_binary(struct linux_
12126                 struct elfhdr interp_elf_ex;
12127                 struct exec interp_ex;
12128         } *loc;
12129 +       unsigned long task_size = TASK_SIZE;
12130  
12131         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
12132         if (!loc) {
12133 @@ -782,14 +986,91 @@ static int load_elf_binary(struct linux_
12134         current->mm->end_code = 0;
12135         current->mm->mmap = NULL;
12136         current->flags &= ~PF_FORKNOEXEC;
12137 +
12138 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
12139 +       current->mm->pax_flags = 0UL;
12140 +#endif
12141 +
12142 +#ifdef CONFIG_PAX_DLRESOLVE
12143 +       current->mm->call_dl_resolve = 0UL;
12144 +#endif
12145 +
12146 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
12147 +       current->mm->call_syscall = 0UL;
12148 +#endif
12149 +
12150 +#ifdef CONFIG_PAX_ASLR
12151 +       current->mm->delta_mmap = 0UL;
12152 +       current->mm->delta_exec = 0UL;
12153 +       current->mm->delta_stack = 0UL;
12154 +#endif
12155 +
12156         current->mm->def_flags = def_flags;
12157  
12158 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
12159 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
12160 +               send_sig(SIGKILL, current, 0);
12161 +               goto out_free_dentry;
12162 +       }
12163 +#endif
12164 +
12165 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
12166 +       pax_set_initial_flags(bprm);
12167 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
12168 +       if (pax_set_initial_flags_func)
12169 +               (pax_set_initial_flags_func)(bprm);
12170 +#endif
12171 +
12172 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
12173 +       if (current->mm->pax_flags & MF_PAX_PAGEEXEC)
12174 +               current->mm->context.user_cs_limit = PAGE_SIZE;
12175 +#endif
12176 +
12177 +#ifdef CONFIG_PAX_SEGMEXEC
12178 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
12179 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
12180 +               current->mm->context.user_cs_limit = -SEGMEXEC_TASK_SIZE;
12181 +               task_size = SEGMEXEC_TASK_SIZE;
12182 +       }
12183 +#endif
12184 +
12185 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
12186 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
12187 +               set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
12188 +               put_cpu_no_resched();
12189 +       }
12190 +#endif
12191 +
12192 +#ifdef CONFIG_PAX_ASLR
12193 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
12194 +#define pax_delta_mask(delta, lsb, len) (((delta) & ((1UL << (len)) - 1)) << (lsb))
12195 +
12196 +               current->mm->delta_mmap = pax_delta_mask(pax_get_random_long(), PAX_DELTA_MMAP_LSB(current), PAX_DELTA_MMAP_LEN(current));
12197 +               current->mm->delta_exec = pax_delta_mask(pax_get_random_long(), PAX_DELTA_EXEC_LSB(current), PAX_DELTA_EXEC_LEN(current));
12198 +               current->mm->delta_stack = pax_delta_mask(pax_get_random_long(), PAX_DELTA_STACK_LSB(current), PAX_DELTA_STACK_LEN(current));
12199 +       }
12200 +#endif
12201 +
12202 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12203 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12204 +               executable_stack = EXSTACK_DEFAULT;
12205 +#endif
12206 +
12207         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
12208            may depend on the personality.  */
12209         SET_PERSONALITY(loc->elf_ex, ibcs2_interpreter);
12210 +
12211 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12212 +       if (!(current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)))
12213 +#endif
12214 +
12215         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
12216                 current->personality |= READ_IMPLIES_EXEC;
12217  
12218 +#ifdef CONFIG_PAX_ASLR
12219 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP))
12220 +#endif
12221 +
12222         if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
12223                 current->flags |= PF_RANDOMIZE;
12224         arch_pick_mmap_layout(current->mm);
12225 @@ -865,6 +1146,15 @@ static int load_elf_binary(struct linux_
12226                          * might try to exec.  This is because the brk will
12227                          * follow the loader, and is not movable.  */
12228                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
12229 +
12230 +#ifdef CONFIG_PAX_RANDMMAP
12231 +                       /* PaX: randomize base address at the default exe base if requested */
12232 +                       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
12233 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE(current) - vaddr + current->mm->delta_exec);
12234 +                               elf_flags |= MAP_FIXED;
12235 +                       }
12236 +#endif
12237 +
12238                 }
12239  
12240                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
12241 @@ -895,9 +1185,9 @@ static int load_elf_binary(struct linux_
12242                  * allowed task size. Note that p_filesz must always be
12243                  * <= p_memsz so it is only necessary to check p_memsz.
12244                  */
12245 -               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12246 -                   elf_ppnt->p_memsz > TASK_SIZE ||
12247 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
12248 +               if (k >= task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
12249 +                   elf_ppnt->p_memsz > task_size ||
12250 +                   task_size - elf_ppnt->p_memsz < k) {
12251                         /* set_brk can never work. Avoid overflows. */
12252                         send_sig(SIGKILL, current, 0);
12253                         goto out_free_dentry;
12254 @@ -924,6 +1214,12 @@ static int load_elf_binary(struct linux_
12255         start_data += load_bias;
12256         end_data += load_bias;
12257  
12258 +#ifdef CONFIG_PAX_RANDMMAP
12259 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
12260 +               elf_brk += PAGE_SIZE + pax_delta_mask(pax_get_random_long(), 4, PAGE_SHIFT);
12261 +#undef pax_delta_mask
12262 +#endif
12263 +
12264         /* Calling set_brk effectively mmaps the pages that we need
12265          * for the bss and break sections.  We must do this before
12266          * mapping in the interpreter, to make sure it doesn't wind
12267 @@ -1186,7 +1482,7 @@ static int dump_seek(struct file *file, 
12268   *
12269   * I think we should skip something. But I am not sure how. H.J.
12270   */
12271 -static int maydump(struct vm_area_struct *vma)
12272 +static int maydump(struct vm_area_struct *vma, long signr)
12273  {
12274         /* The vma can be set up to tell us the answer directly.  */
12275         if (vma->vm_flags & VM_ALWAYSDUMP)
12276 @@ -1201,7 +1497,7 @@ static int maydump(struct vm_area_struct
12277                 return vma->vm_file->f_path.dentry->d_inode->i_nlink == 0;
12278  
12279         /* If it hasn't been written to, don't write it out */
12280 -       if (!vma->anon_vma)
12281 +       if (signr != SIGKILL && !vma->anon_vma)
12282                 return 0;
12283  
12284         return 1;
12285 @@ -1258,8 +1554,11 @@ static int writenote(struct memelfnote *
12286  #undef DUMP_WRITE
12287  
12288  #define DUMP_WRITE(addr, nr)   \
12289 +       do { \
12290 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
12291         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
12292 -               goto end_coredump;
12293 +               goto end_coredump; \
12294 +       } while (0);
12295  #define DUMP_SEEK(off) \
12296         if (!dump_seek(file, (off))) \
12297                 goto end_coredump;
12298 @@ -1647,7 +1946,7 @@ static int elf_core_dump(long signr, str
12299                 phdr.p_offset = offset;
12300                 phdr.p_vaddr = vma->vm_start;
12301                 phdr.p_paddr = 0;
12302 -               phdr.p_filesz = maydump(vma) ? sz : 0;
12303 +               phdr.p_filesz = maydump(vma, signr) ? sz : 0;
12304                 phdr.p_memsz = sz;
12305                 offset += phdr.p_filesz;
12306                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
12307 @@ -1690,7 +1989,7 @@ static int elf_core_dump(long signr, str
12308                         vma = next_vma(vma, gate_vma)) {
12309                 unsigned long addr;
12310  
12311 -               if (!maydump(vma))
12312 +               if (!maydump(vma, signr))
12313                         continue;
12314  
12315                 for (addr = vma->vm_start;
12316 @@ -1710,6 +2009,7 @@ static int elf_core_dump(long signr, str
12317                                         flush_cache_page(vma, addr,
12318                                                          page_to_pfn(page));
12319                                         kaddr = kmap(page);
12320 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
12321                                         if ((size += PAGE_SIZE) > limit ||
12322                                             !dump_write(file, kaddr,
12323                                             PAGE_SIZE)) {
12324 diff -urNp linux-2.6.20.3/fs/binfmt_flat.c linux-2.6.20.3/fs/binfmt_flat.c
12325 --- linux-2.6.20.3/fs/binfmt_flat.c     2007-03-13 14:27:08.000000000 -0400
12326 +++ linux-2.6.20.3/fs/binfmt_flat.c     2007-03-23 08:10:06.000000000 -0400
12327 @@ -551,7 +551,9 @@ static int load_flat_file(struct linux_b
12328                                 realdatastart = (unsigned long) -ENOMEM;
12329                         printk("Unable to allocate RAM for process data, errno %d\n",
12330                                         (int)-datapos);
12331 +                       down_write(&current->mm->mmap_sem);
12332                         do_munmap(current->mm, textpos, text_len);
12333 +                       up_write(&current->mm->mmap_sem);
12334                         ret = realdatastart;
12335                         goto err;
12336                 }
12337 @@ -573,8 +575,10 @@ static int load_flat_file(struct linux_b
12338                 }
12339                 if (result >= (unsigned long)-4096) {
12340                         printk("Unable to read data+bss, errno %d\n", (int)-result);
12341 +                       down_write(&current->mm->mmap_sem);
12342                         do_munmap(current->mm, textpos, text_len);
12343                         do_munmap(current->mm, realdatastart, data_len + extra);
12344 +                       up_write(&current->mm->mmap_sem);
12345                         ret = result;
12346                         goto err;
12347                 }
12348 @@ -638,8 +642,10 @@ static int load_flat_file(struct linux_b
12349                 }
12350                 if (result >= (unsigned long)-4096) {
12351                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
12352 +                       down_write(&current->mm->mmap_sem);
12353                         do_munmap(current->mm, textpos, text_len + data_len + extra +
12354                                 MAX_SHARED_LIBS * sizeof(unsigned long));
12355 +                       up_write(&current->mm->mmap_sem);
12356                         ret = result;
12357                         goto err;
12358                 }
12359 diff -urNp linux-2.6.20.3/fs/binfmt_misc.c linux-2.6.20.3/fs/binfmt_misc.c
12360 --- linux-2.6.20.3/fs/binfmt_misc.c     2007-03-13 14:27:08.000000000 -0400
12361 +++ linux-2.6.20.3/fs/binfmt_misc.c     2007-03-23 08:10:06.000000000 -0400
12362 @@ -113,9 +113,11 @@ static int load_misc_binary(struct linux
12363         struct files_struct *files = NULL;
12364  
12365         retval = -ENOEXEC;
12366 -       if (!enabled)
12367 +       if (!enabled || bprm->misc)
12368                 goto _ret;
12369  
12370 +       bprm->misc++;
12371 +
12372         /* to keep locking time low, we copy the interpreter string */
12373         read_lock(&entries_lock);
12374         fmt = check_file(bprm);
12375 @@ -729,7 +731,7 @@ static int bm_fill_super(struct super_bl
12376         static struct tree_descr bm_files[] = {
12377                 [1] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
12378                 [2] = {"register", &bm_register_operations, S_IWUSR},
12379 -               /* last one */ {""}
12380 +               /* last one */ {"", NULL, 0}
12381         };
12382         int err = simple_fill_super(sb, 0x42494e4d, bm_files);
12383         if (!err)
12384 diff -urNp linux-2.6.20.3/fs/block_dev.c linux-2.6.20.3/fs/block_dev.c
12385 --- linux-2.6.20.3/fs/block_dev.c       2007-03-13 14:27:08.000000000 -0400
12386 +++ linux-2.6.20.3/fs/block_dev.c       2007-03-23 08:10:06.000000000 -0400
12387 @@ -950,7 +950,7 @@ static int bd_claim_by_kobject(struct bl
12388                                 struct kobject *kobj)
12389  {
12390         int res;
12391 -       struct bd_holder *bo, *found;
12392 +       struct bd_holder *bo, *found = NULL;
12393  
12394         if (!kobj)
12395                 return -EINVAL;
12396 diff -urNp linux-2.6.20.3/fs/buffer.c linux-2.6.20.3/fs/buffer.c
12397 --- linux-2.6.20.3/fs/buffer.c  2007-03-13 14:27:08.000000000 -0400
12398 +++ linux-2.6.20.3/fs/buffer.c  2007-03-23 08:11:31.000000000 -0400
12399 @@ -42,6 +42,7 @@
12400  #include <linux/bitops.h>
12401  #include <linux/mpage.h>
12402  #include <linux/bit_spinlock.h>
12403 +#include <linux/grsecurity.h>
12404  
12405  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
12406  static void invalidate_bh_lrus(void);
12407 @@ -2021,6 +2022,7 @@ static int __generic_cont_expand(struct 
12408  
12409         err = -EFBIG;
12410          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
12411 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
12412         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
12413                 send_sig(SIGXFSZ, current, 0);
12414                 goto out;
12415 diff -urNp linux-2.6.20.3/fs/cifs/cifssmb.c linux-2.6.20.3/fs/cifs/cifssmb.c
12416 --- linux-2.6.20.3/fs/cifs/cifssmb.c    2007-03-13 14:27:08.000000000 -0400
12417 +++ linux-2.6.20.3/fs/cifs/cifssmb.c    2007-03-23 08:10:06.000000000 -0400
12418 @@ -2812,10 +2812,10 @@ GetExtAttrOut:
12419  
12420  
12421  /* security id for everyone */
12422 -const static struct cifs_sid sid_everyone = 
12423 +static const struct cifs_sid sid_everyone = 
12424                 {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}};
12425  /* group users */
12426 -const static struct cifs_sid sid_user = 
12427 +static const struct cifs_sid sid_user = 
12428                 {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};
12429  
12430  /* Convert CIFS ACL to POSIX form */
12431 diff -urNp linux-2.6.20.3/fs/cifs/cifs_uniupr.h linux-2.6.20.3/fs/cifs/cifs_uniupr.h
12432 --- linux-2.6.20.3/fs/cifs/cifs_uniupr.h        2007-03-13 14:27:08.000000000 -0400
12433 +++ linux-2.6.20.3/fs/cifs/cifs_uniupr.h        2007-03-23 08:10:06.000000000 -0400
12434 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
12435         {0x0490, 0x04cc, UniCaseRangeU0490},
12436         {0x1e00, 0x1ffc, UniCaseRangeU1e00},
12437         {0xff40, 0xff5a, UniCaseRangeUff40},
12438 -       {0}
12439 +       {0, 0, NULL}
12440  };
12441  #endif
12442  
12443 diff -urNp linux-2.6.20.3/fs/cifs/smbdes.c linux-2.6.20.3/fs/cifs/smbdes.c
12444 --- linux-2.6.20.3/fs/cifs/smbdes.c     2007-03-13 14:27:08.000000000 -0400
12445 +++ linux-2.6.20.3/fs/cifs/smbdes.c     2007-03-23 08:10:06.000000000 -0400
12446 @@ -196,15 +196,18 @@ dohash(char *out, char *in, char *key, i
12447         char c[28];
12448         char d[28];
12449         char *cd;
12450 -       char ki[16][48];
12451 +       char *ki;
12452         char *pd1;
12453         char l[32], r[32];
12454         char *rl;
12455 +       char *er;  /* er[48]  */
12456  
12457         /* Have to reduce stack usage */
12458 -       pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
12459 -       if(pk1 == NULL)
12460 -               return;
12461 +       pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
12462 +       ki = kmalloc(16*48, GFP_KERNEL);
12463 +       er = kmalloc(48+48+32+32+32, GFP_KERNEL);
12464 +       if (!pk1 || !ki || !er)
12465 +               goto free;
12466  
12467         cd = pk1 + 56;
12468         pd1= cd  + 56;
12469 @@ -222,7 +225,7 @@ dohash(char *out, char *in, char *key, i
12470                 lshift(d, sc[i], 28);
12471  
12472                 concat(cd, c, d, 28, 28);
12473 -               permute(ki[i], cd, perm2, 48);
12474 +               permute(ki+48*i, cd, perm2, 48);
12475         }
12476  
12477         permute(pd1, in, perm3, 64);
12478 @@ -233,18 +236,12 @@ dohash(char *out, char *in, char *key, i
12479         }
12480  
12481         for (i = 0; i < 16; i++) {
12482 -               char *er;  /* er[48]  */
12483                 char *erk; /* erk[48] */
12484                 char b[8][6];
12485                 char *cb;  /* cb[32]  */
12486                 char *pcb; /* pcb[32] */
12487                 char *r2;  /* r2[32]  */
12488  
12489 -               er = kmalloc(48+48+32+32+32, GFP_KERNEL);
12490 -               if(er == NULL) {
12491 -                       kfree(pk1);
12492 -                       return;
12493 -               }
12494                 erk = er+48;
12495                 cb  = erk+48;
12496                 pcb = cb+32;
12497 @@ -252,7 +249,7 @@ dohash(char *out, char *in, char *key, i
12498  
12499                 permute(er, r, perm4, 48);
12500  
12501 -               xor(erk, er, ki[forw ? i : 15 - i], 48);
12502 +               xor(erk, er, ki+48*(forw ? i : 15 - i), 48);
12503  
12504                 for (j = 0; j < 8; j++)
12505                         for (k = 0; k < 6; k++)
12506 @@ -282,13 +279,15 @@ dohash(char *out, char *in, char *key, i
12507  
12508                 for (j = 0; j < 32; j++)
12509                         r[j] = r2[j];
12510 -
12511 -               kfree(er);
12512         }
12513  
12514         concat(rl, r, l, 32, 32);
12515  
12516         permute(out, rl, perm6, 64);
12517 +
12518 +free:
12519 +       kfree(er);
12520 +       kfree(ki);
12521         kfree(pk1);
12522  }
12523  
12524 diff -urNp linux-2.6.20.3/fs/compat.c linux-2.6.20.3/fs/compat.c
12525 --- linux-2.6.20.3/fs/compat.c  2007-03-13 14:27:08.000000000 -0400
12526 +++ linux-2.6.20.3/fs/compat.c  2007-03-23 08:11:31.000000000 -0400
12527 @@ -48,6 +48,7 @@
12528  #include <linux/highmem.h>
12529  #include <linux/poll.h>
12530  #include <linux/mm.h>
12531 +#include <linux/grsecurity.h>
12532  
12533  #include <net/sock.h>          /* siocdevprivate_ioctl */
12534  
12535 @@ -1496,6 +1497,11 @@ int compat_do_execve(char * filename,
12536         struct file *file;
12537         int retval;
12538         int i;
12539 +#ifdef CONFIG_GRKERNSEC
12540 +       struct file *old_exec_file;
12541 +       struct acl_subject_label *old_acl;
12542 +       struct rlimit old_rlim[RLIM_NLIMITS];
12543 +#endif
12544  
12545         retval = -ENOMEM;
12546         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
12547 @@ -1513,6 +1519,15 @@ int compat_do_execve(char * filename,
12548         bprm->file = file;
12549         bprm->filename = filename;
12550         bprm->interp = filename;
12551 +
12552 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
12553 +       retval = -EAGAIN;
12554 +       if (gr_handle_nproc())
12555 +               goto out_file;
12556 +       retval = -EACCES;
12557 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
12558 +               goto out_file;
12559 +
12560         bprm->mm = mm_alloc();
12561         retval = -ENOMEM;
12562         if (!bprm->mm)
12563 @@ -1551,10 +1566,39 @@ int compat_do_execve(char * filename,
12564         if (retval < 0)
12565                 goto out;
12566  
12567 +       if (!gr_tpe_allow(file)) {
12568 +               retval = -EACCES;
12569 +               goto out;
12570 +       }
12571 +
12572 +       if (gr_check_crash_exec(file)) {
12573 +               retval = -EACCES;
12574 +               goto out;
12575 +       }
12576 +
12577 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
12578 +
12579 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
12580 +
12581 +#ifdef CONFIG_GRKERNSEC
12582 +       old_acl = current->acl;
12583 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
12584 +       old_exec_file = current->exec_file;
12585 +       get_file(file);
12586 +       current->exec_file = file;
12587 +#endif
12588 +
12589 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
12590 +
12591         retval = search_binary_handler(bprm, regs);
12592         if (retval >= 0) {
12593                 free_arg_pages(bprm);
12594  
12595 +#ifdef CONFIG_GRKERNSEC
12596 +               if (old_exec_file)
12597 +                       fput(old_exec_file);
12598 +#endif
12599 +
12600                 /* execve success */
12601                 security_bprm_free(bprm);
12602                 acct_update_integrals(current);
12603 @@ -1562,6 +1606,13 @@ int compat_do_execve(char * filename,
12604                 return retval;
12605         }
12606  
12607 +#ifdef CONFIG_GRKERNSEC
12608 +       current->acl = old_acl;
12609 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
12610 +       fput(current->exec_file);
12611 +       current->exec_file = old_exec_file;
12612 +#endif
12613 +
12614  out:
12615         /* Something went wrong, return the inode and free the argument pages*/
12616         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
12617 diff -urNp linux-2.6.20.3/fs/dcache.c linux-2.6.20.3/fs/dcache.c
12618 --- linux-2.6.20.3/fs/dcache.c  2007-03-13 14:27:08.000000000 -0400
12619 +++ linux-2.6.20.3/fs/dcache.c  2007-03-23 08:11:31.000000000 -0400
12620 @@ -1747,7 +1747,7 @@ shouldnt_be_hashed:
12621   *
12622   * "buflen" should be positive. Caller holds the dcache_lock.
12623   */
12624 -static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
12625 +char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
12626                         struct dentry *root, struct vfsmount *rootmnt,
12627                         char *buffer, int buflen)
12628  {
12629 diff -urNp linux-2.6.20.3/fs/debugfs/inode.c linux-2.6.20.3/fs/debugfs/inode.c
12630 --- linux-2.6.20.3/fs/debugfs/inode.c   2007-03-13 14:27:08.000000000 -0400
12631 +++ linux-2.6.20.3/fs/debugfs/inode.c   2007-03-23 08:10:06.000000000 -0400
12632 @@ -114,7 +114,7 @@ static inline int debugfs_positive(struc
12633  
12634  static int debug_fill_super(struct super_block *sb, void *data, int silent)
12635  {
12636 -       static struct tree_descr debug_files[] = {{""}};
12637 +       static struct tree_descr debug_files[] = {{"", NULL, 0}};
12638  
12639         return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
12640  }
12641 diff -urNp linux-2.6.20.3/fs/exec.c linux-2.6.20.3/fs/exec.c
12642 --- linux-2.6.20.3/fs/exec.c    2007-03-13 14:27:08.000000000 -0400
12643 +++ linux-2.6.20.3/fs/exec.c    2007-03-23 08:25:38.000000000 -0400
12644 @@ -51,6 +51,8 @@
12645  #include <linux/cn_proc.h>
12646  #include <linux/audit.h>
12647  #include <linux/vs_memory.h>
12648 +#include <linux/random.h>
12649 +#include <linux/grsecurity.h>
12650  
12651  #include <asm/uaccess.h>
12652  #include <asm/mmu_context.h>
12653 @@ -69,6 +71,15 @@ EXPORT_SYMBOL(suid_dumpable);
12654  static struct linux_binfmt *formats;
12655  static DEFINE_RWLOCK(binfmt_lock);
12656  
12657 +#ifdef CONFIG_PAX_SOFTMODE
12658 +unsigned int pax_softmode;
12659 +#endif
12660 +
12661 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
12662 +void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
12663 +EXPORT_SYMBOL(pax_set_initial_flags_func);
12664 +#endif
12665 +
12666  int register_binfmt(struct linux_binfmt * fmt)
12667  {
12668         struct linux_binfmt ** tmp = &formats;
12669 @@ -313,6 +324,10 @@ void install_arg_page(struct vm_area_str
12670         if (unlikely(anon_vma_prepare(vma)))
12671                 goto out;
12672  
12673 +#ifdef CONFIG_PAX_SEGMEXEC
12674 +       if (page_count(page) == 1)
12675 +#endif
12676 +
12677         flush_dcache_page(page);
12678         pte = get_locked_pte(mm, address, &ptl);
12679         if (!pte)
12680 @@ -322,9 +337,21 @@ void install_arg_page(struct vm_area_str
12681                 goto out;
12682         }
12683         inc_mm_counter(mm, anon_rss);
12684 +
12685 +#ifdef CONFIG_PAX_SEGMEXEC
12686 +       if (page_count(page) == 1)
12687 +#endif
12688 +
12689         lru_cache_add_active(page);
12690         set_pte_at(mm, address, pte, pte_mkdirty(pte_mkwrite(mk_pte(
12691                                         page, vma->vm_page_prot))));
12692 +
12693 +#ifdef CONFIG_PAX_SEGMEXEC
12694 +       if (page_count(page) != 1)
12695 +               page_add_anon_rmap(page, vma, address);
12696 +       else
12697 +#endif
12698 +
12699         page_add_new_anon_rmap(page, vma, address);
12700         pte_unmap_unlock(pte, ptl);
12701  
12702 @@ -347,6 +374,10 @@ int setup_arg_pages(struct linux_binprm 
12703         int i, ret;
12704         long arg_size;
12705  
12706 +#ifdef CONFIG_PAX_SEGMEXEC
12707 +       struct vm_area_struct *mpnt_m = NULL;
12708 +#endif
12709 +
12710  #ifdef CONFIG_STACK_GROWSUP
12711         /* Move the argument and environment strings to the bottom of the
12712          * stack space.
12713 @@ -406,11 +437,19 @@ int setup_arg_pages(struct linux_binprm 
12714                 bprm->loader += stack_base;
12715         bprm->exec += stack_base;
12716  
12717 -       mpnt = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
12718 +       mpnt = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
12719         if (!mpnt)
12720                 return -ENOMEM;
12721  
12722 -       memset(mpnt, 0, sizeof(*mpnt));
12723 +#ifdef CONFIG_PAX_SEGMEXEC
12724 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (VM_STACK_FLAGS & VM_MAYEXEC)) {
12725 +               mpnt_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
12726 +               if (!mpnt_m) {
12727 +                       kmem_cache_free(vm_area_cachep, mpnt);
12728 +                       return -ENOMEM;
12729 +               }
12730 +       }
12731 +#endif
12732  
12733         down_write(&mm->mmap_sem);
12734         {
12735 @@ -432,14 +471,51 @@ int setup_arg_pages(struct linux_binprm
12736                 else
12737                         mpnt->vm_flags = VM_STACK_FLAGS;
12738                 mpnt->vm_flags |= mm->def_flags;
12739 -               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & 0x7];
12740 +
12741 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
12742 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
12743 +                       mpnt->vm_page_prot = protection_map[(mpnt->vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
12744 +               else
12745 +#endif
12746 +
12747 +               mpnt->vm_page_prot = protection_map[mpnt->vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
12748                 if ((ret = insert_vm_struct(mm, mpnt))) {
12749                         up_write(&mm->mmap_sem);
12750                         kmem_cache_free(vm_area_cachep, mpnt);
12751 +
12752 +#ifdef CONFIG_PAX_SEGMEXEC
12753 +                       if (mpnt_m)
12754 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
12755 +#endif
12756 +
12757                         return ret;
12758                 }
12759                 vx_vmpages_sub(mm, mm->total_vm - vma_pages(mpnt));
12760                 mm->stack_vm = mm->total_vm;
12761 +
12762 +#ifdef CONFIG_PAX_SEGMEXEC
12763 +               if (mpnt_m) {
12764 +                       *mpnt_m = *mpnt;
12765 +                       if (!(mpnt->vm_flags & VM_EXEC)) {
12766 +                               mpnt_m->vm_flags &= ~(VM_READ | VM_WRITE | VM_EXEC);
12767 +                               mpnt_m->vm_page_prot = PAGE_NONE;
12768 +                       }
12769 +                       mpnt_m->vm_start += SEGMEXEC_TASK_SIZE;
12770 +                       mpnt_m->vm_end += SEGMEXEC_TASK_SIZE;
12771 +                       if ((ret = insert_vm_struct(mm, mpnt_m))) {
12772 +                               up_write(&mm->mmap_sem);
12773 +                               kmem_cache_free(vm_area_cachep, mpnt_m);
12774 +                               return ret;
12775 +                       }
12776 +                       mpnt_m->vm_flags |= VM_MIRROR;
12777 +                       mpnt->vm_flags |= VM_MIRROR;
12778 +                       mpnt_m->vm_mirror = mpnt->vm_start - mpnt_m->vm_start;
12779 +                       mpnt->vm_mirror = mpnt_m->vm_start - mpnt->vm_start;
12780 +                       mpnt_m->vm_pgoff = mpnt->vm_pgoff;
12781 +                       mm->total_vm += vma_pages(mpnt_m);
12782 +               }
12783 +#endif
12784 +
12785         }
12786  
12787         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
12788 @@ -545,6 +621,14 @@ int setup_arg_pages(struct linux_binprm 
12789                 if (page) {
12790                         bprm->page[i] = NULL;
12791                         install_arg_page(mpnt, page, stack_base);
12792 +
12793 +#ifdef CONFIG_PAX_SEGMEXEC
12794 +                       if (mpnt_m) {
12795 +                               page_cache_get(page);
12796 +                               install_arg_page(mpnt_m, page, stack_base + SEGMEXEC_TASK_SIZE);
12797 +                       }
12798 +#endif
12799 +
12800                 }
12801                 stack_base += PAGE_SIZE;
12802         }
12803 @@ -1129,6 +1213,11 @@ int do_execve(char * filename,
12804         struct file *file;
12805         int retval;
12806         int i;
12807 +#ifdef CONFIG_GRKERNSEC
12808 +       struct file *old_exec_file;
12809 +       struct acl_subject_label *old_acl;
12810 +       struct rlimit old_rlim[RLIM_NLIMITS];
12811 +#endif
12812  
12813         retval = -ENOMEM;
12814         bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
12815 @@ -1140,10 +1229,29 @@ int do_execve(char * filename,
12816         if (IS_ERR(file))
12817                 goto out_kfree;
12818  
12819 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
12820 +
12821 +       if (gr_handle_nproc()) {
12822 +               allow_write_access(file);
12823 +               fput(file);
12824 +               return -EAGAIN;
12825 +       }
12826 +
12827 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
12828 +               allow_write_access(file);
12829 +               fput(file);
12830 +               return -EACCES;
12831 +       }
12832 +
12833         sched_exec();
12834  
12835         bprm->p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *);
12836  
12837 +#ifdef CONFIG_PAX_RANDUSTACK
12838 +       if (randomize_va_space)
12839 +               bprm->p -= (pax_get_random_long() & ~(sizeof(void *)-1)) & ~PAGE_MASK;
12840 +#endif
12841 +
12842         bprm->file = file;
12843         bprm->filename = filename;
12844         bprm->interp = filename;
12845 @@ -1185,8 +1293,38 @@ int do_execve(char * filename,
12846         if (retval < 0)
12847                 goto out;
12848  
12849 +       if (!gr_tpe_allow(file)) {
12850 +               retval = -EACCES;
12851 +               goto out;
12852 +       }
12853 +
12854 +       if (gr_check_crash_exec(file)) {
12855 +               retval = -EACCES;
12856 +               goto out;
12857 +       }
12858 +
12859 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
12860 +
12861 +       gr_handle_exec_args(bprm, argv);
12862 +
12863 +#ifdef CONFIG_GRKERNSEC
12864 +       old_acl = current->acl;
12865 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
12866 +       old_exec_file = current->exec_file;
12867 +       get_file(file);
12868 +       current->exec_file = file;
12869 +#endif
12870 +
12871 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
12872 +       if (retval < 0)
12873 +               goto out_fail;
12874 +
12875         retval = search_binary_handler(bprm,regs);
12876         if (retval >= 0) {
12877 +#ifdef CONFIG_GRKERNSEC
12878 +               if (old_exec_file)
12879 +                       fput(old_exec_file);
12880 +#endif
12881                 free_arg_pages(bprm);
12882  
12883                 /* execve success */
12884 @@ -1196,6 +1334,14 @@ int do_execve(char * filename,
12885                 return retval;
12886         }
12887  
12888 +out_fail:
12889 +#ifdef CONFIG_GRKERNSEC
12890 +       current->acl = old_acl;
12891 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
12892 +       fput(current->exec_file);
12893 +       current->exec_file = old_exec_file;
12894 +#endif
12895 +
12896  out:
12897         /* Something went wrong, return the inode and free the argument pages*/
12898         for (i = 0 ; i < MAX_ARG_PAGES ; i++) {
12899 @@ -1356,6 +1502,114 @@ static void format_corename(char *corena
12900         *out_ptr = 0;
12901  }
12902  
12903 +int pax_check_flags(unsigned long * flags)
12904 +{
12905 +       int retval = 0;
12906 +
12907 +#if !defined(__i386__) || !defined(CONFIG_PAX_SEGMEXEC)
12908 +       if (*flags & MF_PAX_SEGMEXEC)
12909 +       {
12910 +               *flags &= ~MF_PAX_SEGMEXEC;
12911 +               retval = -EINVAL;
12912 +       }
12913 +#endif
12914 +
12915 +       if ((*flags & MF_PAX_PAGEEXEC)
12916 +
12917 +#ifdef CONFIG_PAX_PAGEEXEC
12918 +           &&  (*flags & MF_PAX_SEGMEXEC)
12919 +#endif
12920 +
12921 +          )
12922 +       {
12923 +               *flags &= ~MF_PAX_PAGEEXEC;
12924 +               retval = -EINVAL;
12925 +       }
12926 +
12927 +       if ((*flags & MF_PAX_MPROTECT)
12928 +
12929 +#ifdef CONFIG_PAX_MPROTECT
12930 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12931 +#endif
12932 +
12933 +          )
12934 +       {
12935 +               *flags &= ~MF_PAX_MPROTECT;
12936 +               retval = -EINVAL;
12937 +       }
12938 +
12939 +       if ((*flags & MF_PAX_EMUTRAMP)
12940 +
12941 +#ifdef CONFIG_PAX_EMUTRAMP
12942 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
12943 +#endif
12944 +
12945 +          )
12946 +       {
12947 +               *flags &= ~MF_PAX_EMUTRAMP;
12948 +               retval = -EINVAL;
12949 +       }
12950 +
12951 +       return retval;
12952 +}
12953 +
12954 +EXPORT_SYMBOL(pax_check_flags);
12955 +
12956 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
12957 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
12958 +{
12959 +       struct task_struct *tsk = current;
12960 +       struct mm_struct *mm = current->mm;
12961 +       char* buffer_exec = (char*)__get_free_page(GFP_ATOMIC);
12962 +       char* buffer_fault = (char*)__get_free_page(GFP_ATOMIC);
12963 +       char* path_exec=NULL;
12964 +       char* path_fault=NULL;
12965 +       unsigned long start=0UL, end=0UL, offset=0UL;
12966 +
12967 +       if (buffer_exec && buffer_fault) {
12968 +               struct vm_area_struct* vma, * vma_exec=NULL, * vma_fault=NULL;
12969 +
12970 +               down_read(&mm->mmap_sem);
12971 +               vma = mm->mmap;
12972 +               while (vma && (!vma_exec || !vma_fault)) {
12973 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
12974 +                               vma_exec = vma;
12975 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
12976 +                               vma_fault = vma;
12977 +                       vma = vma->vm_next;
12978 +               }
12979 +               if (vma_exec) {
12980 +                       path_exec = d_path(vma_exec->vm_file->f_path.dentry, vma_exec->vm_file->f_path.mnt, buffer_exec, PAGE_SIZE);
12981 +                       if (IS_ERR(path_exec))
12982 +                               path_exec = "<path too long>";
12983 +               }
12984 +               if (vma_fault) {
12985 +                       start = vma_fault->vm_start;
12986 +                       end = vma_fault->vm_end;
12987 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
12988 +                       if (vma_fault->vm_file) {
12989 +                               path_fault = d_path(vma_fault->vm_file->f_path.dentry, vma_fault->vm_file->f_path.mnt, buffer_fault, PAGE_SIZE);
12990 +                               if (IS_ERR(path_fault))
12991 +                                       path_fault = "<path too long>";
12992 +                       } else
12993 +                               path_fault = "<anonymous mapping>";
12994 +               }
12995 +               up_read(&mm->mmap_sem);
12996 +       }
12997 +       if (tsk->signal->curr_ip)
12998 +               printk(KERN_ERR "PAX: From %u.%u.%u.%u: execution attempt in: %s, %08lx-%08lx %08lx\n", NIPQUAD(tsk->signal->curr_ip), path_fault, start, end, offset);
12999 +       else
13000 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
13001 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
13002 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, tsk->pid,
13003 +                       tsk->uid, tsk->euid, pc, sp);
13004 +       free_page((unsigned long)buffer_exec);
13005 +       free_page((unsigned long)buffer_fault);
13006 +       pax_report_insns(pc, sp);
13007 +       do_coredump(SIGKILL, SIGKILL, regs);
13008 +}
13009 +#endif
13010 +
13011  static void zap_process(struct task_struct *start)
13012  {
13013         struct task_struct *t;
13014 @@ -1496,6 +1750,10 @@ int do_coredump(long signr, int exit_cod
13015          */
13016         clear_thread_flag(TIF_SIGPENDING);
13017  
13018 +       if (signr == SIGKILL || signr == SIGILL)
13019 +               gr_handle_brute_attach(current);
13020 +
13021 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
13022         if (current->signal->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
13023                 goto fail_unlock;
13024  
13025 diff -urNp linux-2.6.20.3/fs/ext2/balloc.c linux-2.6.20.3/fs/ext2/balloc.c
13026 --- linux-2.6.20.3/fs/ext2/balloc.c     2007-03-13 14:27:08.000000000 -0400
13027 +++ linux-2.6.20.3/fs/ext2/balloc.c     2007-03-23 08:11:31.000000000 -0400
13028 @@ -111,7 +111,7 @@ static int reserve_blocks(struct super_b
13029         if (free_blocks < count)
13030                 count = free_blocks;
13031  
13032 -       if (free_blocks < root_blocks + count && !capable(CAP_SYS_RESOURCE) &&
13033 +       if (free_blocks < root_blocks + count && !capable_nolog(CAP_SYS_RESOURCE) &&
13034             sbi->s_resuid != current->fsuid &&
13035             (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
13036                 /*
13037 diff -urNp linux-2.6.20.3/fs/ext3/balloc.c linux-2.6.20.3/fs/ext3/balloc.c
13038 --- linux-2.6.20.3/fs/ext3/balloc.c     2007-03-13 14:27:08.000000000 -0400
13039 +++ linux-2.6.20.3/fs/ext3/balloc.c     2007-03-23 08:11:31.000000000 -0400
13040 @@ -1373,7 +1373,7 @@ static int ext3_has_free_blocks(struct e
13041         DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
13042  
13043         cond = (free_blocks < root_blocks + 1 &&
13044 -               !capable(CAP_SYS_RESOURCE) &&
13045 +               !capable_nolog(CAP_SYS_RESOURCE) &&
13046                 sbi->s_resuid != current->fsuid &&
13047                 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
13048  
13049 diff -urNp linux-2.6.20.3/fs/ext3/xattr.c linux-2.6.20.3/fs/ext3/xattr.c
13050 --- linux-2.6.20.3/fs/ext3/xattr.c      2007-03-13 14:27:08.000000000 -0400
13051 +++ linux-2.6.20.3/fs/ext3/xattr.c      2007-03-23 08:10:06.000000000 -0400
13052 @@ -89,8 +89,8 @@
13053                 printk("\n"); \
13054         } while (0)
13055  #else
13056 -# define ea_idebug(f...)
13057 -# define ea_bdebug(f...)
13058 +# define ea_idebug(f...) do {} while (0)
13059 +# define ea_bdebug(f...) do {} while (0)
13060  #endif
13061  
13062  static void ext3_xattr_cache_insert(struct buffer_head *);
13063 diff -urNp linux-2.6.20.3/fs/ext4/balloc.c linux-2.6.20.3/fs/ext4/balloc.c
13064 --- linux-2.6.20.3/fs/ext4/balloc.c     2007-03-13 14:27:08.000000000 -0400
13065 +++ linux-2.6.20.3/fs/ext4/balloc.c     2007-03-23 08:11:31.000000000 -0400
13066 @@ -1390,7 +1390,7 @@ static int ext4_has_free_blocks(struct s
13067         DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
13068  
13069         cond = (free_blocks < root_blocks + 1 &&
13070 -               !capable(CAP_SYS_RESOURCE) &&
13071 +               !capable_nolog(CAP_SYS_RESOURCE) &&
13072                 sbi->s_resuid != current->fsuid &&
13073                 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
13074  
13075 diff -urNp linux-2.6.20.3/fs/fcntl.c linux-2.6.20.3/fs/fcntl.c
13076 --- linux-2.6.20.3/fs/fcntl.c   2007-03-13 14:27:08.000000000 -0400
13077 +++ linux-2.6.20.3/fs/fcntl.c   2007-03-23 08:11:31.000000000 -0400
13078 @@ -19,6 +19,7 @@
13079  #include <linux/signal.h>
13080  #include <linux/rcupdate.h>
13081  #include <linux/vs_limit.h>
13082 +#include <linux/grsecurity.h>
13083  
13084  #include <asm/poll.h>
13085  #include <asm/siginfo.h>
13086 @@ -63,6 +64,7 @@ static int locate_fd(struct files_struct
13087         struct fdtable *fdt;
13088  
13089         error = -EINVAL;
13090 +       gr_learn_resource(current, RLIMIT_NOFILE, orig_start, 0);
13091         if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13092                 goto out;
13093  
13094 @@ -83,6 +85,7 @@ repeat:
13095                                            fdt->max_fds, start);
13096         
13097         error = -EMFILE;
13098 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
13099         if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13100                 goto out;
13101         if (!vx_files_avail(1))
13102 @@ -140,6 +143,8 @@ asmlinkage long sys_dup2(unsigned int ol
13103         struct files_struct * files = current->files;
13104         struct fdtable *fdt;
13105  
13106 +       gr_learn_resource(current, RLIMIT_NOFILE, newfd, 0);
13107 +
13108         spin_lock(&files->file_lock);
13109         if (!(file = fcheck(oldfd)))
13110                 goto out_unlock;
13111 @@ -458,7 +463,8 @@ static inline int sigio_perm(struct task
13112         return (((fown->euid == 0) ||
13113                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
13114                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
13115 -               !security_file_send_sigiotask(p, fown, sig));
13116 +               !security_file_send_sigiotask(p, fown, sig) &&
13117 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
13118  }
13119  
13120  static void send_sigio_to_task(struct task_struct *p,
13121 diff -urNp linux-2.6.20.3/fs/fuse/control.c linux-2.6.20.3/fs/fuse/control.c
13122 --- linux-2.6.20.3/fs/fuse/control.c    2007-03-13 14:27:08.000000000 -0400
13123 +++ linux-2.6.20.3/fs/fuse/control.c    2007-03-23 08:10:06.000000000 -0400
13124 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
13125  
13126  static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
13127  {
13128 -       struct tree_descr empty_descr = {""};
13129 +       struct tree_descr empty_descr = {"", NULL, 0};
13130         struct fuse_conn *fc;
13131         int err;
13132  
13133 diff -urNp linux-2.6.20.3/fs/Kconfig linux-2.6.20.3/fs/Kconfig
13134 --- linux-2.6.20.3/fs/Kconfig   2007-03-13 14:27:08.000000000 -0400
13135 +++ linux-2.6.20.3/fs/Kconfig   2007-03-23 08:11:31.000000000 -0400
13136 @@ -923,7 +923,7 @@ config PROC_FS
13137  
13138  config PROC_KCORE
13139         bool "/proc/kcore support" if !ARM
13140 -       depends on PROC_FS && MMU
13141 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
13142  
13143  config PROC_VMCORE
13144          bool "/proc/vmcore support (EXPERIMENTAL)"
13145 diff -urNp linux-2.6.20.3/fs/namei.c linux-2.6.20.3/fs/namei.c
13146 --- linux-2.6.20.3/fs/namei.c   2007-03-13 14:27:08.000000000 -0400
13147 +++ linux-2.6.20.3/fs/namei.c   2007-03-23 08:11:31.000000000 -0400
13148 @@ -32,6 +32,7 @@
13149  #include <linux/vs_base.h>
13150  #include <linux/vs_tag.h>
13151  #include <linux/vs_cowbl.h>
13152 +#include <linux/grsecurity.h>
13153  #include <asm/namei.h>
13154  #include <asm/uaccess.h>
13155  
13156 @@ -637,6 +638,13 @@ static inline int do_follow_link(struct 
13157         err = security_inode_follow_link(path->dentry, nd);
13158         if (err)
13159                 goto loop;
13160 +
13161 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
13162 +                                 path->dentry->d_inode, path->dentry, nd->mnt)) {
13163 +               err = -EACCES;
13164 +               goto loop;
13165 +       }
13166 +
13167         current->link_count++;
13168         current->total_link_count++;
13169         nd->depth++;
13170 @@ -982,11 +990,18 @@ return_reval:
13171                                 break;
13172                 }
13173  return_base:
13174 +               if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt)) {
13175 +                       path_release(nd);
13176 +                       return -ENOENT;
13177 +               }
13178                 return 0;
13179  out_dput:
13180                 dput_path(&next, nd);
13181                 break;
13182         }
13183 +       if (!gr_acl_handle_hidden_file(nd->dentry, nd->mnt))
13184 +               err = -ENOENT;
13185 +
13186         path_release(nd);
13187  return_err:
13188         return err;
13189 @@ -1598,9 +1613,17 @@ static int open_namei_create(struct name
13190         int error;
13191         struct dentry *dir = nd->dentry;
13192  
13193 +       if (!gr_acl_handle_creat(path->dentry, nd->dentry, nd->mnt, flag, mode)) {
13194 +               error = -EACCES;
13195 +               goto out_unlock_dput;
13196 +       }
13197 +
13198         if (!IS_POSIXACL(dir->d_inode))
13199                 mode &= ~current->fs->umask;
13200         error = vfs_create(dir->d_inode, path->dentry, mode, nd);
13201 +       if (!error)
13202 +               gr_handle_create(path->dentry, nd->mnt);
13203 +out_unlock_dput:
13204         mutex_unlock(&dir->d_inode->i_mutex);
13205         dput(nd->dentry);
13206         nd->dentry = path->dentry;
13207 @@ -1651,6 +1674,17 @@ int open_namei(int dfd, const char *path
13208                                          nd, flag);
13209                 if (error)
13210                         return error;
13211 +
13212 +               if (gr_handle_rawio(nd->dentry->d_inode)) {
13213 +                       error = -EPERM;
13214 +                       goto exit;
13215 +               }
13216 +
13217 +               if (!gr_acl_handle_open(nd->dentry, nd->mnt, flag)) {
13218 +                       error = -EACCES;
13219 +                       goto exit;
13220 +               }
13221 +
13222                 goto ok;
13223         }
13224  
13225 @@ -1700,6 +1734,23 @@ do_last:
13226         /*
13227          * It already exists.
13228          */
13229 +
13230 +       if (gr_handle_rawio(path.dentry->d_inode)) {
13231 +               mutex_unlock(&dir->d_inode->i_mutex);
13232 +               error = -EPERM;
13233 +               goto exit_dput;
13234 +       }
13235 +       if (!gr_acl_handle_open(path.dentry, nd->mnt, flag)) {
13236 +               mutex_unlock(&dir->d_inode->i_mutex);
13237 +               error = -EACCES;
13238 +               goto exit_dput;
13239 +       }
13240 +       if (gr_handle_fifo(path.dentry, nd->mnt, dir, flag, acc_mode)) {
13241 +               mutex_unlock(&dir->d_inode->i_mutex);
13242 +               error = -EACCES;
13243 +               goto exit_dput;
13244 +       }
13245 +
13246         mutex_unlock(&dir->d_inode->i_mutex);
13247         audit_inode_update(path.dentry->d_inode);
13248  
13249 @@ -1755,6 +1806,13 @@ do_link:
13250         error = security_inode_follow_link(path.dentry, nd);
13251         if (error)
13252                 goto exit_dput;
13253 +
13254 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
13255 +                                 path.dentry, nd->mnt)) {
13256 +               error = -EACCES;
13257 +               goto exit_dput;
13258 +       }
13259 +
13260         error = __do_follow_link(&path, nd);
13261         if (error) {
13262                 /* Does someone understand code flow here? Or it is only
13263 @@ -1883,6 +1941,22 @@ asmlinkage long sys_mknodat(int dfd, con
13264         if (!IS_POSIXACL(nd.dentry->d_inode))
13265                 mode &= ~current->fs->umask;
13266         if (!IS_ERR(dentry)) {
13267 +               if (gr_handle_chroot_mknod(dentry, nd.mnt, mode)) {
13268 +                       error = -EPERM;
13269 +                       dput(dentry);
13270 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
13271 +                       path_release(&nd);
13272 +                       goto out;
13273 +               }
13274 +
13275 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
13276 +                       error = -EACCES;
13277 +                       dput(dentry);
13278 +                       mutex_unlock(&nd.dentry->d_inode->i_mutex);
13279 +                       path_release(&nd);
13280 +                       goto out;
13281 +               }
13282 +
13283                 switch (mode & S_IFMT) {
13284                 case 0: case S_IFREG:
13285                         error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd);
13286 @@ -1900,6 +1974,10 @@ asmlinkage long sys_mknodat(int dfd, con
13287                 default:
13288                         error = -EINVAL;
13289                 }
13290 +
13291 +               if (!error)
13292 +                       gr_handle_create(dentry, nd.mnt);
13293 +
13294                 dput(dentry);
13295         }
13296         mutex_unlock(&nd.dentry->d_inode->i_mutex);
13297 @@ -1957,9 +2035,18 @@ asmlinkage long sys_mkdirat(int dfd, con
13298         if (IS_ERR(dentry))
13299                 goto out_unlock;
13300  
13301 +       if (!gr_acl_handle_mkdir(dentry, nd.dentry, nd.mnt)) {
13302 +               error = -EACCES;
13303 +               goto out_unlock_dput;
13304 +       }
13305 +
13306         if (!IS_POSIXACL(nd.dentry->d_inode))
13307                 mode &= ~current->fs->umask;
13308         error = vfs_mkdir(nd.dentry->d_inode, dentry, mode, &nd);
13309 +
13310 +       if (!error)
13311 +               gr_handle_create(dentry, nd.mnt);
13312 +out_unlock_dput:
13313         dput(dentry);
13314  out_unlock:
13315         mutex_unlock(&nd.dentry->d_inode->i_mutex);
13316 @@ -2041,6 +2128,8 @@ static long do_rmdir(int dfd, const char
13317         char * name;
13318         struct dentry *dentry;
13319         struct nameidata nd;
13320 +       ino_t saved_ino = 0;
13321 +       dev_t saved_dev = 0;
13322  
13323         name = getname(pathname);
13324         if(IS_ERR(name))
13325 @@ -2066,7 +2155,22 @@ static long do_rmdir(int dfd, const char
13326         error = PTR_ERR(dentry);
13327         if (IS_ERR(dentry))
13328                 goto exit2;
13329 +
13330 +       if (dentry->d_inode != NULL) {
13331 +               if (dentry->d_inode->i_nlink <= 1) {
13332 +                       saved_ino = dentry->d_inode->i_ino;
13333 +                       saved_dev = dentry->d_inode->i_sb->s_dev;
13334 +               }
13335 +
13336 +               if (!gr_acl_handle_rmdir(dentry, nd.mnt)) {
13337 +                       error = -EACCES;
13338 +                       goto dput_exit2;
13339 +               }
13340 +       }
13341         error = vfs_rmdir(nd.dentry->d_inode, dentry, &nd);
13342 +       if (!error && (saved_dev || saved_ino))
13343 +               gr_handle_delete(saved_ino, saved_dev);
13344 +dput_exit2:
13345         dput(dentry);
13346  exit2:
13347         mutex_unlock(&nd.dentry->d_inode->i_mutex);
13348 @@ -2125,6 +2229,8 @@ static long do_unlinkat(int dfd, const c
13349         struct dentry *dentry;
13350         struct nameidata nd;
13351         struct inode *inode = NULL;
13352 +       ino_t saved_ino = 0;
13353 +       dev_t saved_dev = 0;
13354  
13355         name = getname(pathname);
13356         if(IS_ERR(name))
13357 @@ -2140,13 +2246,26 @@ static long do_unlinkat(int dfd, const c
13358         dentry = lookup_hash(&nd);
13359         error = PTR_ERR(dentry);
13360         if (!IS_ERR(dentry)) {
13361 +               error = 0;
13362                 /* Why not before? Because we want correct error value */
13363                 if (nd.last.name[nd.last.len])
13364                         goto slashes;
13365                 inode = dentry->d_inode;
13366 -               if (inode)
13367 +               if (inode) {
13368 +                       if (inode->i_nlink <= 1) {
13369 +                               saved_ino = inode->i_ino;
13370 +                               saved_dev = inode->i_sb->s_dev;
13371 +                       }
13372 +
13373 +                       if (!gr_acl_handle_unlink(dentry, nd.mnt))
13374 +                               error = -EACCES;
13375 +
13376                         atomic_inc(&inode->i_count);
13377 -               error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
13378 +               }
13379 +               if (!error)
13380 +                       error = vfs_unlink(nd.dentry->d_inode, dentry, &nd);
13381 +               if (!error && (saved_ino || saved_dev))
13382 +                       gr_handle_delete(saved_ino, saved_dev);
13383         exit2:
13384                 dput(dentry);
13385         }
13386 @@ -2227,7 +2346,16 @@ asmlinkage long sys_symlinkat(const char
13387         if (IS_ERR(dentry))
13388                 goto out_unlock;
13389  
13390 +       if (!gr_acl_handle_symlink(dentry, nd.dentry, nd.mnt, from)) {
13391 +               error = -EACCES;
13392 +               goto out_dput_unlock;
13393 +       }
13394 +
13395         error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO, &nd);
13396 +
13397 +       if (!error)
13398 +               gr_handle_create(dentry, nd.mnt);
13399 +out_dput_unlock:
13400         dput(dentry);
13401  out_unlock:
13402         mutex_unlock(&nd.dentry->d_inode->i_mutex);
13403 @@ -2322,7 +2450,25 @@ asmlinkage long sys_linkat(int olddfd, c
13404         error = PTR_ERR(new_dentry);
13405         if (IS_ERR(new_dentry))
13406                 goto out_unlock;
13407 +
13408 +       if (gr_handle_hardlink(old_nd.dentry, old_nd.mnt,
13409 +                              old_nd.dentry->d_inode,
13410 +                              old_nd.dentry->d_inode->i_mode, to)) {
13411 +               error = -EACCES;
13412 +               goto out_unlock_dput;
13413 +       }
13414 +
13415 +       if (!gr_acl_handle_link(new_dentry, nd.dentry, nd.mnt,
13416 +                               old_nd.dentry, old_nd.mnt, to)) {
13417 +               error = -EACCES;
13418 +               goto out_unlock_dput;
13419 +       }
13420 +
13421         error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry, &nd);
13422 +
13423 +       if (!error)
13424 +               gr_handle_create(new_dentry, nd.mnt);
13425 +out_unlock_dput:
13426         dput(new_dentry);
13427  out_unlock:
13428         mutex_unlock(&nd.dentry->d_inode->i_mutex);
13429 @@ -2548,8 +2694,16 @@ static int do_rename(int olddfd, const c
13430         if (new_dentry == trap)
13431                 goto exit5;
13432  
13433 -       error = vfs_rename(old_dir->d_inode, old_dentry,
13434 +       error = gr_acl_handle_rename(new_dentry, newnd.dentry, newnd.mnt,
13435 +                                    old_dentry, old_dir->d_inode, oldnd.mnt,
13436 +                                    newname);
13437 +
13438 +       if (!error)
13439 +               error = vfs_rename(old_dir->d_inode, old_dentry,
13440                                    new_dir->d_inode, new_dentry);
13441 +       if (!error)
13442 +               gr_handle_rename(old_dir->d_inode, newnd.dentry->d_inode, old_dentry, 
13443 +                                new_dentry, oldnd.mnt, new_dentry->d_inode ? 1 : 0);
13444  exit5:
13445         dput(new_dentry);
13446  exit4:
13447 diff -urNp linux-2.6.20.3/fs/namespace.c linux-2.6.20.3/fs/namespace.c
13448 --- linux-2.6.20.3/fs/namespace.c       2007-03-13 14:27:08.000000000 -0400
13449 +++ linux-2.6.20.3/fs/namespace.c       2007-03-23 08:11:31.000000000 -0400
13450 @@ -30,6 +30,7 @@
13451  #include <linux/vs_tag.h>
13452  #include <linux/vserver/space.h>
13453  #include <linux/vserver/global.h>
13454 +#include <linux/grsecurity.h>
13455  #include <asm/uaccess.h>
13456  #include <asm/unistd.h>
13457  #include "pnode.h"
13458 @@ -658,6 +659,8 @@ static int do_umount(struct vfsmount *mn
13459                         DQUOT_OFF(sb->s_dqh);
13460                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
13461                         unlock_kernel();
13462 +
13463 +                       gr_log_remount(mnt->mnt_devname, retval);
13464                 }
13465                 up_write(&sb->s_umount);
13466                 return retval;
13467 @@ -678,6 +681,9 @@ static int do_umount(struct vfsmount *mn
13468                 security_sb_umount_busy(mnt);
13469         up_write(&namespace_sem);
13470         release_mounts(&umount_list);
13471 +
13472 +       gr_log_unmount(mnt->mnt_devname, retval);
13473 +
13474         return retval;
13475  }
13476  
13477 @@ -1504,6 +1510,11 @@ long do_mount(char *dev_name, char *dir_
13478         if (retval)
13479                 goto dput_out;
13480  
13481 +       if (gr_handle_chroot_mount(nd.dentry, nd.mnt, dev_name)) {
13482 +               retval = -EPERM;
13483 +               goto dput_out;
13484 +       }
13485 +
13486         if (flags & MS_REMOUNT)
13487                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
13488                                     data_page, tag);
13489 @@ -1518,6 +1529,9 @@ long do_mount(char *dev_name, char *dir_
13490                                       dev_name, data_page);
13491  dput_out:
13492         path_release(&nd);
13493 +
13494 +       gr_log_mount(dev_name, dir_name, retval);
13495 +
13496         return retval;
13497  }
13498  
13499 @@ -1772,6 +1786,9 @@ asmlinkage long sys_pivot_root(const cha
13500         if (!capable(CAP_SYS_ADMIN))
13501                 return -EPERM;
13502  
13503 +       if (gr_handle_chroot_pivot())
13504 +               return -EPERM;
13505 +
13506         lock_kernel();
13507  
13508         error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
13509 diff -urNp linux-2.6.20.3/fs/nls/nls_base.c linux-2.6.20.3/fs/nls/nls_base.c
13510 --- linux-2.6.20.3/fs/nls/nls_base.c    2007-03-13 14:27:08.000000000 -0400
13511 +++ linux-2.6.20.3/fs/nls/nls_base.c    2007-03-23 08:10:06.000000000 -0400
13512 @@ -42,7 +42,7 @@ static struct utf8_table utf8_table[] =
13513      {0xF8,  0xF0,   3*6,    0x1FFFFF,       0x10000,   /* 4 byte sequence */},
13514      {0xFC,  0xF8,   4*6,    0x3FFFFFF,      0x200000,  /* 5 byte sequence */},
13515      {0xFE,  0xFC,   5*6,    0x7FFFFFFF,     0x4000000, /* 6 byte sequence */},
13516 -    {0,                                                       /* end of table    */}
13517 +    {0, 0, 0, 0, 0,                                   /* end of table    */}
13518  };
13519  
13520  int
13521 diff -urNp linux-2.6.20.3/fs/ntfs/file.c linux-2.6.20.3/fs/ntfs/file.c
13522 --- linux-2.6.20.3/fs/ntfs/file.c       2007-03-13 14:27:08.000000000 -0400
13523 +++ linux-2.6.20.3/fs/ntfs/file.c       2007-03-23 08:10:06.000000000 -0400
13524 @@ -2335,6 +2335,6 @@ struct inode_operations ntfs_file_inode_
13525  #endif /* NTFS_RW */
13526  };
13527  
13528 -const struct file_operations ntfs_empty_file_ops = {};
13529 +const struct file_operations ntfs_empty_file_ops;
13530  
13531 -struct inode_operations ntfs_empty_inode_ops = {};
13532 +struct inode_operations ntfs_empty_inode_ops;
13533 diff -urNp linux-2.6.20.3/fs/open.c linux-2.6.20.3/fs/open.c
13534 --- linux-2.6.20.3/fs/open.c    2007-03-13 14:27:08.000000000 -0400
13535 +++ linux-2.6.20.3/fs/open.c    2007-03-23 08:11:31.000000000 -0400
13536 @@ -27,6 +27,7 @@
13537  #include <linux/vs_dlimit.h>
13538  #include <linux/vs_tag.h>
13539  #include <linux/vs_cowbl.h>
13540 +#include <linux/grsecurity.h>
13541  
13542  int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
13543  {
13544 @@ -204,6 +205,9 @@ int do_truncate(struct dentry *dentry, l
13545         if (length < 0)
13546                 return -EINVAL;
13547  
13548 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_vfsmnt))
13549 +               return -EACCES;
13550 +
13551         newattrs.ia_size = length;
13552         newattrs.ia_valid = ATTR_SIZE | time_attrs;
13553         if (filp) {
13554 @@ -398,6 +402,9 @@ asmlinkage long sys_faccessat(int dfd, c
13555         if(IS_RDONLY(nd.dentry->d_inode) || MNT_IS_RDONLY(nd.mnt))
13556                 res = -EROFS;
13557  
13558 +       if (!res && !gr_acl_handle_access(nd.dentry, nd.mnt, mode))
13559 +               res = -EACCES;
13560 +
13561  out_path_release:
13562         path_release(&nd);
13563  out:
13564 @@ -427,6 +434,8 @@ asmlinkage long sys_chdir(const char __u
13565         if (error)
13566                 goto dput_and_out;
13567  
13568 +       gr_log_chdir(nd.dentry, nd.mnt);
13569 +
13570         set_fs_pwd(current->fs, nd.mnt, nd.dentry);
13571  
13572  dput_and_out:
13573 @@ -457,6 +466,13 @@ asmlinkage long sys_fchdir(unsigned int 
13574                 goto out_putf;
13575  
13576         error = file_permission(file, MAY_EXEC);
13577 +
13578 +       if (!error && !gr_chroot_fchdir(dentry, mnt))
13579 +               error = -EPERM;
13580 +
13581 +       if (!error)
13582 +               gr_log_chdir(dentry, mnt);
13583 +
13584         if (!error)
13585                 set_fs_pwd(current->fs, mnt, dentry);
13586  out_putf:
13587 @@ -482,8 +498,16 @@ asmlinkage long sys_chroot(const char __
13588         if (!capable(CAP_SYS_CHROOT))
13589                 goto dput_and_out;
13590  
13591 +       if (gr_handle_chroot_chroot(nd.dentry, nd.mnt))
13592 +               goto dput_and_out;
13593 +
13594         set_fs_root(current->fs, nd.mnt, nd.dentry);
13595         set_fs_altroot();
13596 +
13597 +       gr_handle_chroot_caps(current);
13598 +
13599 +       gr_handle_chroot_chdir(nd.dentry, nd.mnt);
13600 +
13601         error = 0;
13602  dput_and_out:
13603         path_release(&nd);
13604 @@ -514,9 +538,22 @@ asmlinkage long sys_fchmod(unsigned int 
13605         err = -EPERM;
13606         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13607                 goto out_putf;
13608 +
13609 +       if (!gr_acl_handle_fchmod(dentry, file->f_vfsmnt, mode)) {
13610 +               err = -EACCES;
13611 +               goto out_putf;
13612 +       }
13613 +
13614         mutex_lock(&inode->i_mutex);
13615         if (mode == (mode_t) -1)
13616                 mode = inode->i_mode;
13617 +
13618 +       if (gr_handle_chroot_chmod(dentry, file->f_vfsmnt, mode)) {
13619 +               err = -EPERM;
13620 +               mutex_unlock(&inode->i_mutex);
13621 +               goto out_putf;
13622 +       }
13623 +
13624         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
13625         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
13626         err = notify_change(dentry, &newattrs);
13627 @@ -549,9 +586,21 @@ asmlinkage long sys_fchmodat(int dfd, co
13628         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13629                 goto dput_and_out;
13630  
13631 +       if (!gr_acl_handle_chmod(nd.dentry, nd.mnt, mode)) {
13632 +               error = -EACCES;
13633 +               goto dput_and_out;
13634 +       };
13635 +
13636         mutex_lock(&inode->i_mutex);
13637         if (mode == (mode_t) -1)
13638                 mode = inode->i_mode;
13639 +
13640 +       if (gr_handle_chroot_chmod(nd.dentry, nd.mnt, mode)) {
13641 +               error = -EACCES;
13642 +               mutex_unlock(&inode->i_mutex);
13643 +               goto dput_and_out;
13644 +       }
13645 +
13646         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
13647         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
13648         error = notify_change(nd.dentry, &newattrs);
13649 @@ -595,6 +644,12 @@ static int chown_common(struct dentry * 
13650         error = -EPERM;
13651         if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
13652                 goto out;
13653 +
13654 +       if (!gr_acl_handle_chown(dentry, mnt)) {
13655 +               error = -EACCES;
13656 +               goto out;
13657 +       }
13658 +
13659         newattrs.ia_valid =  ATTR_CTIME;
13660         if (user != (uid_t) -1) {
13661                 newattrs.ia_valid |= ATTR_UID;
13662 @@ -871,6 +926,7 @@ repeat:
13663          * N.B. For clone tasks sharing a files structure, this test
13664          * will limit the total number of files that can be opened.
13665          */
13666 +       gr_learn_resource(current, RLIMIT_NOFILE, fd, 0);
13667         if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
13668                 goto out;
13669  
13670 diff -urNp linux-2.6.20.3/fs/partitions/efi.c linux-2.6.20.3/fs/partitions/efi.c
13671 --- linux-2.6.20.3/fs/partitions/efi.c  2007-03-13 14:27:08.000000000 -0400
13672 +++ linux-2.6.20.3/fs/partitions/efi.c  2007-03-23 08:10:06.000000000 -0400
13673 @@ -99,7 +99,7 @@
13674  #ifdef EFI_DEBUG
13675  #define Dprintk(x...) printk(KERN_DEBUG x)
13676  #else
13677 -#define Dprintk(x...)
13678 +#define Dprintk(x...) do {} while (0)
13679  #endif
13680  
13681  /* This allows a kernel command line option 'gpt' to override
13682 diff -urNp linux-2.6.20.3/fs/pipe.c linux-2.6.20.3/fs/pipe.c
13683 --- linux-2.6.20.3/fs/pipe.c    2007-03-13 14:27:08.000000000 -0400
13684 +++ linux-2.6.20.3/fs/pipe.c    2007-03-23 08:11:31.000000000 -0400
13685 @@ -827,7 +827,7 @@ void free_pipe_info(struct inode *inode)
13686         inode->i_pipe = NULL;
13687  }
13688  
13689 -static struct vfsmount *pipe_mnt __read_mostly;
13690 +struct vfsmount *pipe_mnt __read_mostly;
13691  static int pipefs_delete_dentry(struct dentry *dentry)
13692  {
13693         /*
13694 diff -urNp linux-2.6.20.3/fs/proc/array.c linux-2.6.20.3/fs/proc/array.c
13695 --- linux-2.6.20.3/fs/proc/array.c      2007-03-13 14:27:08.000000000 -0400
13696 +++ linux-2.6.20.3/fs/proc/array.c      2007-03-23 08:11:31.000000000 -0400
13697 @@ -304,6 +304,21 @@ static inline char *task_cap(struct task
13698                 (unsigned)vx_info_mbcap(vxi, p->cap_effective));
13699  }
13700  
13701 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13702 +static inline char *task_pax(struct task_struct *p, char *buffer)
13703 +{
13704 +       if (p->mm)
13705 +               return buffer + sprintf(buffer, "PaX:\t%c%c%c%c%c\n",
13706 +                               p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
13707 +                               p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
13708 +                               p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
13709 +                               p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
13710 +                               p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
13711 +       else
13712 +               return buffer + sprintf(buffer, "PaX:\t-----\n");
13713 +}
13714 +#endif
13715 +
13716  int proc_pid_status(struct task_struct *task, char * buffer)
13717  {
13718         char * orig = buffer;
13719 @@ -309,9 +324,20 @@ int proc_pid_status(struct task_struct *
13720  #if defined(CONFIG_S390)
13721         buffer = task_show_regs(task, buffer);
13722  #endif
13723 +
13724 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
13725 +       buffer = task_pax(task, buffer);
13726 +#endif
13727 +
13728         return buffer - orig;
13729  }
13730  
13731 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
13732 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
13733 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
13734 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
13735 +#endif
13736 +
13737  static int do_task_stat(struct task_struct *task, char * buffer, int whole)
13738  {
13739         unsigned long vsize, eip, esp, wchan = ~0UL;
13740 @@ -398,6 +424,19 @@ static int do_task_stat(struct task_stru
13741                 stime = task->stime;
13742         }
13743  
13744 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
13745 +       if (PAX_RAND_FLAGS(mm)) {
13746 +               eip = 0;
13747 +               esp = 0;
13748 +               wchan = 0;
13749 +       }
13750 +#endif
13751 +#ifdef CONFIG_GRKERNSEC_HIDESYM
13752 +       wchan = 0;
13753 +       eip =0;
13754 +       esp =0;
13755 +#endif
13756 +
13757         /* scale priority and nice values from timeslices to -20..20 */
13758         /* to make it look like a "normal" Unix priority/nice value  */
13759         priority = task_prio(task);
13760 @@ -437,9 +476,15 @@ static int do_task_stat(struct task_stru
13761                 vsize,
13762                 mm ? get_mm_rss(mm) : 0,
13763                 rsslim,
13764 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
13765 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
13766 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
13767 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
13768 +#else
13769                 mm ? mm->start_code : 0,
13770                 mm ? mm->end_code : 0,
13771                 mm ? mm->start_stack : 0,
13772 +#endif
13773                 esp,
13774                 eip,
13775                 /* The signal information here is obsolete.
13776 @@ -486,3 +531,14 @@ int proc_pid_statm(struct task_struct *t
13777         return sprintf(buffer,"%d %d %d %d %d %d %d\n",
13778                        size, resident, shared, text, lib, data, 0);
13779  }
13780 +
13781 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
13782 +int proc_pid_ipaddr(struct task_struct *task, char * buffer)
13783 +{
13784 +       int len;
13785 +
13786 +       len = sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
13787 +       return len;
13788 +}
13789 +#endif
13790 +
13791 diff -urNp linux-2.6.20.3/fs/proc/base.c linux-2.6.20.3/fs/proc/base.c
13792 --- linux-2.6.20.3/fs/proc/base.c       2007-03-13 14:27:08.000000000 -0400
13793 +++ linux-2.6.20.3/fs/proc/base.c       2007-03-23 08:11:31.000000000 -0400
13794 @@ -75,6 +75,7 @@
13795  #include <linux/oom.h>
13796  #include <linux/vs_context.h>
13797  #include <linux/vs_network.h>
13798 +#include <linux/grsecurity.h>
13799  
13800  #include "internal.h"
13801  
13802 @@ -197,7 +198,7 @@ static int proc_root_link(struct inode *
13803         (task->parent == current && \
13804         (task->ptrace & PT_PTRACED) && \
13805          (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
13806 -        security_ptrace(current,task) == 0))
13807 +        security_ptrace(current,task) == 0 && !gr_handle_proc_ptrace(task)))
13808  
13809  static int proc_pid_environ(struct task_struct *task, char * buffer)
13810  {
13811 @@ -330,6 +331,8 @@ static int proc_fd_access_allowed(struct
13812         task = get_proc_task(inode);
13813         if (task) {
13814                 allowed = ptrace_may_attach(task);
13815 +               if (allowed != 0)
13816 +                       allowed = !gr_acl_handle_procpidmem(task);
13817                 put_task_struct(task);
13818         }
13819         return allowed;
13820 @@ -523,7 +526,7 @@ static ssize_t mem_read(struct file * fi
13821         if (!task)
13822                 goto out_no_task;
13823  
13824 -       if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
13825 +       if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
13826                 goto out;
13827  
13828         ret = -ENOMEM;
13829 @@ -593,7 +596,7 @@ static ssize_t mem_write(struct file * f
13830         if (!task)
13831                 goto out_no_task;
13832  
13833 -       if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
13834 +       if (!MAY_PTRACE(task) || !ptrace_may_attach(task) || gr_acl_handle_procpidmem(task))
13835                 goto out;
13836  
13837         copied = -ENOMEM;
13838 @@ -1035,7 +1038,11 @@ static struct inode *proc_pid_make_inode
13839         inode->i_gid = 0;
13840         if (task_dumpable(task)) {
13841                 inode->i_uid = task->euid;
13842 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13843 +               inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
13844 +#else
13845                 inode->i_gid = task->egid;
13846 +#endif
13847         }
13848         /* procfs is xid tagged */
13849         inode->i_tag = (tag_t)vx_task_xid(task);
13850 @@ -1048,17 +1055,45 @@ static int pid_getattr(struct vfsmount *
13851  {
13852         struct inode *inode = dentry->d_inode;
13853         struct task_struct *task;
13854 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13855 +       struct task_struct *tmp = current;
13856 +#endif
13857 +
13858         generic_fillattr(inode, stat);
13859  
13860         rcu_read_lock();
13861         stat->uid = 0;
13862         stat->gid = 0;
13863         task = pid_task(proc_pid(inode), PIDTYPE_PID);
13864 -       if (task) {
13865 +
13866 +       if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
13867 +               rcu_read_unlock();
13868 +               return -ENOENT;
13869 +       }
13870 +
13871 +
13872 +       if (task
13873 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13874 +           && (!tmp->uid || (tmp->uid == task->uid)
13875 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13876 +           || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
13877 +#endif
13878 +           )
13879 +#endif
13880 +       ) {
13881                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
13882 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13883 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
13884 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
13885 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
13886 +#endif
13887                     task_dumpable(task)) {
13888                         stat->uid = task->euid;
13889 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13890 +                       stat->gid = CONFIG_GRKERNSEC_PROC_GID;
13891 +#else
13892                         stat->gid = task->egid;
13893 +#endif
13894                 }
13895         }
13896         rcu_read_unlock();
13897 @@ -1093,11 +1127,26 @@ static int pid_revalidate(struct dentry 
13898  {
13899         struct inode *inode = dentry->d_inode;
13900         struct task_struct *task = get_proc_task(inode);
13901 +
13902 +       if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
13903 +               put_task_struct(task);
13904 +               goto out;
13905 +       }
13906 +
13907         if (task) {
13908                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
13909 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13910 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
13911 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
13912 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
13913 +#endif
13914                     task_dumpable(task)) {
13915                         inode->i_uid = task->euid;
13916 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
13917 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
13918 +#else
13919                         inode->i_gid = task->egid;
13920 +#endif
13921                 } else {
13922                         inode->i_uid = 0;
13923                         inode->i_gid = 0;
13924 @@ -1111,6 +1159,7 @@ static int pid_revalidate(struct dentry 
13925                 put_task_struct(task);
13926                 return 1;
13927         }
13928 +out:
13929         d_drop(dentry);
13930         return 0;
13931  }
13932 @@ -1336,6 +1387,9 @@ static struct dentry *proc_lookupfd(stru
13933         if (fd == ~0U)
13934                 goto out;
13935  
13936 +       if (gr_acl_handle_procpidmem(task))
13937 +               goto out;
13938 +
13939         result = proc_fd_instantiate(dir, dentry, task, &fd);
13940  out:
13941         put_task_struct(task);
13942 @@ -1380,6 +1434,8 @@ static int proc_readfd(struct file * fil
13943                                 goto out;
13944                         filp->f_pos++;
13945                 default:
13946 +                       if (gr_acl_handle_procpidmem(p))
13947 +                               goto out;
13948                         files = get_files_struct(p);
13949                         if (!files)
13950                                 goto out;
13951 @@ -1479,6 +1535,9 @@ static struct dentry *proc_pident_lookup
13952                 !memcmp(dentry->d_name.name, "ninfo", 5)))
13953                 goto out;
13954  
13955 +       if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
13956 +               goto out;
13957 +
13958         /*
13959          * Yes, it does not scale. And it should not. Don't add
13960          * new entries into /proc/<tgid>/ without very good reasons.
13961 @@ -1531,6 +1590,9 @@ static int proc_pident_readdir(struct fi
13962         if (!task)
13963                 goto out_no_task;
13964  
13965 +       if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
13966 +               goto out;
13967 +
13968         ret = 0;
13969         pid = task->pid;
13970         i = filp->f_pos;
13971 @@ -1791,6 +1853,9 @@ static struct dentry *proc_base_lookup(s
13972         if (p > last)
13973                 goto out;
13974  
13975 +       if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
13976 +               goto out;
13977 +
13978         error = proc_base_instantiate(dir, dentry, task, p);
13979  
13980  out:
13981 @@ -1881,6 +1946,9 @@ static struct pid_entry tgid_base_stuff[
13982  #ifdef CONFIG_TASK_IO_ACCOUNTING
13983         INF("io",       S_IRUGO, pid_io_accounting),
13984  #endif
13985 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
13986 +       INF("ipaddr",     S_IRUSR, pid_ipaddr),
13987 +#endif
13988  };
13989  
13990  static int proc_tgid_base_readdir(struct file * filp,
13991 @@ -1984,7 +2052,14 @@ static struct dentry *proc_pid_instantia
13992         if (!inode)
13993                 goto out;
13994  
13995 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13996 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
13997 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
13998 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
13999 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
14000 +#else
14001         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
14002 +#endif
14003         inode->i_op = &proc_tgid_base_inode_operations;
14004         inode->i_fop = &proc_tgid_base_operations;
14005         inode->i_flags|=S_IMMUTABLE;
14006 @@ -2049,7 +2124,11 @@ struct dentry *proc_pid_lookup(struct in
14007         if (!task)
14008                 goto out;
14009  
14010 +       if (gr_check_hidden_task(task))
14011 +               goto out_put_task;
14012 +
14013         result = proc_pid_instantiate(dir, dentry, task, NULL);
14014 +out_put_task:
14015         put_task_struct(task);
14016  out:
14017         return result;
14018 @@ -2083,6 +2162,9 @@ int proc_pid_readdir(struct file * filp,
14019  {
14020         unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
14021         struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
14022 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14023 +       struct task_struct *tmp = current;
14024 +#endif
14025         struct task_struct *task;
14026         int tgid;
14027  
14028 @@ -2117,6 +2199,18 @@ int proc_pid_readdir(struct file * filp,
14029              task;
14030              put_task_struct(task), task = next_tgid(tgid + 1)) {
14031                 tgid = task->pid;
14032 +
14033 +               if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task)
14034 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14035 +                   || (tmp->uid && (task->uid != tmp->uid)
14036 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
14037 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
14038 +#endif
14039 +                       )
14040 +#endif
14041 +               )
14042 +                       continue;
14043 +
14044                 filp->f_pos = tgid + TGID_OFFSET;
14045                 if (!vx_proc_task_visible(task))
14046                         continue;
14047 diff -urNp linux-2.6.20.3/fs/proc/inode.c linux-2.6.20.3/fs/proc/inode.c
14048 --- linux-2.6.20.3/fs/proc/inode.c      2007-03-13 14:27:08.000000000 -0400
14049 +++ linux-2.6.20.3/fs/proc/inode.c      2007-03-23 08:11:31.000000000 -0400
14050 @@ -166,7 +166,11 @@ struct inode *proc_get_inode(struct supe
14051                 if (de->mode) {
14052                         inode->i_mode = de->mode;
14053                         inode->i_uid = de->uid;
14054 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
14055 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
14056 +#else
14057                         inode->i_gid = de->gid;
14058 +#endif
14059                 }
14060                 if (de->vx_flags)
14061                         PROC_I(inode)->vx_flags = de->vx_flags;
14062 diff -urNp linux-2.6.20.3/fs/proc/internal.h linux-2.6.20.3/fs/proc/internal.h
14063 --- linux-2.6.20.3/fs/proc/internal.h   2007-03-13 14:27:08.000000000 -0400
14064 +++ linux-2.6.20.3/fs/proc/internal.h   2007-03-23 08:11:31.000000000 -0400
14065 @@ -37,6 +37,9 @@ extern int proc_tid_stat(struct task_str
14066  extern int proc_tgid_stat(struct task_struct *, char *);
14067  extern int proc_pid_status(struct task_struct *, char *);
14068  extern int proc_pid_statm(struct task_struct *, char *);
14069 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
14070 +extern int proc_pid_ipaddr(struct task_struct*,char*);
14071 +#endif
14072  
14073  extern struct file_operations proc_maps_operations;
14074  extern struct file_operations proc_numa_maps_operations;
14075 diff -urNp linux-2.6.20.3/fs/proc/proc_misc.c linux-2.6.20.3/fs/proc/proc_misc.c
14076 --- linux-2.6.20.3/fs/proc/proc_misc.c  2007-03-13 14:27:08.000000000 -0400
14077 +++ linux-2.6.20.3/fs/proc/proc_misc.c  2007-03-23 08:11:31.000000000 -0400
14078 @@ -673,6 +673,8 @@ void create_seq_entry(char *name, mode_t
14079  void __init proc_misc_init(void)
14080  {
14081         struct proc_dir_entry *entry;
14082 +       int gr_mode = 0;
14083 +
14084         static struct {
14085                 char *name;
14086                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
14087 @@ -688,7 +690,9 @@ void __init proc_misc_init(void)
14088                 {"stram",       stram_read_proc},
14089  #endif
14090                 {"filesystems", filesystems_read_proc},
14091 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
14092                 {"cmdline",     cmdline_read_proc},
14093 +#endif
14094                 {"locks",       locks_read_proc},
14095                 {"execdomains", execdomains_read_proc},
14096                 {NULL,}
14097 @@ -696,6 +700,15 @@ void __init proc_misc_init(void)
14098         for (p = simple_ones; p->name; p++)
14099                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
14100  
14101 +#ifdef CONFIG_GRKERNSEC_PROC_USER
14102 +       gr_mode = S_IRUSR;
14103 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14104 +       gr_mode = S_IRUSR | S_IRGRP;
14105 +#endif
14106 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14107 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
14108 +#endif
14109 +
14110         proc_symlink("mounts", NULL, "self/mounts");
14111  
14112         /* And now for trickier ones */
14113 @@ -704,7 +717,11 @@ void __init proc_misc_init(void)
14114         if (entry)
14115                 entry->proc_fops = &proc_kmsg_operations;
14116  #endif
14117 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14118 +       create_seq_entry("devices", gr_mode, &proc_devinfo_operations);
14119 +#else
14120         create_seq_entry("devices", 0, &proc_devinfo_operations);
14121 +#endif
14122         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
14123  #ifdef CONFIG_BLOCK
14124         create_seq_entry("partitions", 0, &proc_partitions_operations);
14125 @@ -712,7 +729,11 @@ void __init proc_misc_init(void)
14126         create_seq_entry("stat", 0, &proc_stat_operations);
14127         create_seq_entry("interrupts", 0, &proc_interrupts_operations);
14128  #ifdef CONFIG_SLAB
14129 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14130 +       create_seq_entry("slabinfo",S_IWUSR|gr_mode,&proc_slabinfo_operations);
14131 +#else
14132         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
14133 +#endif
14134  #ifdef CONFIG_DEBUG_SLAB_LEAK
14135         create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
14136  #endif
14137 @@ -729,7 +750,7 @@ void __init proc_misc_init(void)
14138  #ifdef CONFIG_SCHEDSTATS
14139         create_seq_entry("schedstat", 0, &proc_schedstat_operations);
14140  #endif
14141 -#ifdef CONFIG_PROC_KCORE
14142 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
14143         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
14144         if (proc_root_kcore) {
14145                 proc_root_kcore->proc_fops = &proc_kcore_operations;
14146 diff -urNp linux-2.6.20.3/fs/proc/root.c linux-2.6.20.3/fs/proc/root.c
14147 --- linux-2.6.20.3/fs/proc/root.c       2007-03-13 14:27:08.000000000 -0400
14148 +++ linux-2.6.20.3/fs/proc/root.c       2007-03-23 08:11:31.000000000 -0400
14149 @@ -65,7 +65,13 @@ void __init proc_root_init(void)
14150                 return;
14151         }
14152         proc_misc_init();
14153 +#ifdef CONFIG_GRKERNSEC_PROC_USER
14154 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR, NULL);
14155 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14156 +       proc_net = proc_mkdir_mode("net", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
14157 +#else
14158         proc_net = proc_mkdir("net", NULL);
14159 +#endif
14160         proc_net_stat = proc_mkdir("net/stat", NULL);
14161  
14162  #ifdef CONFIG_SYSVIPC
14163 @@ -89,7 +95,15 @@ void __init proc_root_init(void)
14164  #ifdef CONFIG_PROC_DEVICETREE
14165         proc_device_tree_init();
14166  #endif
14167 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
14168 +#ifdef CONFIG_GRKERNSEC_PROC_USER
14169 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
14170 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
14171 +       proc_bus = proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
14172 +#endif
14173 +#else
14174         proc_bus = proc_mkdir("bus", NULL);
14175 +#endif
14176         proc_vx_init();
14177  }
14178  
14179 diff -urNp linux-2.6.20.3/fs/proc/task_mmu.c linux-2.6.20.3/fs/proc/task_mmu.c
14180 --- linux-2.6.20.3/fs/proc/task_mmu.c   2007-03-13 14:27:08.000000000 -0400
14181 +++ linux-2.6.20.3/fs/proc/task_mmu.c   2007-03-23 08:21:11.000000000 -0400
14182 @@ -43,15 +43,27 @@ char *task_mem(struct mm_struct *mm, cha
14183                 "VmStk:\t%8lu kB\n"
14184                 "VmExe:\t%8lu kB\n"
14185                 "VmLib:\t%8lu kB\n"
14186 -               "VmPTE:\t%8lu kB\n",
14187 -               hiwater_vm << (PAGE_SHIFT-10),
14188 +               "VmPTE:\t%8lu kB\n"
14189 +
14190 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14191 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
14192 +#endif
14193 +
14194 +               ,hiwater_vm << (PAGE_SHIFT-10),
14195                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
14196                 mm->locked_vm << (PAGE_SHIFT-10),
14197                 hiwater_rss << (PAGE_SHIFT-10),
14198                 total_rss << (PAGE_SHIFT-10),
14199                 data << (PAGE_SHIFT-10),
14200                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
14201 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
14202 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
14203 +
14204 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14205 +               , mm->context.user_cs_base, mm->context.user_cs_limit
14206 +#endif
14207 +
14208 +       );
14209 +
14210         return buffer;
14211  }
14212  
14213 @@ -122,6 +134,12 @@ struct mem_size_stats
14214         unsigned long private_dirty;
14215  };
14216  
14217 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14218 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
14219 +                           (_mm->pax_flags & MF_PAX_RANDMMAP || \
14220 +                            _mm->pax_flags & MF_PAX_SEGMEXEC))
14221 +#endif
14222 +
14223  static int show_map_internal(struct seq_file *m, void *v, struct mem_size_stats *mss)
14224  {
14225         struct proc_maps_private *priv = m->private;
14226 @@ -141,13 +159,22 @@ static int show_map_internal(struct seq_
14227         }
14228  
14229         seq_printf(m, "%08lx-%08lx %c%c%c%c %08lx %02x:%02x %lu %n",
14230 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14231 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
14232 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
14233 +#else
14234                         vma->vm_start,
14235                         vma->vm_end,
14236 +#endif
14237                         flags & VM_READ ? 'r' : '-',
14238                         flags & VM_WRITE ? 'w' : '-',
14239                         flags & VM_EXEC ? 'x' : '-',
14240                         flags & VM_MAYSHARE ? 's' : 'p',
14241 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14242 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_pgoff << PAGE_SHIFT,
14243 +#else
14244                         vma->vm_pgoff << PAGE_SHIFT,
14245 +#endif
14246                         MAJOR(dev), MINOR(dev), ino, &len);
14247  
14248         /*
14249 @@ -161,11 +188,11 @@ static int show_map_internal(struct seq_
14250                 const char *name = arch_vma_name(vma);
14251                 if (!name) {
14252                         if (mm) {
14253 -                               if (vma->vm_start <= mm->start_brk &&
14254 -                                               vma->vm_end >= mm->brk) {
14255 +                               if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
14256                                         name = "[heap]";
14257 -                               } else if (vma->vm_start <= mm->start_stack &&
14258 -                                          vma->vm_end >= mm->start_stack) {
14259 +                               } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
14260 +                                          (vma->vm_start <= mm->start_stack &&
14261 +                                           vma->vm_end >= mm->start_stack)) {
14262                                         name = "[stack]";
14263                                 }
14264                         } else {
14265 @@ -179,7 +206,25 @@ static int show_map_internal(struct seq_
14266         }
14267         seq_putc(m, '\n');
14268  
14269 -       if (mss)
14270 +       
14271 +       if (mss) {
14272 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
14273 +           if (PAX_RAND_FLAGS(mm))
14274 +               seq_printf(m,
14275 +                          "Size:          %8lu kB\n"
14276 +                          "Rss:           %8lu kB\n"
14277 +                          "Shared_Clean:  %8lu kB\n"
14278 +                          "Shared_Dirty:  %8lu kB\n"
14279 +                          "Private_Clean: %8lu kB\n"
14280 +                          "Private_Dirty: %8lu kB\n",
14281 +                          0UL,
14282 +                          0UL,
14283 +                          0UL,
14284 +                          0UL,
14285 +                          0UL,
14286 +                          0UL);
14287 +           else
14288 +#endif
14289                 seq_printf(m,
14290                            "Size:          %8lu kB\n"
14291                            "Rss:           %8lu kB\n"
14292 @@ -193,6 +238,7 @@ static int show_map_internal(struct seq_
14293                            mss->shared_dirty  >> 10,
14294                            mss->private_clean >> 10,
14295                            mss->private_dirty >> 10);
14296 +       }
14297  
14298         if (m->count < m->size)  /* vma is copied successfully */
14299                 m->version = (vma != get_gate_vma(task))? vma->vm_start: 0;
14300 diff -urNp linux-2.6.20.3/fs/readdir.c linux-2.6.20.3/fs/readdir.c
14301 --- linux-2.6.20.3/fs/readdir.c 2007-03-13 14:27:08.000000000 -0400
14302 +++ linux-2.6.20.3/fs/readdir.c 2007-03-23 08:11:31.000000000 -0400
14303 @@ -16,6 +16,8 @@
14304  #include <linux/security.h>
14305  #include <linux/syscalls.h>
14306  #include <linux/unistd.h>
14307 +#include <linux/namei.h>
14308 +#include <linux/grsecurity.h>
14309  
14310  #include <asm/uaccess.h>
14311  
14312 @@ -65,6 +67,7 @@ struct old_linux_dirent {
14313  
14314  struct readdir_callback {
14315         struct old_linux_dirent __user * dirent;
14316 +       struct file * file;
14317         int result;
14318  };
14319  
14320 @@ -80,6 +83,10 @@ static int fillonedir(void * __buf, cons
14321         d_ino = ino;
14322         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
14323                 return -EOVERFLOW;
14324 +
14325 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
14326 +               return 0;
14327 +
14328         buf->result++;
14329         dirent = buf->dirent;
14330         if (!access_ok(VERIFY_WRITE, dirent,
14331 @@ -111,6 +118,7 @@ asmlinkage long old_readdir(unsigned int
14332  
14333         buf.result = 0;
14334         buf.dirent = dirent;
14335 +       buf.file = file;
14336  
14337         error = vfs_readdir(file, fillonedir, &buf);
14338         if (error >= 0)
14339 @@ -137,6 +145,7 @@ struct linux_dirent {
14340  struct getdents_callback {
14341         struct linux_dirent __user * current_dir;
14342         struct linux_dirent __user * previous;
14343 +       struct file * file;
14344         int count;
14345         int error;
14346  };
14347 @@ -155,6 +164,10 @@ static int filldir(void * __buf, const c
14348         d_ino = ino;
14349         if (sizeof(d_ino) < sizeof(ino) && d_ino != ino)
14350                 return -EOVERFLOW;
14351 +
14352 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
14353 +               return 0;
14354 +
14355         dirent = buf->previous;
14356         if (dirent) {
14357                 if (__put_user(offset, &dirent->d_off))
14358 @@ -201,6 +214,7 @@ asmlinkage long sys_getdents(unsigned in
14359         buf.previous = NULL;
14360         buf.count = count;
14361         buf.error = 0;
14362 +       buf.file = file;
14363  
14364         error = vfs_readdir(file, filldir, &buf);
14365         if (error < 0)
14366 @@ -225,6 +239,7 @@ out:
14367  struct getdents_callback64 {
14368         struct linux_dirent64 __user * current_dir;
14369         struct linux_dirent64 __user * previous;
14370 +       struct file *file;
14371         int count;
14372         int error;
14373  };
14374 @@ -239,6 +254,10 @@ static int filldir64(void * __buf, const
14375         buf->error = -EINVAL;   /* only used if we fail.. */
14376         if (reclen > buf->count)
14377                 return -EINVAL;
14378 +
14379 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
14380 +               return 0;
14381 +
14382         dirent = buf->previous;
14383         if (dirent) {
14384                 if (__put_user(offset, &dirent->d_off))
14385 @@ -285,6 +304,7 @@ asmlinkage long sys_getdents64(unsigned 
14386  
14387         buf.current_dir = dirent;
14388         buf.previous = NULL;
14389 +       buf.file = file;
14390         buf.count = count;
14391         buf.error = 0;
14392  
14393 diff -urNp linux-2.6.20.3/fs/udf/balloc.c linux-2.6.20.3/fs/udf/balloc.c
14394 --- linux-2.6.20.3/fs/udf/balloc.c      2007-03-13 14:27:08.000000000 -0400
14395 +++ linux-2.6.20.3/fs/udf/balloc.c      2007-03-23 08:10:06.000000000 -0400
14396 @@ -153,8 +153,7 @@ static void udf_bitmap_free_blocks(struc
14397         unsigned long overflow;
14398  
14399         mutex_lock(&sbi->s_alloc_mutex);
14400 -       if (bloc.logicalBlockNum < 0 ||
14401 -               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14402 +       if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14403         {
14404                 udf_debug("%d < %d || %d + %d > %d\n",
14405                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
14406 @@ -227,7 +226,7 @@ static int udf_bitmap_prealloc_blocks(st
14407         struct buffer_head *bh;
14408  
14409         mutex_lock(&sbi->s_alloc_mutex);
14410 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
14411 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
14412                 goto out;
14413  
14414         if (first_block + block_count > UDF_SB_PARTLEN(sb, partition))
14415 @@ -294,7 +293,7 @@ static int udf_bitmap_new_block(struct s
14416         mutex_lock(&sbi->s_alloc_mutex);
14417  
14418  repeat:
14419 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
14420 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
14421                 goal = 0;
14422  
14423         nr_groups = bitmap->s_nr_groups;
14424 @@ -434,8 +433,7 @@ static void udf_table_free_blocks(struct
14425         int i;
14426  
14427         mutex_lock(&sbi->s_alloc_mutex);
14428 -       if (bloc.logicalBlockNum < 0 ||
14429 -               (bloc.logicalBlockNum + count) > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14430 +       if (bloc.logicalBlockNum + count > UDF_SB_PARTLEN(sb, bloc.partitionReferenceNum))
14431         {
14432                 udf_debug("%d < %d || %d + %d > %d\n",
14433                         bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
14434 @@ -682,7 +680,7 @@ static int udf_table_prealloc_blocks(str
14435         struct buffer_head *bh;
14436         int8_t etype = -1;
14437  
14438 -       if (first_block < 0 || first_block >= UDF_SB_PARTLEN(sb, partition))
14439 +       if (first_block >= UDF_SB_PARTLEN(sb, partition))
14440                 return 0;
14441  
14442         if (UDF_I_ALLOCTYPE(table) == ICBTAG_FLAG_AD_SHORT)
14443 @@ -762,7 +760,7 @@ static int udf_table_new_block(struct su
14444                 return newblock;
14445  
14446         mutex_lock(&sbi->s_alloc_mutex);
14447 -       if (goal < 0 || goal >= UDF_SB_PARTLEN(sb, partition))
14448 +       if (goal >= UDF_SB_PARTLEN(sb, partition))
14449                 goal = 0;
14450  
14451         /* We search for the closest matching block to goal. If we find a exact hit,
14452 diff -urNp linux-2.6.20.3/fs/udf/inode.c linux-2.6.20.3/fs/udf/inode.c
14453 --- linux-2.6.20.3/fs/udf/inode.c       2007-03-13 14:27:08.000000000 -0400
14454 +++ linux-2.6.20.3/fs/udf/inode.c       2007-03-23 08:10:06.000000000 -0400
14455 @@ -300,9 +300,6 @@ static int udf_get_block(struct inode *i
14456  
14457         lock_kernel();
14458  
14459 -       if (block < 0)
14460 -               goto abort_negative;
14461 -
14462         if (block == UDF_I_NEXT_ALLOC_BLOCK(inode) + 1)
14463         {
14464                 UDF_I_NEXT_ALLOC_BLOCK(inode) ++;
14465 @@ -323,10 +320,6 @@ static int udf_get_block(struct inode *i
14466  abort:
14467         unlock_kernel();
14468         return err;
14469 -
14470 -abort_negative:
14471 -       udf_warning(inode->i_sb, "udf_get_block", "block < 0");
14472 -       goto abort;
14473  }
14474  
14475  static struct buffer_head *
14476 diff -urNp linux-2.6.20.3/fs/ufs/inode.c linux-2.6.20.3/fs/ufs/inode.c
14477 --- linux-2.6.20.3/fs/ufs/inode.c       2007-03-13 14:27:08.000000000 -0400
14478 +++ linux-2.6.20.3/fs/ufs/inode.c       2007-03-23 08:10:06.000000000 -0400
14479 @@ -55,9 +55,7 @@ static int ufs_block_to_path(struct inod
14480  
14481  
14482         UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
14483 -       if (i_block < 0) {
14484 -               ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
14485 -       } else if (i_block < direct_blocks) {
14486 +       if (i_block < direct_blocks) {
14487                 offsets[n++] = i_block;
14488         } else if ((i_block -= direct_blocks) < indirect_blocks) {
14489                 offsets[n++] = UFS_IND_BLOCK;
14490 @@ -425,8 +423,6 @@ int ufs_getfrag_block(struct inode *inod
14491         lock_kernel();
14492  
14493         UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
14494 -       if (fragment < 0)
14495 -               goto abort_negative;
14496         if (fragment >
14497             ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
14498              << uspi->s_fpbshift))
14499 @@ -489,10 +485,6 @@ abort:
14500         unlock_kernel();
14501         return err;
14502  
14503 -abort_negative:
14504 -       ufs_warning(sb, "ufs_get_block", "block < 0");
14505 -       goto abort;
14506 -
14507  abort_too_big:
14508         ufs_warning(sb, "ufs_get_block", "block > big");
14509         goto abort;
14510 diff -urNp linux-2.6.20.3/fs/utimes.c linux-2.6.20.3/fs/utimes.c
14511 --- linux-2.6.20.3/fs/utimes.c  2007-03-13 14:27:08.000000000 -0400
14512 +++ linux-2.6.20.3/fs/utimes.c  2007-03-23 08:11:31.000000000 -0400
14513 @@ -6,6 +6,7 @@
14514  #include <linux/utime.h>
14515  #include <linux/mount.h>
14516  #include <linux/vs_cowbl.h>
14517 +#include <linux/grsecurity.h>
14518  #include <asm/uaccess.h>
14519  #include <asm/unistd.h>
14520  
14521 @@ -63,6 +64,12 @@ asmlinkage long sys_utime(char __user * 
14522                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
14523                         goto dput_and_out;
14524         }
14525 +
14526 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
14527 +               error = -EACCES;
14528 +               goto dput_and_out;
14529 +       }
14530 +
14531         mutex_lock(&inode->i_mutex);
14532         error = notify_change(nd.dentry, &newattrs);
14533         mutex_unlock(&inode->i_mutex);
14534 @@ -115,6 +122,12 @@ long do_utimes(int dfd, char __user *fil
14535                     (error = vfs_permission(&nd, MAY_WRITE)) != 0)
14536                         goto dput_and_out;
14537         }
14538 +
14539 +       if (!gr_acl_handle_utime(nd.dentry, nd.mnt)) {
14540 +               error = -EACCES;
14541 +               goto dput_and_out;
14542 +       }
14543 +
14544         mutex_lock(&inode->i_mutex);
14545         error = notify_change(nd.dentry, &newattrs);
14546         mutex_unlock(&inode->i_mutex);
14547 diff -urNp linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c
14548 --- linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c  2007-03-13 14:27:08.000000000 -0400
14549 +++ linux-2.6.20.3/fs/xfs/linux-2.6/xfs_file.c  2007-03-23 08:10:06.000000000 -0400
14550 @@ -342,6 +342,12 @@ xfs_file_mmap(
14551         struct file     *filp,
14552         struct vm_area_struct *vma)
14553  {
14554 +
14555 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
14556 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
14557 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
14558 +#endif
14559 +
14560         vma->vm_ops = &xfs_file_vm_ops;
14561  
14562  #ifdef CONFIG_XFS_DMAPI
14563 diff -urNp linux-2.6.20.3/fs/xfs/xfs_bmap.c linux-2.6.20.3/fs/xfs/xfs_bmap.c
14564 --- linux-2.6.20.3/fs/xfs/xfs_bmap.c    2007-03-13 14:27:08.000000000 -0400
14565 +++ linux-2.6.20.3/fs/xfs/xfs_bmap.c    2007-03-23 08:10:06.000000000 -0400
14566 @@ -376,7 +376,7 @@ xfs_bmap_validate_ret(
14567         int                     nmap,
14568         int                     ret_nmap);
14569  #else
14570 -#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
14571 +#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
14572  #endif /* DEBUG */
14573  
14574  #if defined(XFS_RW_TRACE)
14575 diff -urNp linux-2.6.20.3/grsecurity/gracl_alloc.c linux-2.6.20.3/grsecurity/gracl_alloc.c
14576 --- linux-2.6.20.3/grsecurity/gracl_alloc.c     1969-12-31 19:00:00.000000000 -0500
14577 +++ linux-2.6.20.3/grsecurity/gracl_alloc.c     2007-03-23 08:11:31.000000000 -0400
14578 @@ -0,0 +1,91 @@
14579 +#include <linux/kernel.h>
14580 +#include <linux/mm.h>
14581 +#include <linux/slab.h>
14582 +#include <linux/vmalloc.h>
14583 +#include <linux/gracl.h>
14584 +#include <linux/grsecurity.h>
14585 +
14586 +static unsigned long alloc_stack_next = 1;
14587 +static unsigned long alloc_stack_size = 1;
14588 +static void **alloc_stack;
14589 +
14590 +static __inline__ int
14591 +alloc_pop(void)
14592 +{
14593 +       if (alloc_stack_next == 1)
14594 +               return 0;
14595 +
14596 +       kfree(alloc_stack[alloc_stack_next - 2]);
14597 +
14598 +       alloc_stack_next--;
14599 +
14600 +       return 1;
14601 +}
14602 +
14603 +static __inline__ void
14604 +alloc_push(void *buf)
14605 +{
14606 +       if (alloc_stack_next >= alloc_stack_size)
14607 +               BUG();
14608 +
14609 +       alloc_stack[alloc_stack_next - 1] = buf;
14610 +
14611 +       alloc_stack_next++;
14612 +
14613 +       return;
14614 +}
14615 +
14616 +void *
14617 +acl_alloc(unsigned long len)
14618 +{
14619 +       void *ret;
14620 +
14621 +       if (len > PAGE_SIZE)
14622 +               BUG();
14623 +
14624 +       ret = kmalloc(len, GFP_KERNEL);
14625 +
14626 +       if (ret)
14627 +               alloc_push(ret);
14628 +
14629 +       return ret;
14630 +}
14631 +
14632 +void
14633 +acl_free_all(void)
14634 +{
14635 +       if (gr_acl_is_enabled() || !alloc_stack)
14636 +               return;
14637 +
14638 +       while (alloc_pop()) ;
14639 +
14640 +       if (alloc_stack) {
14641 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
14642 +                       kfree(alloc_stack);
14643 +               else
14644 +                       vfree(alloc_stack);
14645 +       }
14646 +
14647 +       alloc_stack = NULL;
14648 +       alloc_stack_size = 1;
14649 +       alloc_stack_next = 1;
14650 +
14651 +       return;
14652 +}
14653 +
14654 +int
14655 +acl_alloc_stack_init(unsigned long size)
14656 +{
14657 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
14658 +               alloc_stack =
14659 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
14660 +       else
14661 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
14662 +
14663 +       alloc_stack_size = size;
14664 +
14665 +       if (!alloc_stack)
14666 +               return 0;
14667 +       else
14668 +               return 1;
14669 +}
14670 diff -urNp linux-2.6.20.3/grsecurity/gracl.c linux-2.6.20.3/grsecurity/gracl.c
14671 --- linux-2.6.20.3/grsecurity/gracl.c   1969-12-31 19:00:00.000000000 -0500
14672 +++ linux-2.6.20.3/grsecurity/gracl.c   2007-03-23 08:11:31.000000000 -0400
14673 @@ -0,0 +1,3550 @@
14674 +#include <linux/kernel.h>
14675 +#include <linux/module.h>
14676 +#include <linux/sched.h>
14677 +#include <linux/mm.h>
14678 +#include <linux/file.h>
14679 +#include <linux/fs.h>
14680 +#include <linux/namei.h>
14681 +#include <linux/mount.h>
14682 +#include <linux/tty.h>
14683 +#include <linux/proc_fs.h>
14684 +#include <linux/smp_lock.h>
14685 +#include <linux/slab.h>
14686 +#include <linux/vmalloc.h>
14687 +#include <linux/types.h>
14688 +#include <linux/capability.h>
14689 +#include <linux/sysctl.h>
14690 +#include <linux/netdevice.h>
14691 +#include <linux/ptrace.h>
14692 +#include <linux/gracl.h>
14693 +#include <linux/gralloc.h>
14694 +#include <linux/grsecurity.h>
14695 +#include <linux/grinternal.h>
14696 +#include <linux/pid_namespace.h>
14697 +#include <linux/percpu.h>
14698 +
14699 +#include <asm/uaccess.h>
14700 +#include <asm/errno.h>
14701 +#include <asm/mman.h>
14702 +
14703 +static struct acl_role_db acl_role_set;
14704 +static struct name_db name_set;
14705 +static struct inodev_db inodev_set;
14706 +
14707 +/* for keeping track of userspace pointers used for subjects, so we
14708 +   can share references in the kernel as well
14709 +*/
14710 +
14711 +static struct dentry *real_root;
14712 +static struct vfsmount *real_root_mnt;
14713 +
14714 +static struct acl_subj_map_db subj_map_set;
14715 +
14716 +static struct acl_role_label *default_role;
14717 +
14718 +static u16 acl_sp_role_value;
14719 +
14720 +extern char *gr_shared_page[4];
14721 +static DECLARE_MUTEX(gr_dev_sem);
14722 +rwlock_t gr_inode_lock = RW_LOCK_UNLOCKED;
14723 +
14724 +struct gr_arg *gr_usermode;
14725 +
14726 +static unsigned int gr_status = GR_STATUS_INIT;
14727 +
14728 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
14729 +extern void gr_clear_learn_entries(void);
14730 +
14731 +#ifdef CONFIG_GRKERNSEC_RESLOG
14732 +extern void gr_log_resource(const struct task_struct *task,
14733 +                           const int res, const unsigned long wanted, const int gt);
14734 +#endif
14735 +
14736 +extern char * __d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
14737 +                        struct dentry *root, struct vfsmount *rootmnt,
14738 +                        char *buffer, int buflen);
14739 +
14740 +unsigned char *gr_system_salt;
14741 +unsigned char *gr_system_sum;
14742 +
14743 +static struct sprole_pw **acl_special_roles = NULL;
14744 +static __u16 num_sprole_pws = 0;
14745 +
14746 +static struct acl_role_label *kernel_role = NULL;
14747 +
14748 +static unsigned int gr_auth_attempts = 0;
14749 +static unsigned long gr_auth_expires = 0UL;
14750 +
14751 +extern struct vfsmount *sock_mnt;
14752 +extern struct vfsmount *pipe_mnt;
14753 +extern struct vfsmount *shm_mnt;
14754 +static struct acl_object_label *fakefs_obj;
14755 +
14756 +extern int gr_init_uidset(void);
14757 +extern void gr_free_uidset(void);
14758 +extern void gr_remove_uid(uid_t uid);
14759 +extern int gr_find_uid(uid_t uid);
14760 +
14761 +__inline__ int
14762 +gr_acl_is_enabled(void)
14763 +{
14764 +       return (gr_status & GR_READY);
14765 +}
14766 +
14767 +char gr_roletype_to_char(void)
14768 +{
14769 +       switch (current->role->roletype &
14770 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
14771 +                GR_ROLE_SPECIAL)) {
14772 +       case GR_ROLE_DEFAULT:
14773 +               return 'D';
14774 +       case GR_ROLE_USER:
14775 +               return 'U';
14776 +       case GR_ROLE_GROUP:
14777 +               return 'G';
14778 +       case GR_ROLE_SPECIAL:
14779 +               return 'S';
14780 +       }
14781 +
14782 +       return 'X';
14783 +}
14784 +
14785 +__inline__ int
14786 +gr_acl_tpe_check(void)
14787 +{
14788 +       if (unlikely(!(gr_status & GR_READY)))
14789 +               return 0;
14790 +       if (current->role->roletype & GR_ROLE_TPE)
14791 +               return 1;
14792 +       else
14793 +               return 0;
14794 +}
14795 +
14796 +int
14797 +gr_handle_rawio(const struct inode *inode)
14798 +{
14799 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
14800 +       if (inode && S_ISBLK(inode->i_mode) &&
14801 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
14802 +           !capable(CAP_SYS_RAWIO))
14803 +               return 1;
14804 +#endif
14805 +       return 0;
14806 +}
14807 +
14808 +static int
14809 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
14810 +{
14811 +       int i;
14812 +       unsigned long *l1;
14813 +       unsigned long *l2;
14814 +       unsigned char *c1;
14815 +       unsigned char *c2;
14816 +       int num_longs;
14817 +
14818 +       if (likely(lena != lenb))
14819 +               return 0;
14820 +
14821 +       l1 = (unsigned long *)a;
14822 +       l2 = (unsigned long *)b;
14823 +
14824 +       num_longs = lena / sizeof(unsigned long);
14825 +
14826 +       for (i = num_longs; i--; l1++, l2++) {
14827 +               if (unlikely(*l1 != *l2))
14828 +                       return 0;
14829 +       }
14830 +
14831 +       c1 = (unsigned char *) l1;
14832 +       c2 = (unsigned char *) l2;
14833 +
14834 +       i = lena - (num_longs * sizeof(unsigned long)); 
14835 +
14836 +       for (; i--; c1++, c2++) {
14837 +               if (unlikely(*c1 != *c2))
14838 +                       return 0;
14839 +       }
14840 +
14841 +       return 1;
14842 +}
14843 +               
14844 +static char *
14845 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
14846 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
14847 +{
14848 +       char *end = buf + buflen;
14849 +       char *retval;
14850 +       int namelen = 0;
14851 +
14852 +       *--end = '\0';
14853 +
14854 +       retval = end - 1;
14855 +       *retval = '/';
14856 +
14857 +       if (dentry == root && vfsmnt == rootmnt)
14858 +               return retval;
14859 +       if (dentry != vfsmnt->mnt_root && !IS_ROOT(dentry)) {
14860 +               namelen = strlen(dentry->d_name.name);
14861 +               buflen -= namelen;
14862 +               if (buflen < 2)
14863 +                       goto err;
14864 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
14865 +                       buflen--;
14866 +       }
14867 +
14868 +       retval = __d_path(dentry->d_parent, vfsmnt, root, rootmnt, buf, buflen);
14869 +       if (unlikely(IS_ERR(retval)))
14870 +err:
14871 +               retval = strcpy(buf, "<path too long>");
14872 +       else if (namelen != 0) {
14873 +               end = buf + buflen - 1; // accounts for null termination
14874 +               if (dentry->d_parent != root || vfsmnt != rootmnt)
14875 +                       *end++ = '/'; // accounted for above with buflen--
14876 +               memcpy(end, dentry->d_name.name, namelen);
14877 +       }
14878 +
14879 +       return retval;
14880 +}
14881 +
14882 +static char *
14883 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
14884 +               char *buf, int buflen)
14885 +{
14886 +       char *res;
14887 +
14888 +       /* we can use real_root, real_root_mnt, because this is only called
14889 +          by the RBAC system */
14890 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
14891 +
14892 +       return res;
14893 +}
14894 +
14895 +static char *
14896 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
14897 +           char *buf, int buflen)
14898 +{
14899 +       char *res;
14900 +       struct dentry *root;
14901 +       struct vfsmount *rootmnt;
14902 +       struct task_struct *reaper = child_reaper(current);
14903 +
14904 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
14905 +       read_lock(&reaper->fs->lock);
14906 +       root = dget(reaper->fs->root);
14907 +       rootmnt = mntget(reaper->fs->rootmnt);
14908 +       read_unlock(&reaper->fs->lock);
14909 +
14910 +       spin_lock(&dcache_lock);
14911 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
14912 +       spin_unlock(&dcache_lock);
14913 +
14914 +       dput(root);
14915 +       mntput(rootmnt);
14916 +       return res;
14917 +}
14918 +
14919 +static char *
14920 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
14921 +{
14922 +       char *ret;
14923 +       spin_lock(&dcache_lock);
14924 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
14925 +                            PAGE_SIZE);
14926 +       spin_unlock(&dcache_lock);
14927 +       return ret;
14928 +}
14929 +
14930 +char *
14931 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
14932 +{
14933 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
14934 +                            PAGE_SIZE);
14935 +}
14936 +
14937 +char *
14938 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
14939 +{
14940 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
14941 +                          PAGE_SIZE);
14942 +}
14943 +
14944 +char *
14945 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
14946 +{
14947 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
14948 +                          PAGE_SIZE);
14949 +}
14950 +
14951 +char *
14952 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
14953 +{
14954 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
14955 +                          PAGE_SIZE);
14956 +}
14957 +
14958 +char *
14959 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
14960 +{
14961 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
14962 +                          PAGE_SIZE);
14963 +}
14964 +
14965 +__inline__ __u32
14966 +to_gr_audit(const __u32 reqmode)
14967 +{
14968 +       /* masks off auditable permission flags, then shifts them to create
14969 +          auditing flags, and adds the special case of append auditing if
14970 +          we're requesting write */
14971 +       return (((reqmode & GR_AUDIT_READ) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
14972 +}
14973 +
14974 +struct acl_subject_label *
14975 +lookup_subject_map(const struct acl_subject_label *userp)
14976 +{
14977 +       unsigned int index = shash(userp, subj_map_set.s_size);
14978 +       struct subject_map *match;
14979 +
14980 +       match = subj_map_set.s_hash[index];
14981 +
14982 +       while (match && match->user != userp)
14983 +               match = match->next;
14984 +
14985 +       if (match != NULL)
14986 +               return match->kernel;
14987 +       else
14988 +               return NULL;
14989 +}
14990 +
14991 +static void
14992 +insert_subj_map_entry(struct subject_map *subjmap)
14993 +{
14994 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
14995 +       struct subject_map **curr;
14996 +
14997 +       subjmap->prev = NULL;
14998 +
14999 +       curr = &subj_map_set.s_hash[index];
15000 +       if (*curr != NULL)
15001 +               (*curr)->prev = subjmap;
15002 +
15003 +       subjmap->next = *curr;
15004 +       *curr = subjmap;
15005 +
15006 +       return;
15007 +}
15008 +
15009 +static struct acl_role_label *
15010 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
15011 +                     const gid_t gid)
15012 +{
15013 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
15014 +       struct acl_role_label *match;
15015 +       struct role_allowed_ip *ipp;
15016 +       unsigned int x;
15017 +
15018 +       match = acl_role_set.r_hash[index];
15019 +
15020 +       while (match) {
15021 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
15022 +                       for (x = 0; x < match->domain_child_num; x++) {
15023 +                               if (match->domain_children[x] == uid)
15024 +                                       goto found;
15025 +                       }
15026 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
15027 +                       break;
15028 +               match = match->next;
15029 +       }
15030 +found:
15031 +       if (match == NULL) {
15032 +             try_group:
15033 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
15034 +               match = acl_role_set.r_hash[index];
15035 +
15036 +               while (match) {
15037 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
15038 +                               for (x = 0; x < match->domain_child_num; x++) {
15039 +                                       if (match->domain_children[x] == gid)
15040 +                                               goto found2;
15041 +                               }
15042 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
15043 +                               break;
15044 +                       match = match->next;
15045 +               }
15046 +found2:
15047 +               if (match == NULL)
15048 +                       match = default_role;
15049 +               if (match->allowed_ips == NULL)
15050 +                       return match;
15051 +               else {
15052 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
15053 +                               if (likely
15054 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
15055 +                                    (ntohl(ipp->addr) & ipp->netmask)))
15056 +                                       return match;
15057 +                       }
15058 +                       match = default_role;
15059 +               }
15060 +       } else if (match->allowed_ips == NULL) {
15061 +               return match;
15062 +       } else {
15063 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
15064 +                       if (likely
15065 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
15066 +                            (ntohl(ipp->addr) & ipp->netmask)))
15067 +                               return match;
15068 +               }
15069 +               goto try_group;
15070 +       }
15071 +
15072 +       return match;
15073 +}
15074 +
15075 +struct acl_subject_label *
15076 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
15077 +                     const struct acl_role_label *role)
15078 +{
15079 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
15080 +       struct acl_subject_label *match;
15081 +
15082 +       match = role->subj_hash[index];
15083 +
15084 +       while (match && (match->inode != ino || match->device != dev ||
15085 +              (match->mode & GR_DELETED))) {
15086 +               match = match->next;
15087 +       }
15088 +
15089 +       if (match && !(match->mode & GR_DELETED))
15090 +               return match;
15091 +       else
15092 +               return NULL;
15093 +}
15094 +
15095 +static struct acl_object_label *
15096 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
15097 +                    const struct acl_subject_label *subj)
15098 +{
15099 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
15100 +       struct acl_object_label *match;
15101 +
15102 +       match = subj->obj_hash[index];
15103 +
15104 +       while (match && (match->inode != ino || match->device != dev ||
15105 +              (match->mode & GR_DELETED))) {
15106 +               match = match->next;
15107 +       }
15108 +
15109 +       if (match && !(match->mode & GR_DELETED))
15110 +               return match;
15111 +       else
15112 +               return NULL;
15113 +}
15114 +
15115 +static struct acl_object_label *
15116 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
15117 +                    const struct acl_subject_label *subj)
15118 +{
15119 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
15120 +       struct acl_object_label *match;
15121 +
15122 +       match = subj->obj_hash[index];
15123 +
15124 +       while (match && (match->inode != ino || match->device != dev ||
15125 +              !(match->mode & GR_DELETED))) {
15126 +               match = match->next;
15127 +       }
15128 +
15129 +       if (match && (match->mode & GR_DELETED))
15130 +               return match;
15131 +
15132 +       match = subj->obj_hash[index];
15133 +
15134 +       while (match && (match->inode != ino || match->device != dev ||
15135 +              (match->mode & GR_DELETED))) {
15136 +               match = match->next;
15137 +       }
15138 +
15139 +       if (match && !(match->mode & GR_DELETED))
15140 +               return match;
15141 +       else
15142 +               return NULL;
15143 +}
15144 +
15145 +static struct name_entry *
15146 +lookup_name_entry(const char *name)
15147 +{
15148 +       unsigned int len = strlen(name);
15149 +       unsigned int key = full_name_hash(name, len);
15150 +       unsigned int index = key % name_set.n_size;
15151 +       struct name_entry *match;
15152 +
15153 +       match = name_set.n_hash[index];
15154 +
15155 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
15156 +               match = match->next;
15157 +
15158 +       return match;
15159 +}
15160 +
15161 +static struct inodev_entry *
15162 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
15163 +{
15164 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
15165 +       struct inodev_entry *match;
15166 +
15167 +       match = inodev_set.i_hash[index];
15168 +
15169 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
15170 +               match = match->next;
15171 +
15172 +       return match;
15173 +}
15174 +
15175 +static void
15176 +insert_inodev_entry(struct inodev_entry *entry)
15177 +{
15178 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
15179 +                                   inodev_set.i_size);
15180 +       struct inodev_entry **curr;
15181 +
15182 +       entry->prev = NULL;
15183 +
15184 +       curr = &inodev_set.i_hash[index];
15185 +       if (*curr != NULL)
15186 +               (*curr)->prev = entry;
15187 +       
15188 +       entry->next = *curr;
15189 +       *curr = entry;
15190 +
15191 +       return;
15192 +}
15193 +
15194 +static void
15195 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
15196 +{
15197 +       unsigned int index =
15198 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
15199 +       struct acl_role_label **curr;
15200 +
15201 +       role->prev = NULL;
15202 +
15203 +       curr = &acl_role_set.r_hash[index];
15204 +       if (*curr != NULL)
15205 +               (*curr)->prev = role;
15206 +
15207 +       role->next = *curr;
15208 +       *curr = role;
15209 +
15210 +       return;
15211 +}
15212 +
15213 +static void
15214 +insert_acl_role_label(struct acl_role_label *role)
15215 +{
15216 +       int i;
15217 +
15218 +       if (role->roletype & GR_ROLE_DOMAIN) {
15219 +               for (i = 0; i < role->domain_child_num; i++)
15220 +                       __insert_acl_role_label(role, role->domain_children[i]);
15221 +       } else
15222 +               __insert_acl_role_label(role, role->uidgid);
15223 +}
15224 +                                       
15225 +static int
15226 +insert_name_entry(char *name, const ino_t inode, const dev_t device)
15227 +{
15228 +       struct name_entry **curr, *nentry;
15229 +       struct inodev_entry *ientry;
15230 +       unsigned int len = strlen(name);
15231 +       unsigned int key = full_name_hash(name, len);
15232 +       unsigned int index = key % name_set.n_size;
15233 +
15234 +       curr = &name_set.n_hash[index];
15235 +
15236 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
15237 +               curr = &((*curr)->next);
15238 +
15239 +       if (*curr != NULL)
15240 +               return 1;
15241 +
15242 +       nentry = acl_alloc(sizeof (struct name_entry));
15243 +       if (nentry == NULL)
15244 +               return 0;
15245 +       ientry = acl_alloc(sizeof (struct inodev_entry));
15246 +       if (ientry == NULL)
15247 +               return 0;
15248 +       ientry->nentry = nentry;
15249 +
15250 +       nentry->key = key;
15251 +       nentry->name = name;
15252 +       nentry->inode = inode;
15253 +       nentry->device = device;
15254 +       nentry->len = len;
15255 +
15256 +       nentry->prev = NULL;
15257 +       curr = &name_set.n_hash[index];
15258 +       if (*curr != NULL)
15259 +               (*curr)->prev = nentry;
15260 +       nentry->next = *curr;
15261 +       *curr = nentry;
15262 +
15263 +       /* insert us into the table searchable by inode/dev */
15264 +       insert_inodev_entry(ientry);
15265 +
15266 +       return 1;
15267 +}
15268 +
15269 +static void
15270 +insert_acl_obj_label(struct acl_object_label *obj,
15271 +                    struct acl_subject_label *subj)
15272 +{
15273 +       unsigned int index =
15274 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
15275 +       struct acl_object_label **curr;
15276 +
15277 +       
15278 +       obj->prev = NULL;
15279 +
15280 +       curr = &subj->obj_hash[index];
15281 +       if (*curr != NULL)
15282 +               (*curr)->prev = obj;
15283 +
15284 +       obj->next = *curr;
15285 +       *curr = obj;
15286 +
15287 +       return;
15288 +}
15289 +
15290 +static void
15291 +insert_acl_subj_label(struct acl_subject_label *obj,
15292 +                     struct acl_role_label *role)
15293 +{
15294 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
15295 +       struct acl_subject_label **curr;
15296 +
15297 +       obj->prev = NULL;
15298 +
15299 +       curr = &role->subj_hash[index];
15300 +       if (*curr != NULL)
15301 +               (*curr)->prev = obj;
15302 +
15303 +       obj->next = *curr;
15304 +       *curr = obj;
15305 +
15306 +       return;
15307 +}
15308 +
15309 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
15310 +
15311 +static void *
15312 +create_table(__u32 * len, int elementsize)
15313 +{
15314 +       unsigned int table_sizes[] = {
15315 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
15316 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
15317 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
15318 +               268435399, 536870909, 1073741789, 2147483647
15319 +       };
15320 +       void *newtable = NULL;
15321 +       unsigned int pwr = 0;
15322 +
15323 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
15324 +              table_sizes[pwr] <= *len)
15325 +               pwr++;
15326 +
15327 +       if (table_sizes[pwr] <= *len)
15328 +               return newtable;
15329 +
15330 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
15331 +               newtable =
15332 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
15333 +       else
15334 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
15335 +
15336 +       *len = table_sizes[pwr];
15337 +
15338 +       return newtable;
15339 +}
15340 +
15341 +static int
15342 +init_variables(const struct gr_arg *arg)
15343 +{
15344 +       struct task_struct *reaper = child_reaper(current);
15345 +       unsigned int stacksize;
15346 +
15347 +       subj_map_set.s_size = arg->role_db.num_subjects;
15348 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
15349 +       name_set.n_size = arg->role_db.num_objects;
15350 +       inodev_set.i_size = arg->role_db.num_objects;
15351 +
15352 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
15353 +           !name_set.n_size || !inodev_set.i_size)
15354 +               return 1;
15355 +
15356 +       if (!gr_init_uidset())
15357 +               return 1;
15358 +
15359 +       /* set up the stack that holds allocation info */
15360 +
15361 +       stacksize = arg->role_db.num_pointers + 5;
15362 +
15363 +       if (!acl_alloc_stack_init(stacksize))
15364 +               return 1;
15365 +
15366 +       /* grab reference for the real root dentry and vfsmount */
15367 +       read_lock(&reaper->fs->lock);
15368 +       real_root_mnt = mntget(reaper->fs->rootmnt);
15369 +       real_root = dget(reaper->fs->root);
15370 +       read_unlock(&reaper->fs->lock);
15371 +       
15372 +       fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
15373 +       if (fakefs_obj == NULL)
15374 +               return 1;
15375 +       fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
15376 +
15377 +       subj_map_set.s_hash =
15378 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
15379 +       acl_role_set.r_hash =
15380 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
15381 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
15382 +       inodev_set.i_hash =
15383 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
15384 +
15385 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
15386 +           !name_set.n_hash || !inodev_set.i_hash)
15387 +               return 1;
15388 +
15389 +       memset(subj_map_set.s_hash, 0,
15390 +              sizeof(struct subject_map *) * subj_map_set.s_size);
15391 +       memset(acl_role_set.r_hash, 0,
15392 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
15393 +       memset(name_set.n_hash, 0,
15394 +              sizeof (struct name_entry *) * name_set.n_size);
15395 +       memset(inodev_set.i_hash, 0,
15396 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
15397 +
15398 +       return 0;
15399 +}
15400 +
15401 +/* free information not needed after startup
15402 +   currently contains user->kernel pointer mappings for subjects
15403 +*/
15404 +
15405 +static void
15406 +free_init_variables(void)
15407 +{
15408 +       __u32 i;
15409 +
15410 +       if (subj_map_set.s_hash) {
15411 +               for (i = 0; i < subj_map_set.s_size; i++) {
15412 +                       if (subj_map_set.s_hash[i]) {
15413 +                               kfree(subj_map_set.s_hash[i]);
15414 +                               subj_map_set.s_hash[i] = NULL;
15415 +                       }
15416 +               }
15417 +
15418 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
15419 +                   PAGE_SIZE)
15420 +                       kfree(subj_map_set.s_hash);
15421 +               else
15422 +                       vfree(subj_map_set.s_hash);
15423 +       }
15424 +
15425 +       return;
15426 +}
15427 +
15428 +static void
15429 +free_variables(void)
15430 +{
15431 +       struct acl_subject_label *s;
15432 +       struct acl_role_label *r;
15433 +       struct task_struct *task, *task2;
15434 +       unsigned int i, x;
15435 +
15436 +       gr_clear_learn_entries();
15437 +
15438 +       read_lock(&tasklist_lock);
15439 +       do_each_thread(task2, task) {
15440 +               task->acl_sp_role = 0;
15441 +               task->acl_role_id = 0;
15442 +               task->acl = NULL;
15443 +               task->role = NULL;
15444 +       } while_each_thread(task2, task);
15445 +       read_unlock(&tasklist_lock);
15446 +
15447 +       /* release the reference to the real root dentry and vfsmount */
15448 +       if (real_root)
15449 +               dput(real_root);
15450 +       real_root = NULL;
15451 +       if (real_root_mnt)
15452 +               mntput(real_root_mnt);
15453 +       real_root_mnt = NULL;
15454 +
15455 +       /* free all object hash tables */
15456 +
15457 +       FOR_EACH_ROLE_START(r, i)
15458 +               if (r->subj_hash == NULL)
15459 +                       break;
15460 +               FOR_EACH_SUBJECT_START(r, s, x)
15461 +                       if (s->obj_hash == NULL)
15462 +                               break;
15463 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
15464 +                               kfree(s->obj_hash);
15465 +                       else
15466 +                               vfree(s->obj_hash);
15467 +               FOR_EACH_SUBJECT_END(s, x)
15468 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
15469 +                       if (s->obj_hash == NULL)
15470 +                               break;
15471 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
15472 +                               kfree(s->obj_hash);
15473 +                       else
15474 +                               vfree(s->obj_hash);
15475 +               FOR_EACH_NESTED_SUBJECT_END(s)
15476 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
15477 +                       kfree(r->subj_hash);
15478 +               else
15479 +                       vfree(r->subj_hash);
15480 +               r->subj_hash = NULL;
15481 +       FOR_EACH_ROLE_END(r,i)
15482 +
15483 +       acl_free_all();
15484 +
15485 +       if (acl_role_set.r_hash) {
15486 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
15487 +                   PAGE_SIZE)
15488 +                       kfree(acl_role_set.r_hash);
15489 +               else
15490 +                       vfree(acl_role_set.r_hash);
15491 +       }
15492 +       if (name_set.n_hash) {
15493 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
15494 +                   PAGE_SIZE)
15495 +                       kfree(name_set.n_hash);
15496 +               else
15497 +                       vfree(name_set.n_hash);
15498 +       }
15499 +
15500 +       if (inodev_set.i_hash) {
15501 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
15502 +                   PAGE_SIZE)
15503 +                       kfree(inodev_set.i_hash);
15504 +               else
15505 +                       vfree(inodev_set.i_hash);
15506 +       }
15507 +
15508 +       gr_free_uidset();
15509 +
15510 +       memset(&name_set, 0, sizeof (struct name_db));
15511 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
15512 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
15513 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
15514 +
15515 +       default_role = NULL;
15516 +
15517 +       return;
15518 +}
15519 +
15520 +static __u32
15521 +count_user_objs(struct acl_object_label *userp)
15522 +{
15523 +       struct acl_object_label o_tmp;
15524 +       __u32 num = 0;
15525 +
15526 +       while (userp) {
15527 +               if (copy_from_user(&o_tmp, userp,
15528 +                                  sizeof (struct acl_object_label)))
15529 +                       break;
15530 +
15531 +               userp = o_tmp.prev;
15532 +               num++;
15533 +       }
15534 +
15535 +       return num;
15536 +}
15537 +
15538 +static struct acl_subject_label *
15539 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
15540 +
15541 +static int
15542 +copy_user_glob(struct acl_object_label *obj)
15543 +{
15544 +       struct acl_object_label *g_tmp, **guser;
15545 +       unsigned int len;
15546 +       char *tmp;
15547 +
15548 +       if (obj->globbed == NULL)
15549 +               return 0;
15550 +
15551 +       guser = &obj->globbed;
15552 +       while (*guser) {
15553 +               g_tmp = (struct acl_object_label *)
15554 +                       acl_alloc(sizeof (struct acl_object_label));
15555 +               if (g_tmp == NULL)
15556 +                       return -ENOMEM;
15557 +
15558 +               if (copy_from_user(g_tmp, *guser,
15559 +                                  sizeof (struct acl_object_label)))
15560 +                       return -EFAULT;
15561 +
15562 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
15563 +
15564 +               if (!len || len >= PATH_MAX)
15565 +                       return -EINVAL;
15566 +
15567 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
15568 +                       return -ENOMEM;
15569 +
15570 +               if (copy_from_user(tmp, g_tmp->filename, len))
15571 +                       return -EFAULT;
15572 +
15573 +               g_tmp->filename = tmp;
15574 +
15575 +               *guser = g_tmp;
15576 +               guser = &(g_tmp->next);
15577 +       }
15578 +
15579 +       return 0;
15580 +}
15581 +
15582 +static int
15583 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
15584 +              struct acl_role_label *role)
15585 +{
15586 +       struct acl_object_label *o_tmp;
15587 +       unsigned int len;
15588 +       int ret;
15589 +       char *tmp;
15590 +
15591 +       while (userp) {
15592 +               if ((o_tmp = (struct acl_object_label *)
15593 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
15594 +                       return -ENOMEM;
15595 +
15596 +               if (copy_from_user(o_tmp, userp,
15597 +                                  sizeof (struct acl_object_label)))
15598 +                       return -EFAULT;
15599 +
15600 +               userp = o_tmp->prev;
15601 +
15602 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
15603 +
15604 +               if (!len || len >= PATH_MAX)
15605 +                       return -EINVAL;
15606 +
15607 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
15608 +                       return -ENOMEM;
15609 +
15610 +               if (copy_from_user(tmp, o_tmp->filename, len))
15611 +                       return -EFAULT;
15612 +
15613 +               o_tmp->filename = tmp;
15614 +
15615 +               insert_acl_obj_label(o_tmp, subj);
15616 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
15617 +                                      o_tmp->device))
15618 +                       return -ENOMEM;
15619 +
15620 +               ret = copy_user_glob(o_tmp);
15621 +               if (ret)
15622 +                       return ret;
15623 +
15624 +               if (o_tmp->nested) {
15625 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
15626 +                       if (IS_ERR(o_tmp->nested))
15627 +                               return PTR_ERR(o_tmp->nested);
15628 +
15629 +                       /* insert into nested subject list */
15630 +                       o_tmp->nested->next = role->hash->first;
15631 +                       role->hash->first = o_tmp->nested;
15632 +               }
15633 +       }
15634 +
15635 +       return 0;
15636 +}
15637 +
15638 +static __u32
15639 +count_user_subjs(struct acl_subject_label *userp)
15640 +{
15641 +       struct acl_subject_label s_tmp;
15642 +       __u32 num = 0;
15643 +
15644 +       while (userp) {
15645 +               if (copy_from_user(&s_tmp, userp,
15646 +                                  sizeof (struct acl_subject_label)))
15647 +                       break;
15648 +
15649 +               userp = s_tmp.prev;
15650 +               /* do not count nested subjects against this count, since
15651 +                  they are not included in the hash table, but are
15652 +                  attached to objects.  We have already counted
15653 +                  the subjects in userspace for the allocation 
15654 +                  stack
15655 +               */
15656 +               if (!(s_tmp.mode & GR_NESTED))
15657 +                       num++;
15658 +       }
15659 +
15660 +       return num;
15661 +}
15662 +
15663 +static int
15664 +copy_user_allowedips(struct acl_role_label *rolep)
15665 +{
15666 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
15667 +
15668 +       ruserip = rolep->allowed_ips;
15669 +
15670 +       while (ruserip) {
15671 +               rlast = rtmp;
15672 +
15673 +               if ((rtmp = (struct role_allowed_ip *)
15674 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
15675 +                       return -ENOMEM;
15676 +
15677 +               if (copy_from_user(rtmp, ruserip,
15678 +                                  sizeof (struct role_allowed_ip)))
15679 +                       return -EFAULT;
15680 +
15681 +               ruserip = rtmp->prev;
15682 +
15683 +               if (!rlast) {
15684 +                       rtmp->prev = NULL;
15685 +                       rolep->allowed_ips = rtmp;
15686 +               } else {
15687 +                       rlast->next = rtmp;
15688 +                       rtmp->prev = rlast;
15689 +               }
15690 +
15691 +               if (!ruserip)
15692 +                       rtmp->next = NULL;
15693 +       }
15694 +
15695 +       return 0;
15696 +}
15697 +
15698 +static int
15699 +copy_user_transitions(struct acl_role_label *rolep)
15700 +{
15701 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
15702 +       
15703 +       unsigned int len;
15704 +       char *tmp;
15705 +
15706 +       rusertp = rolep->transitions;
15707 +
15708 +       while (rusertp) {
15709 +               rlast = rtmp;
15710 +
15711 +               if ((rtmp = (struct role_transition *)
15712 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
15713 +                       return -ENOMEM;
15714 +
15715 +               if (copy_from_user(rtmp, rusertp,
15716 +                                  sizeof (struct role_transition)))
15717 +                       return -EFAULT;
15718 +
15719 +               rusertp = rtmp->prev;
15720 +
15721 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
15722 +
15723 +               if (!len || len >= GR_SPROLE_LEN)
15724 +                       return -EINVAL;
15725 +
15726 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
15727 +                       return -ENOMEM;
15728 +
15729 +               if (copy_from_user(tmp, rtmp->rolename, len))
15730 +                       return -EFAULT;
15731 +
15732 +               rtmp->rolename = tmp;
15733 +
15734 +               if (!rlast) {
15735 +                       rtmp->prev = NULL;
15736 +                       rolep->transitions = rtmp;
15737 +               } else {
15738 +                       rlast->next = rtmp;
15739 +                       rtmp->prev = rlast;
15740 +               }
15741 +
15742 +               if (!rusertp)
15743 +                       rtmp->next = NULL;
15744 +       }
15745 +
15746 +       return 0;
15747 +}
15748 +
15749 +static struct acl_subject_label *
15750 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
15751 +{
15752 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
15753 +       unsigned int len;
15754 +       char *tmp;
15755 +       __u32 num_objs;
15756 +       struct acl_ip_label **i_tmp, *i_utmp2;
15757 +       struct gr_hash_struct ghash;
15758 +       struct subject_map *subjmap;
15759 +       unsigned int i_num;
15760 +       int err;
15761 +
15762 +       s_tmp = lookup_subject_map(userp);
15763 +
15764 +       /* we've already copied this subject into the kernel, just return
15765 +          the reference to it, and don't copy it over again
15766 +       */
15767 +       if (s_tmp)
15768 +               return(s_tmp);
15769 +
15770 +       if ((s_tmp = (struct acl_subject_label *)
15771 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
15772 +               return ERR_PTR(-ENOMEM);
15773 +
15774 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
15775 +       if (subjmap == NULL)
15776 +               return ERR_PTR(-ENOMEM);
15777 +
15778 +       subjmap->user = userp;
15779 +       subjmap->kernel = s_tmp;
15780 +       insert_subj_map_entry(subjmap);
15781 +
15782 +       if (copy_from_user(s_tmp, userp,
15783 +                          sizeof (struct acl_subject_label)))
15784 +               return ERR_PTR(-EFAULT);
15785 +
15786 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
15787 +
15788 +       if (!len || len >= PATH_MAX)
15789 +               return ERR_PTR(-EINVAL);
15790 +
15791 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
15792 +               return ERR_PTR(-ENOMEM);
15793 +
15794 +       if (copy_from_user(tmp, s_tmp->filename, len))
15795 +               return ERR_PTR(-EFAULT);
15796 +
15797 +       s_tmp->filename = tmp;
15798 +
15799 +       if (!strcmp(s_tmp->filename, "/"))
15800 +               role->root_label = s_tmp;
15801 +
15802 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
15803 +               return ERR_PTR(-EFAULT);
15804 +
15805 +       /* copy user and group transition tables */
15806 +
15807 +       if (s_tmp->user_trans_num) {
15808 +               uid_t *uidlist;
15809 +
15810 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
15811 +               if (uidlist == NULL)
15812 +                       return ERR_PTR(-ENOMEM);
15813 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
15814 +                       return ERR_PTR(-EFAULT);
15815 +
15816 +               s_tmp->user_transitions = uidlist;
15817 +       }
15818 +
15819 +       if (s_tmp->group_trans_num) {
15820 +               gid_t *gidlist;
15821 +
15822 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
15823 +               if (gidlist == NULL)
15824 +                       return ERR_PTR(-ENOMEM);
15825 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
15826 +                       return ERR_PTR(-EFAULT);
15827 +
15828 +               s_tmp->group_transitions = gidlist;
15829 +       }
15830 +
15831 +       /* set up object hash table */
15832 +       num_objs = count_user_objs(ghash.first);
15833 +
15834 +       s_tmp->obj_hash_size = num_objs;
15835 +       s_tmp->obj_hash =
15836 +           (struct acl_object_label **)
15837 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
15838 +
15839 +       if (!s_tmp->obj_hash)
15840 +               return ERR_PTR(-ENOMEM);
15841 +
15842 +       memset(s_tmp->obj_hash, 0,
15843 +              s_tmp->obj_hash_size *
15844 +              sizeof (struct acl_object_label *));
15845 +
15846 +       /* add in objects */
15847 +       err = copy_user_objs(ghash.first, s_tmp, role);
15848 +
15849 +       if (err)
15850 +               return ERR_PTR(err);
15851 +
15852 +       /* set pointer for parent subject */
15853 +       if (s_tmp->parent_subject) {
15854 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
15855 +
15856 +               if (IS_ERR(s_tmp2))
15857 +                       return s_tmp2;
15858 +
15859 +               s_tmp->parent_subject = s_tmp2;
15860 +       }
15861 +
15862 +       /* add in ip acls */
15863 +
15864 +       if (!s_tmp->ip_num) {
15865 +               s_tmp->ips = NULL;
15866 +               goto insert;
15867 +       }
15868 +
15869 +       i_tmp =
15870 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
15871 +                                              sizeof (struct
15872 +                                                      acl_ip_label *));
15873 +
15874 +       if (!i_tmp)
15875 +               return ERR_PTR(-ENOMEM);
15876 +
15877 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
15878 +               *(i_tmp + i_num) =
15879 +                   (struct acl_ip_label *)
15880 +                   acl_alloc(sizeof (struct acl_ip_label));
15881 +               if (!*(i_tmp + i_num))
15882 +                       return ERR_PTR(-ENOMEM);
15883 +
15884 +               if (copy_from_user
15885 +                   (&i_utmp2, s_tmp->ips + i_num,
15886 +                    sizeof (struct acl_ip_label *)))
15887 +                       return ERR_PTR(-EFAULT);
15888 +
15889 +               if (copy_from_user
15890 +                   (*(i_tmp + i_num), i_utmp2,
15891 +                    sizeof (struct acl_ip_label)))
15892 +                       return ERR_PTR(-EFAULT);
15893 +               
15894 +               if ((*(i_tmp + i_num))->iface == NULL)
15895 +                       continue;
15896 +
15897 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
15898 +               if (!len || len >= IFNAMSIZ)
15899 +                       return ERR_PTR(-EINVAL);
15900 +               tmp = acl_alloc(len);
15901 +               if (tmp == NULL)
15902 +                       return ERR_PTR(-ENOMEM);
15903 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
15904 +                       return ERR_PTR(-EFAULT);
15905 +               (*(i_tmp + i_num))->iface = tmp;
15906 +       }
15907 +
15908 +       s_tmp->ips = i_tmp;
15909 +
15910 +insert:
15911 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
15912 +                              s_tmp->device))
15913 +               return ERR_PTR(-ENOMEM);
15914 +
15915 +       return s_tmp;
15916 +}
15917 +
15918 +static int
15919 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
15920 +{
15921 +       struct acl_subject_label s_pre;
15922 +       struct acl_subject_label * ret;
15923 +       int err;
15924 +
15925 +       while (userp) {
15926 +               if (copy_from_user(&s_pre, userp,
15927 +                                  sizeof (struct acl_subject_label)))
15928 +                       return -EFAULT;
15929 +               
15930 +               /* do not add nested subjects here, add
15931 +                  while parsing objects
15932 +               */
15933 +
15934 +               if (s_pre.mode & GR_NESTED) {
15935 +                       userp = s_pre.prev;
15936 +                       continue;
15937 +               }
15938 +
15939 +               ret = do_copy_user_subj(userp, role);
15940 +
15941 +               err = PTR_ERR(ret);
15942 +               if (IS_ERR(ret))
15943 +                       return err;
15944 +
15945 +               insert_acl_subj_label(ret, role);
15946 +
15947 +               userp = s_pre.prev;
15948 +       }
15949 +
15950 +       return 0;
15951 +}
15952 +
15953 +static int
15954 +copy_user_acl(struct gr_arg *arg)
15955 +{
15956 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
15957 +       struct sprole_pw *sptmp;
15958 +       struct gr_hash_struct *ghash;
15959 +       uid_t *domainlist;
15960 +       unsigned int r_num;
15961 +       unsigned int len;
15962 +       char *tmp;
15963 +       int err = 0;
15964 +       __u16 i;
15965 +       __u32 num_subjs;
15966 +
15967 +       /* we need a default and kernel role */
15968 +       if (arg->role_db.num_roles < 2)
15969 +               return -EINVAL;
15970 +
15971 +       /* copy special role authentication info from userspace */
15972 +
15973 +       num_sprole_pws = arg->num_sprole_pws;
15974 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
15975 +
15976 +       if (!acl_special_roles) {
15977 +               err = -ENOMEM;
15978 +               goto cleanup;
15979 +       }
15980 +
15981 +       for (i = 0; i < num_sprole_pws; i++) {
15982 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
15983 +               if (!sptmp) {
15984 +                       err = -ENOMEM;
15985 +                       goto cleanup;
15986 +               }
15987 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
15988 +                                  sizeof (struct sprole_pw))) {
15989 +                       err = -EFAULT;
15990 +                       goto cleanup;
15991 +               }
15992 +
15993 +               len =
15994 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
15995 +
15996 +               if (!len || len >= GR_SPROLE_LEN) {
15997 +                       err = -EINVAL;
15998 +                       goto cleanup;
15999 +               }
16000 +
16001 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
16002 +                       err = -ENOMEM;
16003 +                       goto cleanup;
16004 +               }
16005 +
16006 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
16007 +                       err = -EFAULT;
16008 +                       goto cleanup;
16009 +               }
16010 +
16011 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
16012 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
16013 +#endif
16014 +               sptmp->rolename = tmp;
16015 +               acl_special_roles[i] = sptmp;
16016 +       }
16017 +
16018 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
16019 +
16020 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
16021 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
16022 +
16023 +               if (!r_tmp) {
16024 +                       err = -ENOMEM;
16025 +                       goto cleanup;
16026 +               }
16027 +
16028 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
16029 +                                  sizeof (struct acl_role_label *))) {
16030 +                       err = -EFAULT;
16031 +                       goto cleanup;
16032 +               }
16033 +
16034 +               if (copy_from_user(r_tmp, r_utmp2,
16035 +                                  sizeof (struct acl_role_label))) {
16036 +                       err = -EFAULT;
16037 +                       goto cleanup;
16038 +               }
16039 +
16040 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
16041 +
16042 +               if (!len || len >= PATH_MAX) {
16043 +                       err = -EINVAL;
16044 +                       goto cleanup;
16045 +               }
16046 +
16047 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
16048 +                       err = -ENOMEM;
16049 +                       goto cleanup;
16050 +               }
16051 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
16052 +                       err = -EFAULT;
16053 +                       goto cleanup;
16054 +               }
16055 +               r_tmp->rolename = tmp;
16056 +
16057 +               if (!strcmp(r_tmp->rolename, "default")
16058 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
16059 +                       default_role = r_tmp;
16060 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
16061 +                       kernel_role = r_tmp;
16062 +               }
16063 +
16064 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
16065 +                       err = -ENOMEM;
16066 +                       goto cleanup;
16067 +               }
16068 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
16069 +                       err = -EFAULT;
16070 +                       goto cleanup;
16071 +               }
16072 +
16073 +               r_tmp->hash = ghash;
16074 +
16075 +               num_subjs = count_user_subjs(r_tmp->hash->first);
16076 +
16077 +               r_tmp->subj_hash_size = num_subjs;
16078 +               r_tmp->subj_hash =
16079 +                   (struct acl_subject_label **)
16080 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
16081 +
16082 +               if (!r_tmp->subj_hash) {
16083 +                       err = -ENOMEM;
16084 +                       goto cleanup;
16085 +               }
16086 +
16087 +               err = copy_user_allowedips(r_tmp);
16088 +               if (err)
16089 +                       goto cleanup;
16090 +
16091 +               /* copy domain info */
16092 +               if (r_tmp->domain_children != NULL) {
16093 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
16094 +                       if (domainlist == NULL) {
16095 +                               err = -ENOMEM;
16096 +                               goto cleanup;
16097 +                       }
16098 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
16099 +                               err = -EFAULT;
16100 +                               goto cleanup;
16101 +                       }
16102 +                       r_tmp->domain_children = domainlist;
16103 +               }
16104 +
16105 +               err = copy_user_transitions(r_tmp);
16106 +               if (err)
16107 +                       goto cleanup;
16108 +
16109 +               memset(r_tmp->subj_hash, 0,
16110 +                      r_tmp->subj_hash_size *
16111 +                      sizeof (struct acl_subject_label *));
16112 +
16113 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
16114 +
16115 +               if (err)
16116 +                       goto cleanup;
16117 +
16118 +               /* set nested subject list to null */
16119 +               r_tmp->hash->first = NULL;
16120 +
16121 +               insert_acl_role_label(r_tmp);
16122 +       }
16123 +
16124 +       goto return_err;
16125 +      cleanup:
16126 +       free_variables();
16127 +      return_err:
16128 +       return err;
16129 +
16130 +}
16131 +
16132 +static int
16133 +gracl_init(struct gr_arg *args)
16134 +{
16135 +       int error = 0;
16136 +
16137 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
16138 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
16139 +
16140 +       if (init_variables(args)) {
16141 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
16142 +               error = -ENOMEM;
16143 +               free_variables();
16144 +               goto out;
16145 +       }
16146 +
16147 +       error = copy_user_acl(args);
16148 +       free_init_variables();
16149 +       if (error) {
16150 +               free_variables();
16151 +               goto out;
16152 +       }
16153 +
16154 +       if ((error = gr_set_acls(0))) {
16155 +               free_variables();
16156 +               goto out;
16157 +       }
16158 +
16159 +       gr_status |= GR_READY;
16160 +      out:
16161 +       return error;
16162 +}
16163 +
16164 +/* derived from glibc fnmatch() 0: match, 1: no match*/
16165 +
16166 +static int
16167 +glob_match(const char *p, const char *n)
16168 +{
16169 +       char c;
16170 +
16171 +       while ((c = *p++) != '\0') {
16172 +       switch (c) {
16173 +               case '?':
16174 +                       if (*n == '\0')
16175 +                               return 1;
16176 +                       else if (*n == '/')
16177 +                               return 1;
16178 +                       break;
16179 +               case '\\':
16180 +                       if (*n != c)
16181 +                               return 1;
16182 +                       break;
16183 +               case '*':
16184 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
16185 +                               if (*n == '/')
16186 +                                       return 1;
16187 +                               else if (c == '?') {
16188 +                                       if (*n == '\0')
16189 +                                               return 1;
16190 +                                       else
16191 +                                               ++n;
16192 +                               }
16193 +                       }
16194 +                       if (c == '\0') {
16195 +                               return 0;
16196 +                       } else {
16197 +                               const char *endp;
16198 +
16199 +                               if ((endp = strchr(n, '/')) == NULL)
16200 +                                       endp = n + strlen(n);
16201 +
16202 +                               if (c == '[') {
16203 +                                       for (--p; n < endp; ++n)
16204 +                                               if (!glob_match(p, n))
16205 +                                                       return 0;
16206 +                               } else if (c == '/') {
16207 +                                       while (*n != '\0' && *n != '/')
16208 +                                               ++n;
16209 +                                       if (*n == '/' && !glob_match(p, n + 1))
16210 +                                               return 0;
16211 +                               } else {
16212 +                                       for (--p; n < endp; ++n)
16213 +                                               if (*n == c && !glob_match(p, n))
16214 +                                                       return 0;
16215 +                               }
16216 +
16217 +                               return 1;
16218 +                       }
16219 +               case '[':
16220 +                       {
16221 +                       int not;
16222 +                       char cold;
16223 +
16224 +                       if (*n == '\0' || *n == '/')
16225 +                               return 1;
16226 +
16227 +                       not = (*p == '!' || *p == '^');
16228 +                       if (not)
16229 +                               ++p;
16230 +
16231 +                       c = *p++;
16232 +                       for (;;) {
16233 +                               unsigned char fn = (unsigned char)*n;
16234 +
16235 +                               if (c == '\0')
16236 +                                       return 1;
16237 +                               else {
16238 +                                       if (c == fn)
16239 +                                               goto matched;
16240 +                                       cold = c;
16241 +                                       c = *p++;
16242 +
16243 +                                       if (c == '-' && *p != ']') {
16244 +                                               unsigned char cend = *p++;
16245 +
16246 +                                               if (cend == '\0')
16247 +                                                       return 1;
16248 +
16249 +                                               if (cold <= fn && fn <= cend)
16250 +                                                       goto matched;
16251 +
16252 +                                               c = *p++;
16253 +                                       }
16254 +                               }
16255 +
16256 +                               if (c == ']')
16257 +                                       break;
16258 +                       }
16259 +                       if (!not)
16260 +                               return 1;
16261 +                       break;
16262 +               matched:
16263 +                       while (c != ']') {
16264 +                               if (c == '\0')
16265 +                                       return 1;
16266 +
16267 +                               c = *p++;
16268 +                       }
16269 +                       if (not)
16270 +                               return 1;
16271 +               }
16272 +               break;
16273 +       default:
16274 +               if (c != *n)
16275 +                       return 1;
16276 +       }
16277 +
16278 +       ++n;
16279 +       }
16280 +
16281 +       if (*n == '\0')
16282 +               return 0;
16283 +
16284 +       if (*n == '/')
16285 +               return 0;
16286 +
16287 +       return 1;
16288 +}
16289 +
16290 +static struct acl_object_label *
16291 +chk_glob_label(struct acl_object_label *globbed,
16292 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
16293 +{
16294 +       struct acl_object_label *tmp;
16295 +
16296 +       if (*path == NULL)
16297 +               *path = gr_to_filename_nolock(dentry, mnt);
16298 +
16299 +       tmp = globbed;
16300 +
16301 +       while (tmp) {
16302 +               if (!glob_match(tmp->filename, *path))
16303 +                       return tmp;
16304 +               tmp = tmp->next;
16305 +       }
16306 +
16307 +       return NULL;
16308 +}
16309 +
16310 +static struct acl_object_label *
16311 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
16312 +           const ino_t curr_ino, const dev_t curr_dev,
16313 +           const struct acl_subject_label *subj, char **path)
16314 +{
16315 +       struct acl_subject_label *tmpsubj;
16316 +       struct acl_object_label *retval;
16317 +       struct acl_object_label *retval2;
16318 +
16319 +       tmpsubj = (struct acl_subject_label *) subj;
16320 +       read_lock(&gr_inode_lock);
16321 +       do {
16322 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
16323 +               if (retval) {
16324 +                       if (retval->globbed) {
16325 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
16326 +                                               (struct vfsmount *)orig_mnt, path);
16327 +                               if (retval2)
16328 +                                       retval = retval2;
16329 +                       }
16330 +                       break;
16331 +               }
16332 +       } while ((tmpsubj = tmpsubj->parent_subject));
16333 +       read_unlock(&gr_inode_lock);
16334 +
16335 +       return retval;
16336 +}
16337 +
16338 +static __inline__ struct acl_object_label *
16339 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
16340 +           const struct dentry *curr_dentry,
16341 +           const struct acl_subject_label *subj, char **path)
16342 +{
16343 +       return __full_lookup(orig_dentry, orig_mnt,
16344 +                            curr_dentry->d_inode->i_ino, 
16345 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
16346 +}
16347 +
16348 +static struct acl_object_label *
16349 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16350 +             const struct acl_subject_label *subj, char *path)
16351 +{
16352 +       struct dentry *dentry = (struct dentry *) l_dentry;
16353 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
16354 +       struct acl_object_label *retval;
16355 +
16356 +       spin_lock(&dcache_lock);
16357 +
16358 +       if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt)) {
16359 +               retval = fakefs_obj;
16360 +               goto out;
16361 +       }
16362 +
16363 +       for (;;) {
16364 +               if (dentry == real_root && mnt == real_root_mnt)
16365 +                       break;
16366 +
16367 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
16368 +                       if (mnt->mnt_parent == mnt)
16369 +                               break;
16370 +
16371 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
16372 +                       if (retval != NULL)
16373 +                               goto out;
16374 +
16375 +                       dentry = mnt->mnt_mountpoint;
16376 +                       mnt = mnt->mnt_parent;
16377 +                       continue;
16378 +               }
16379 +
16380 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
16381 +               if (retval != NULL)
16382 +                       goto out;
16383 +
16384 +               dentry = dentry->d_parent;
16385 +       }
16386 +
16387 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
16388 +
16389 +       if (retval == NULL)
16390 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
16391 +out:
16392 +       spin_unlock(&dcache_lock);
16393 +       return retval;
16394 +}
16395 +
16396 +static __inline__ struct acl_object_label *
16397 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16398 +             const struct acl_subject_label *subj)
16399 +{
16400 +       char *path = NULL;
16401 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
16402 +}
16403 +
16404 +static __inline__ struct acl_object_label *
16405 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16406 +                    const struct acl_subject_label *subj, char *path)
16407 +{
16408 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
16409 +}
16410 +
16411 +static struct acl_subject_label *
16412 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
16413 +              const struct acl_role_label *role)
16414 +{
16415 +       struct dentry *dentry = (struct dentry *) l_dentry;
16416 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
16417 +       struct acl_subject_label *retval;
16418 +
16419 +       spin_lock(&dcache_lock);
16420 +
16421 +       for (;;) {
16422 +               if (dentry == real_root && mnt == real_root_mnt)
16423 +                       break;
16424 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
16425 +                       if (mnt->mnt_parent == mnt)
16426 +                               break;
16427 +
16428 +                       read_lock(&gr_inode_lock);
16429 +                       retval =
16430 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
16431 +                                               dentry->d_inode->i_sb->s_dev, role);
16432 +                       read_unlock(&gr_inode_lock);
16433 +                       if (retval != NULL)
16434 +                               goto out;
16435 +
16436 +                       dentry = mnt->mnt_mountpoint;
16437 +                       mnt = mnt->mnt_parent;
16438 +                       continue;
16439 +               }
16440 +
16441 +               read_lock(&gr_inode_lock);
16442 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
16443 +                                         dentry->d_inode->i_sb->s_dev, role);
16444 +               read_unlock(&gr_inode_lock);
16445 +               if (retval != NULL)
16446 +                       goto out;
16447 +
16448 +               dentry = dentry->d_parent;
16449 +       }
16450 +
16451 +       read_lock(&gr_inode_lock);
16452 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
16453 +                                 dentry->d_inode->i_sb->s_dev, role);
16454 +       read_unlock(&gr_inode_lock);
16455 +
16456 +       if (unlikely(retval == NULL)) {
16457 +               read_lock(&gr_inode_lock);
16458 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
16459 +                                         real_root->d_inode->i_sb->s_dev, role);
16460 +               read_unlock(&gr_inode_lock);
16461 +       }
16462 +out:
16463 +       spin_unlock(&dcache_lock);
16464 +
16465 +       return retval;
16466 +}
16467 +
16468 +static void
16469 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
16470 +{
16471 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
16472 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
16473 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
16474 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
16475 +
16476 +       return;
16477 +}
16478 +
16479 +static void
16480 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
16481 +                      const unsigned int effective, const unsigned int fs)
16482 +{
16483 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
16484 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_dentry,
16485 +                      task->exec_file->f_vfsmnt) : task->acl->filename, task->acl->filename,
16486 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
16487 +
16488 +       return;
16489 +}
16490 +
16491 +__u32
16492 +gr_check_link(const struct dentry * new_dentry,
16493 +             const struct dentry * parent_dentry,
16494 +             const struct vfsmount * parent_mnt,
16495 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
16496 +{
16497 +       struct acl_object_label *obj;
16498 +       __u32 oldmode, newmode;
16499 +       __u32 needmode;
16500 +
16501 +       if (unlikely(!(gr_status & GR_READY)))
16502 +               return (GR_CREATE | GR_LINK);
16503 +
16504 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
16505 +       oldmode = obj->mode;
16506 +
16507 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
16508 +               oldmode |= (GR_CREATE | GR_LINK);
16509 +
16510 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
16511 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
16512 +               needmode |= GR_SETID | GR_AUDIT_SETID;
16513 +
16514 +       newmode =
16515 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
16516 +                           oldmode | needmode);
16517 +
16518 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
16519 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
16520 +                             GR_INHERIT | GR_AUDIT_INHERIT);
16521 +
16522 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
16523 +               goto bad;
16524 +
16525 +       if ((oldmode & needmode) != needmode)
16526 +               goto bad;
16527 +
16528 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
16529 +       if ((newmode & needmode) != needmode)
16530 +               goto bad;
16531 +
16532 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
16533 +               return newmode;
16534 +bad:
16535 +       needmode = oldmode;
16536 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
16537 +               needmode |= GR_SETID;
16538 +       
16539 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
16540 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
16541 +               return (GR_CREATE | GR_LINK);
16542 +       } else if (newmode & GR_SUPPRESS)
16543 +               return GR_SUPPRESS;
16544 +       else
16545 +               return 0;
16546 +}
16547 +
16548 +__u32
16549 +gr_search_file(const struct dentry * dentry, const __u32 mode,
16550 +              const struct vfsmount * mnt)
16551 +{
16552 +       __u32 retval = mode;
16553 +       struct acl_subject_label *curracl;
16554 +       struct acl_object_label *currobj;
16555 +
16556 +       if (unlikely(!(gr_status & GR_READY)))
16557 +               return (mode & ~GR_AUDITS);
16558 +
16559 +       curracl = current->acl;
16560 +
16561 +       currobj = chk_obj_label(dentry, mnt, curracl);
16562 +       retval = currobj->mode & mode;
16563 +
16564 +       if (unlikely
16565 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
16566 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
16567 +               __u32 new_mode = mode;
16568 +
16569 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
16570 +
16571 +               retval = new_mode;
16572 +
16573 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
16574 +                       new_mode |= GR_INHERIT;
16575 +
16576 +               if (!(mode & GR_NOLEARN))
16577 +                       gr_log_learn(current, dentry, mnt, new_mode);
16578 +       }
16579 +
16580 +       return retval;
16581 +}
16582 +
16583 +__u32
16584 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
16585 +               const struct vfsmount * mnt, const __u32 mode)
16586 +{
16587 +       struct name_entry *match;
16588 +       struct acl_object_label *matchpo;
16589 +       struct acl_subject_label *curracl;
16590 +       char *path;
16591 +       __u32 retval;
16592 +
16593 +       if (unlikely(!(gr_status & GR_READY)))
16594 +               return (mode & ~GR_AUDITS);
16595 +
16596 +       preempt_disable();
16597 +       path = gr_to_filename_rbac(new_dentry, mnt);
16598 +       match = lookup_name_entry(path);
16599 +
16600 +       if (!match)
16601 +               goto check_parent;
16602 +
16603 +       curracl = current->acl;
16604 +
16605 +       read_lock(&gr_inode_lock);
16606 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
16607 +       read_unlock(&gr_inode_lock);
16608 +
16609 +       if (matchpo) {
16610 +               if ((matchpo->mode & mode) !=
16611 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
16612 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
16613 +                       __u32 new_mode = mode;
16614 +
16615 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
16616 +
16617 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
16618 +
16619 +                       preempt_enable();
16620 +                       return new_mode;
16621 +               }
16622 +               preempt_enable();
16623 +               return (matchpo->mode & mode);
16624 +       }
16625 +
16626 +      check_parent:
16627 +       curracl = current->acl;
16628 +
16629 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
16630 +       retval = matchpo->mode & mode;
16631 +
16632 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
16633 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
16634 +               __u32 new_mode = mode;
16635 +
16636 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
16637 +
16638 +               gr_log_learn(current, new_dentry, mnt, new_mode);
16639 +               preempt_enable();
16640 +               return new_mode;
16641 +       }
16642 +
16643 +       preempt_enable();
16644 +       return retval;
16645 +}
16646 +
16647 +int
16648 +gr_check_hidden_task(const struct task_struct *task)
16649 +{
16650 +       if (unlikely(!(gr_status & GR_READY)))
16651 +               return 0;
16652 +
16653 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
16654 +               return 1;
16655 +
16656 +       return 0;
16657 +}
16658 +
16659 +int
16660 +gr_check_protected_task(const struct task_struct *task)
16661 +{
16662 +       if (unlikely(!(gr_status & GR_READY) || !task))
16663 +               return 0;
16664 +
16665 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
16666 +           task->acl != current->acl)
16667 +               return 1;
16668 +
16669 +       return 0;
16670 +}
16671 +
16672 +void
16673 +gr_copy_label(struct task_struct *tsk)
16674 +{
16675 +       tsk->signal->used_accept = 0;
16676 +       tsk->acl_sp_role = 0;
16677 +       tsk->acl_role_id = current->acl_role_id;
16678 +       tsk->acl = current->acl;
16679 +       tsk->role = current->role;
16680 +       tsk->signal->curr_ip = current->signal->curr_ip;
16681 +       if (current->exec_file)
16682 +               get_file(current->exec_file);
16683 +       tsk->exec_file = current->exec_file;
16684 +       tsk->is_writable = current->is_writable;
16685 +       if (unlikely(current->signal->used_accept))
16686 +               current->signal->curr_ip = 0;
16687 +
16688 +       return;
16689 +}
16690 +
16691 +static void
16692 +gr_set_proc_res(struct task_struct *task)
16693 +{
16694 +       struct acl_subject_label *proc;
16695 +       unsigned short i;
16696 +
16697 +       proc = task->acl;
16698 +
16699 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
16700 +               return;
16701 +
16702 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
16703 +               if (!(proc->resmask & (1 << i)))
16704 +                       continue;
16705 +
16706 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
16707 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
16708 +       }
16709 +
16710 +       return;
16711 +}
16712 +
16713 +int
16714 +gr_check_user_change(int real, int effective, int fs)
16715 +{
16716 +       unsigned int i;
16717 +       __u16 num;
16718 +       uid_t *uidlist;
16719 +       int curuid;
16720 +       int realok = 0;
16721 +       int effectiveok = 0;
16722 +       int fsok = 0;
16723 +
16724 +       if (unlikely(!(gr_status & GR_READY)))
16725 +               return 0;
16726 +
16727 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
16728 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
16729 +
16730 +       num = current->acl->user_trans_num;
16731 +       uidlist = current->acl->user_transitions;
16732 +
16733 +       if (uidlist == NULL)
16734 +               return 0;
16735 +
16736 +       if (real == -1)
16737 +               realok = 1;
16738 +       if (effective == -1)
16739 +               effectiveok = 1;
16740 +       if (fs == -1)
16741 +               fsok = 1;
16742 +
16743 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
16744 +               for (i = 0; i < num; i++) {
16745 +                       curuid = (int)uidlist[i];
16746 +                       if (real == curuid)
16747 +                               realok = 1;
16748 +                       if (effective == curuid)
16749 +                               effectiveok = 1;
16750 +                       if (fs == curuid)
16751 +                               fsok = 1;
16752 +               }
16753 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
16754 +               for (i = 0; i < num; i++) {
16755 +                       curuid = (int)uidlist[i];
16756 +                       if (real == curuid)
16757 +                               break;
16758 +                       if (effective == curuid)
16759 +                               break;
16760 +                       if (fs == curuid)
16761 +                               break;
16762 +               }
16763 +               /* not in deny list */
16764 +               if (i == num) {
16765 +                       realok = 1;
16766 +                       effectiveok = 1;
16767 +                       fsok = 1;
16768 +               }
16769 +       }
16770 +
16771 +       if (realok && effectiveok && fsok)
16772 +               return 0;
16773 +       else {
16774 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
16775 +               return 1;
16776 +       }
16777 +}
16778 +
16779 +int
16780 +gr_check_group_change(int real, int effective, int fs)
16781 +{
16782 +       unsigned int i;
16783 +       __u16 num;
16784 +       gid_t *gidlist;
16785 +       int curgid;
16786 +       int realok = 0;
16787 +       int effectiveok = 0;
16788 +       int fsok = 0;
16789 +
16790 +       if (unlikely(!(gr_status & GR_READY)))
16791 +               return 0;
16792 +
16793 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
16794 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
16795 +
16796 +       num = current->acl->group_trans_num;
16797 +       gidlist = current->acl->group_transitions;
16798 +
16799 +       if (gidlist == NULL)
16800 +               return 0;
16801 +
16802 +       if (real == -1)
16803 +               realok = 1;
16804 +       if (effective == -1)
16805 +               effectiveok = 1;
16806 +       if (fs == -1)
16807 +               fsok = 1;
16808 +
16809 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
16810 +               for (i = 0; i < num; i++) {
16811 +                       curgid = (int)gidlist[i];
16812 +                       if (real == curgid)
16813 +                               realok = 1;
16814 +                       if (effective == curgid)
16815 +                               effectiveok = 1;
16816 +                       if (fs == curgid)
16817 +                               fsok = 1;
16818 +               }
16819 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
16820 +               for (i = 0; i < num; i++) {
16821 +                       curgid = (int)gidlist[i];
16822 +                       if (real == curgid)
16823 +                               break;
16824 +                       if (effective == curgid)
16825 +                               break;
16826 +                       if (fs == curgid)
16827 +                               break;
16828 +               }
16829 +               /* not in deny list */
16830 +               if (i == num) {
16831 +                       realok = 1;
16832 +                       effectiveok = 1;
16833 +                       fsok = 1;
16834 +               }
16835 +       }
16836 +
16837 +       if (realok && effectiveok && fsok)
16838 +               return 0;
16839 +       else {
16840 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
16841 +               return 1;
16842 +       }
16843 +}
16844 +
16845 +void
16846 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
16847 +{
16848 +       struct acl_role_label *role = task->role;
16849 +       struct acl_subject_label *subj = NULL;
16850 +       struct acl_object_label *obj;
16851 +       struct file *filp;
16852 +
16853 +       if (unlikely(!(gr_status & GR_READY)))
16854 +               return;
16855 +
16856 +       filp = task->exec_file;
16857 +
16858 +       /* kernel process, we'll give them the kernel role */
16859 +       if (unlikely(!filp)) {
16860 +               task->role = kernel_role;
16861 +               task->acl = kernel_role->root_label;
16862 +               return;
16863 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
16864 +               role = lookup_acl_role_label(task, uid, gid);
16865 +
16866 +       /* perform subject lookup in possibly new role
16867 +          we can use this result below in the case where role == task->role
16868 +       */
16869 +       subj = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, role);
16870 +
16871 +       /* if we changed uid/gid, but result in the same role
16872 +          and are using inheritance, don't lose the inherited subject
16873 +          if current subject is other than what normal lookup
16874 +          would result in, we arrived via inheritance, don't
16875 +          lose subject
16876 +       */
16877 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
16878 +                                  (subj == task->acl)))
16879 +               task->acl = subj;
16880 +
16881 +       task->role = role;
16882 +
16883 +       task->is_writable = 0;
16884 +
16885 +       /* ignore additional mmap checks for processes that are writable 
16886 +          by the default ACL */
16887 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
16888 +       if (unlikely(obj->mode & GR_WRITE))
16889 +               task->is_writable = 1;
16890 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
16891 +       if (unlikely(obj->mode & GR_WRITE))
16892 +               task->is_writable = 1;
16893 +
16894 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
16895 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
16896 +#endif
16897 +
16898 +       gr_set_proc_res(task);
16899 +
16900 +       return;
16901 +}
16902 +
16903 +int
16904 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
16905 +{
16906 +       struct task_struct *task = current;
16907 +       struct acl_subject_label *newacl;
16908 +       struct acl_object_label *obj;
16909 +       __u32 retmode;
16910 +
16911 +       if (unlikely(!(gr_status & GR_READY)))
16912 +               return 0;
16913 +
16914 +       newacl = chk_subj_label(dentry, mnt, task->role);
16915 +
16916 +       task_lock(task);
16917 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
16918 +            GR_POVERRIDE) && (task->acl != newacl) &&
16919 +            !(task->role->roletype & GR_ROLE_GOD) &&
16920 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
16921 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
16922 +           (atomic_read(&task->fs->count) > 1 ||
16923 +            atomic_read(&task->files->count) > 1 ||
16924 +            atomic_read(&task->sighand->count) > 1)) {
16925 +                task_unlock(task);
16926 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
16927 +               return -EACCES;
16928 +       }
16929 +       task_unlock(task);
16930 +
16931 +       obj = chk_obj_label(dentry, mnt, task->acl);
16932 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
16933 +
16934 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
16935 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
16936 +               if (obj->nested)
16937 +                       task->acl = obj->nested;
16938 +               else
16939 +                       task->acl = newacl;
16940 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
16941 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
16942 +
16943 +       task->is_writable = 0;
16944 +
16945 +       /* ignore additional mmap checks for processes that are writable 
16946 +          by the default ACL */
16947 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
16948 +       if (unlikely(obj->mode & GR_WRITE))
16949 +               task->is_writable = 1;
16950 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
16951 +       if (unlikely(obj->mode & GR_WRITE))
16952 +               task->is_writable = 1;
16953 +
16954 +       gr_set_proc_res(task);
16955 +
16956 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
16957 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
16958 +#endif
16959 +       return 0;
16960 +}
16961 +
16962 +static void
16963 +do_handle_delete(const ino_t ino, const dev_t dev)
16964 +{
16965 +       struct acl_object_label *matchpo;
16966 +       struct acl_subject_label *matchps;
16967 +       struct acl_subject_label *subj;
16968 +       struct acl_role_label *role;
16969 +       unsigned int i, x;
16970 +
16971 +       FOR_EACH_ROLE_START(role, i)
16972 +               FOR_EACH_SUBJECT_START(role, subj, x)
16973 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
16974 +                               matchpo->mode |= GR_DELETED;
16975 +               FOR_EACH_SUBJECT_END(subj,x)
16976 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
16977 +                       if (subj->inode == ino && subj->device == dev)
16978 +                               subj->mode |= GR_DELETED;
16979 +               FOR_EACH_NESTED_SUBJECT_END(subj)
16980 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
16981 +                       matchps->mode |= GR_DELETED;
16982 +       FOR_EACH_ROLE_END(role,i)
16983 +
16984 +       return;
16985 +}
16986 +
16987 +void
16988 +gr_handle_delete(const ino_t ino, const dev_t dev)
16989 +{
16990 +       if (unlikely(!(gr_status & GR_READY)))
16991 +               return;
16992 +
16993 +       write_lock(&gr_inode_lock);
16994 +       if (unlikely((unsigned long)lookup_inodev_entry(ino, dev)))
16995 +               do_handle_delete(ino, dev);
16996 +       write_unlock(&gr_inode_lock);
16997 +
16998 +       return;
16999 +}
17000 +
17001 +static void
17002 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
17003 +                    const ino_t newinode, const dev_t newdevice,
17004 +                    struct acl_subject_label *subj)
17005 +{
17006 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
17007 +       struct acl_object_label *match;
17008 +
17009 +       match = subj->obj_hash[index];
17010 +
17011 +       while (match && (match->inode != oldinode ||
17012 +              match->device != olddevice ||
17013 +              !(match->mode & GR_DELETED)))
17014 +               match = match->next;
17015 +
17016 +       if (match && (match->inode == oldinode)
17017 +           && (match->device == olddevice)
17018 +           && (match->mode & GR_DELETED)) {
17019 +               if (match->prev == NULL) {
17020 +                       subj->obj_hash[index] = match->next;
17021 +                       if (match->next != NULL)
17022 +                               match->next->prev = NULL;
17023 +               } else {
17024 +                       match->prev->next = match->next;
17025 +                       if (match->next != NULL)
17026 +                               match->next->prev = match->prev;
17027 +               }
17028 +               match->prev = NULL;
17029 +               match->next = NULL;
17030 +               match->inode = newinode;
17031 +               match->device = newdevice;
17032 +               match->mode &= ~GR_DELETED;
17033 +
17034 +               insert_acl_obj_label(match, subj);
17035 +       }
17036 +
17037 +       return;
17038 +}
17039 +
17040 +static void
17041 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
17042 +                     const ino_t newinode, const dev_t newdevice,
17043 +                     struct acl_role_label *role)
17044 +{
17045 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
17046 +       struct acl_subject_label *match;
17047 +
17048 +       match = role->subj_hash[index];
17049 +
17050 +       while (match && (match->inode != oldinode ||
17051 +              match->device != olddevice ||
17052 +              !(match->mode & GR_DELETED)))
17053 +               match = match->next;
17054 +
17055 +       if (match && (match->inode == oldinode)
17056 +           && (match->device == olddevice)
17057 +           && (match->mode & GR_DELETED)) {
17058 +               if (match->prev == NULL) {
17059 +                       role->subj_hash[index] = match->next;
17060 +                       if (match->next != NULL)
17061 +                               match->next->prev = NULL;
17062 +               } else {
17063 +                       match->prev->next = match->next;
17064 +                       if (match->next != NULL)
17065 +                               match->next->prev = match->prev;
17066 +               }
17067 +               match->prev = NULL;
17068 +               match->next = NULL;
17069 +               match->inode = newinode;
17070 +               match->device = newdevice;
17071 +               match->mode &= ~GR_DELETED;
17072 +
17073 +               insert_acl_subj_label(match, role);
17074 +       }
17075 +
17076 +       return;
17077 +}
17078 +
17079 +static void
17080 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
17081 +                   const ino_t newinode, const dev_t newdevice)
17082 +{
17083 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
17084 +       struct inodev_entry *match;
17085 +
17086 +       match = inodev_set.i_hash[index];
17087 +
17088 +       while (match && (match->nentry->inode != oldinode ||
17089 +              match->nentry->device != olddevice))
17090 +               match = match->next;
17091 +
17092 +       if (match && (match->nentry->inode == oldinode)
17093 +           && (match->nentry->device == olddevice)) {
17094 +               if (match->prev == NULL) {
17095 +                       inodev_set.i_hash[index] = match->next;
17096 +                       if (match->next != NULL)
17097 +                               match->next->prev = NULL;
17098 +               } else {
17099 +                       match->prev->next = match->next;
17100 +                       if (match->next != NULL)
17101 +                               match->next->prev = match->prev;
17102 +               }
17103 +               match->prev = NULL;
17104 +               match->next = NULL;
17105 +               match->nentry->inode = newinode;
17106 +               match->nentry->device = newdevice;
17107 +
17108 +               insert_inodev_entry(match);
17109 +       }
17110 +
17111 +       return;
17112 +}
17113 +
17114 +static void
17115 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
17116 +                const struct vfsmount *mnt)
17117 +{
17118 +       struct acl_subject_label *subj;
17119 +       struct acl_role_label *role;
17120 +       unsigned int i, x;
17121 +
17122 +       FOR_EACH_ROLE_START(role, i)
17123 +               update_acl_subj_label(matchn->inode, matchn->device,
17124 +                                     dentry->d_inode->i_ino,
17125 +                                     dentry->d_inode->i_sb->s_dev, role);
17126 +
17127 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
17128 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
17129 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
17130 +                               subj->inode = dentry->d_inode->i_ino;
17131 +                               subj->device = dentry->d_inode->i_sb->s_dev;
17132 +                       }
17133 +               FOR_EACH_NESTED_SUBJECT_END(subj)
17134 +               FOR_EACH_SUBJECT_START(role, subj, x)
17135 +                       update_acl_obj_label(matchn->inode, matchn->device,
17136 +                                            dentry->d_inode->i_ino,
17137 +                                            dentry->d_inode->i_sb->s_dev, subj);
17138 +               FOR_EACH_SUBJECT_END(subj,x)
17139 +       FOR_EACH_ROLE_END(role,i)
17140 +
17141 +       update_inodev_entry(matchn->inode, matchn->device,
17142 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
17143 +
17144 +       return;
17145 +}
17146 +
17147 +void
17148 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
17149 +{
17150 +       struct name_entry *matchn;
17151 +
17152 +       if (unlikely(!(gr_status & GR_READY)))
17153 +               return;
17154 +
17155 +       preempt_disable();
17156 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
17157 +
17158 +       if (unlikely((unsigned long)matchn)) {
17159 +               write_lock(&gr_inode_lock);
17160 +               do_handle_create(matchn, dentry, mnt);
17161 +               write_unlock(&gr_inode_lock);
17162 +       }
17163 +       preempt_enable();
17164 +
17165 +       return;
17166 +}
17167 +
17168 +void
17169 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
17170 +                struct dentry *old_dentry,
17171 +                struct dentry *new_dentry,
17172 +                struct vfsmount *mnt, const __u8 replace)
17173 +{
17174 +       struct name_entry *matchn;
17175 +
17176 +       if (unlikely(!(gr_status & GR_READY)))
17177 +               return;
17178 +
17179 +       preempt_disable();
17180 +       matchn = lookup_name_entry(gr_to_filename_rbac(new_dentry, mnt));
17181 +
17182 +       /* we wouldn't have to check d_inode if it weren't for
17183 +          NFS silly-renaming
17184 +        */
17185 +
17186 +       write_lock(&gr_inode_lock);
17187 +       if (unlikely(replace && new_dentry->d_inode)) {
17188 +               if (unlikely(lookup_inodev_entry(new_dentry->d_inode->i_ino,
17189 +                                       new_dentry->d_inode->i_sb->s_dev) &&
17190 +                   (old_dentry->d_inode->i_nlink <= 1)))
17191 +                       do_handle_delete(new_dentry->d_inode->i_ino,
17192 +                                        new_dentry->d_inode->i_sb->s_dev);
17193 +       }
17194 +
17195 +       if (unlikely(lookup_inodev_entry(old_dentry->d_inode->i_ino,
17196 +                               old_dentry->d_inode->i_sb->s_dev) &&
17197 +           (old_dentry->d_inode->i_nlink <= 1)))
17198 +               do_handle_delete(old_dentry->d_inode->i_ino,
17199 +                                old_dentry->d_inode->i_sb->s_dev);
17200 +
17201 +       if (unlikely((unsigned long)matchn))
17202 +               do_handle_create(matchn, old_dentry, mnt);
17203 +
17204 +       write_unlock(&gr_inode_lock);
17205 +       preempt_enable();
17206 +
17207 +       return;
17208 +}
17209 +
17210 +static int
17211 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
17212 +                        unsigned char **sum)
17213 +{
17214 +       struct acl_role_label *r;
17215 +       struct role_allowed_ip *ipp;
17216 +       struct role_transition *trans;
17217 +       unsigned int i;
17218 +       int found = 0;
17219 +
17220 +       /* check transition table */
17221 +
17222 +       for (trans = current->role->transitions; trans; trans = trans->next) {
17223 +               if (!strcmp(rolename, trans->rolename)) {
17224 +                       found = 1;
17225 +                       break;
17226 +               }
17227 +       }
17228 +
17229 +       if (!found)
17230 +               return 0;
17231 +
17232 +       /* handle special roles that do not require authentication
17233 +          and check ip */
17234 +
17235 +       FOR_EACH_ROLE_START(r, i)
17236 +               if (!strcmp(rolename, r->rolename) &&
17237 +                   (r->roletype & GR_ROLE_SPECIAL)) {
17238 +                       found = 0;
17239 +                       if (r->allowed_ips != NULL) {
17240 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
17241 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
17242 +                                            (ntohl(ipp->addr) & ipp->netmask))
17243 +                                               found = 1;
17244 +                               }
17245 +                       } else
17246 +                               found = 2;
17247 +                       if (!found)
17248 +                               return 0;
17249 +
17250 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
17251 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
17252 +                               *salt = NULL;
17253 +                               *sum = NULL;
17254 +                               return 1;
17255 +                       }
17256 +               }
17257 +       FOR_EACH_ROLE_END(r,i)
17258 +
17259 +       for (i = 0; i < num_sprole_pws; i++) {
17260 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
17261 +                       *salt = acl_special_roles[i]->salt;
17262 +                       *sum = acl_special_roles[i]->sum;
17263 +                       return 1;
17264 +               }
17265 +       }
17266 +
17267 +       return 0;
17268 +}
17269 +
17270 +static void
17271 +assign_special_role(char *rolename)
17272 +{
17273 +       struct acl_object_label *obj;
17274 +       struct acl_role_label *r;
17275 +       struct acl_role_label *assigned = NULL;
17276 +       struct task_struct *tsk;
17277 +       struct file *filp;
17278 +       unsigned int i;
17279 +
17280 +       FOR_EACH_ROLE_START(r, i)
17281 +               if (!strcmp(rolename, r->rolename) &&
17282 +                   (r->roletype & GR_ROLE_SPECIAL))
17283 +                       assigned = r;
17284 +       FOR_EACH_ROLE_END(r,i)
17285 +
17286 +       if (!assigned)
17287 +               return;
17288 +
17289 +       read_lock(&tasklist_lock);
17290 +       read_lock(&grsec_exec_file_lock);
17291 +
17292 +       tsk = current->parent;
17293 +       if (tsk == NULL)
17294 +               goto out_unlock;
17295 +
17296 +       filp = tsk->exec_file;
17297 +       if (filp == NULL)
17298 +               goto out_unlock;
17299 +
17300 +       tsk->is_writable = 0;
17301 +
17302 +       tsk->acl_sp_role = 1;
17303 +       tsk->acl_role_id = ++acl_sp_role_value;
17304 +       tsk->role = assigned;
17305 +       tsk->acl = chk_subj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role);
17306 +
17307 +       /* ignore additional mmap checks for processes that are writable 
17308 +          by the default ACL */
17309 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
17310 +       if (unlikely(obj->mode & GR_WRITE))
17311 +               tsk->is_writable = 1;
17312 +       obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, tsk->role->root_label);
17313 +       if (unlikely(obj->mode & GR_WRITE))
17314 +               tsk->is_writable = 1;
17315 +
17316 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
17317 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
17318 +#endif
17319 +
17320 +out_unlock:
17321 +       read_unlock(&grsec_exec_file_lock);
17322 +       read_unlock(&tasklist_lock);
17323 +       return;
17324 +}
17325 +
17326 +int gr_check_secure_terminal(struct task_struct *task)
17327 +{
17328 +       struct task_struct *p, *p2, *p3;
17329 +       struct files_struct *files;
17330 +       struct fdtable *fdt;
17331 +       struct file *our_file = NULL, *file;
17332 +       int i;
17333 +
17334 +       if (task->signal->tty == NULL)
17335 +               return 1;
17336 +
17337 +       files = get_files_struct(task);
17338 +       if (files != NULL) {
17339 +               rcu_read_lock();
17340 +               fdt = files_fdtable(files);
17341 +               for (i=0; i < fdt->max_fds; i++) {
17342 +                       file = fcheck_files(files, i);
17343 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
17344 +                               get_file(file);
17345 +                               our_file = file;
17346 +                       }
17347 +               }
17348 +               rcu_read_unlock();
17349 +               put_files_struct(files);
17350 +       }
17351 +
17352 +       if (our_file == NULL)
17353 +               return 1;
17354 +
17355 +       read_lock(&tasklist_lock);
17356 +       do_each_thread(p2, p) {
17357 +               files = get_files_struct(p);
17358 +               if (files == NULL ||
17359 +                   (p->signal && p->signal->tty == task->signal->tty)) {
17360 +                       if (files != NULL)
17361 +                               put_files_struct(files);
17362 +                       continue;
17363 +               }
17364 +               rcu_read_lock();
17365 +               fdt = files_fdtable(files);
17366 +               for (i=0; i < fdt->max_fds; i++) {
17367 +                       file = fcheck_files(files, i);
17368 +                       if (file && S_ISCHR(file->f_dentry->d_inode->i_mode) &&
17369 +                           file->f_dentry->d_inode->i_rdev == our_file->f_dentry->d_inode->i_rdev) {
17370 +                               p3 = task;
17371 +                               while (p3->pid > 0) {
17372 +                                       if (p3 == p)
17373 +                                               break;
17374 +                                       p3 = p3->parent;
17375 +                               }
17376 +                               if (p3 == p)
17377 +                                       break;
17378 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
17379 +                               gr_handle_alertkill(p);
17380 +                               rcu_read_unlock();
17381 +                               put_files_struct(files);
17382 +                               read_unlock(&tasklist_lock);
17383 +                               fput(our_file);
17384 +                               return 0;
17385 +                       }
17386 +               }
17387 +               rcu_read_unlock();
17388 +               put_files_struct(files);
17389 +       } while_each_thread(p2, p);
17390 +       read_unlock(&tasklist_lock);
17391 +
17392 +       fput(our_file);
17393 +       return 1;
17394 +}
17395 +
17396 +ssize_t
17397 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
17398 +{
17399 +       struct gr_arg_wrapper uwrap;
17400 +       unsigned char *sprole_salt;
17401 +       unsigned char *sprole_sum;
17402 +       int error = sizeof (struct gr_arg_wrapper);
17403 +       int error2 = 0;
17404 +
17405 +       down(&gr_dev_sem);
17406 +
17407 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
17408 +               error = -EPERM;
17409 +               goto out;
17410 +       }
17411 +
17412 +       if (count != sizeof (struct gr_arg_wrapper)) {
17413 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
17414 +               error = -EINVAL;
17415 +               goto out;
17416 +       }
17417 +
17418 +       
17419 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
17420 +               gr_auth_expires = 0;
17421 +               gr_auth_attempts = 0;
17422 +       }
17423 +
17424 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
17425 +               error = -EFAULT;
17426 +               goto out;
17427 +       }
17428 +
17429 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
17430 +               error = -EINVAL;
17431 +               goto out;
17432 +       }
17433 +
17434 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
17435 +               error = -EFAULT;
17436 +               goto out;
17437 +       }
17438 +
17439 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
17440 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
17441 +           time_after(gr_auth_expires, get_seconds())) {
17442 +               error = -EBUSY;
17443 +               goto out;
17444 +       }
17445 +
17446 +       /* if non-root trying to do anything other than use a special role,
17447 +          do not attempt authentication, do not count towards authentication
17448 +          locking
17449 +        */
17450 +
17451 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
17452 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
17453 +           current->uid) {
17454 +               error = -EPERM;
17455 +               goto out;
17456 +       }
17457 +
17458 +       /* ensure pw and special role name are null terminated */
17459 +
17460 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
17461 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
17462 +
17463 +       /* Okay. 
17464 +        * We have our enough of the argument structure..(we have yet
17465 +        * to copy_from_user the tables themselves) . Copy the tables
17466 +        * only if we need them, i.e. for loading operations. */
17467 +
17468 +       switch (gr_usermode->mode) {
17469 +       case STATUS:
17470 +                       if (gr_status & GR_READY) {
17471 +                               error = 1;
17472 +                               if (!gr_check_secure_terminal(current))
17473 +                                       error = 3;
17474 +                       } else
17475 +                               error = 2;
17476 +                       goto out;
17477 +       case SHUTDOWN:
17478 +               if ((gr_status & GR_READY)
17479 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
17480 +                       gr_status &= ~GR_READY;
17481 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
17482 +                       free_variables();
17483 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
17484 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
17485 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
17486 +               } else if (gr_status & GR_READY) {
17487 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
17488 +                       error = -EPERM;
17489 +               } else {
17490 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
17491 +                       error = -EAGAIN;
17492 +               }
17493 +               break;
17494 +       case ENABLE:
17495 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
17496 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
17497 +               else {
17498 +                       if (gr_status & GR_READY)
17499 +                               error = -EAGAIN;
17500 +                       else
17501 +                               error = error2;
17502 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
17503 +               }
17504 +               break;
17505 +       case RELOAD:
17506 +               if (!(gr_status & GR_READY)) {
17507 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
17508 +                       error = -EAGAIN;
17509 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
17510 +                       lock_kernel();
17511 +                       gr_status &= ~GR_READY;
17512 +                       free_variables();
17513 +                       if (!(error2 = gracl_init(gr_usermode))) {
17514 +                               unlock_kernel();
17515 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
17516 +                       } else {
17517 +                               unlock_kernel();
17518 +                               error = error2;
17519 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
17520 +                       }
17521 +               } else {
17522 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
17523 +                       error = -EPERM;
17524 +               }
17525 +               break;
17526 +       case SEGVMOD:
17527 +               if (unlikely(!(gr_status & GR_READY))) {
17528 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
17529 +                       error = -EAGAIN;
17530 +                       break;
17531 +               }
17532 +
17533 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
17534 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
17535 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
17536 +                               struct acl_subject_label *segvacl;
17537 +                               segvacl =
17538 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
17539 +                                                         gr_usermode->segv_device,
17540 +                                                         current->role);
17541 +                               if (segvacl) {
17542 +                                       segvacl->crashes = 0;
17543 +                                       segvacl->expires = 0;
17544 +                               }
17545 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
17546 +                               gr_remove_uid(gr_usermode->segv_uid);
17547 +                       }
17548 +               } else {
17549 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
17550 +                       error = -EPERM;
17551 +               }
17552 +               break;
17553 +       case SPROLE:
17554 +       case SPROLEPAM:
17555 +               if (unlikely(!(gr_status & GR_READY))) {
17556 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
17557 +                       error = -EAGAIN;
17558 +                       break;
17559 +               }
17560 +
17561 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
17562 +                       current->role->expires = 0;
17563 +                       current->role->auth_attempts = 0;
17564 +               }
17565 +
17566 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
17567 +                   time_after(current->role->expires, get_seconds())) {
17568 +                       error = -EBUSY;
17569 +                       goto out;
17570 +               }
17571 +
17572 +               if (lookup_special_role_auth
17573 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
17574 +                   && ((!sprole_salt && !sprole_sum)
17575 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
17576 +                       char *p = "";
17577 +                       assign_special_role(gr_usermode->sp_role);
17578 +                       read_lock(&tasklist_lock);
17579 +                       if (current->parent)
17580 +                               p = current->parent->role->rolename;
17581 +                       read_unlock(&tasklist_lock);
17582 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
17583 +                                       p, acl_sp_role_value);
17584 +               } else {
17585 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
17586 +                       error = -EPERM;
17587 +                       if(!(current->role->auth_attempts++))
17588 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
17589 +
17590 +                       goto out;
17591 +               }
17592 +               break;
17593 +       case UNSPROLE:
17594 +               if (unlikely(!(gr_status & GR_READY))) {
17595 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
17596 +                       error = -EAGAIN;
17597 +                       break;
17598 +               }
17599 +
17600 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
17601 +                       char *p = "";
17602 +                       int i = 0;
17603 +
17604 +                       read_lock(&tasklist_lock);
17605 +                       if (current->parent) {
17606 +                               p = current->parent->role->rolename;
17607 +                               i = current->parent->acl_role_id;
17608 +                       }
17609 +                       read_unlock(&tasklist_lock);
17610 +
17611 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
17612 +                       gr_set_acls(1);
17613 +               } else {
17614 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
17615 +                       error = -EPERM;
17616 +                       goto out;
17617 +               }
17618 +               break;
17619 +       default:
17620 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
17621 +               error = -EINVAL;
17622 +               break;
17623 +       }
17624 +
17625 +       if (error != -EPERM)
17626 +               goto out;
17627 +
17628 +       if(!(gr_auth_attempts++))
17629 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
17630 +
17631 +      out:
17632 +       up(&gr_dev_sem);
17633 +       return error;
17634 +}
17635 +
17636 +int
17637 +gr_set_acls(const int type)
17638 +{
17639 +       struct acl_object_label *obj;
17640 +       struct task_struct *task, *task2;
17641 +       struct file *filp;
17642 +       struct acl_role_label *role = current->role;
17643 +       __u16 acl_role_id = current->acl_role_id;
17644 +
17645 +       read_lock(&tasklist_lock);
17646 +       read_lock(&grsec_exec_file_lock);
17647 +       do_each_thread(task2, task) {
17648 +               /* check to see if we're called from the exit handler,
17649 +                  if so, only replace ACLs that have inherited the admin
17650 +                  ACL */
17651 +
17652 +               if (type && (task->role != role ||
17653 +                            task->acl_role_id != acl_role_id))
17654 +                       continue;
17655 +
17656 +               task->acl_role_id = 0;
17657 +               task->acl_sp_role = 0;
17658 +
17659 +               if ((filp = task->exec_file)) {
17660 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
17661 +
17662 +                       task->acl =
17663 +                           chk_subj_label(filp->f_dentry, filp->f_vfsmnt,
17664 +                                          task->role);
17665 +                       if (task->acl) {
17666 +                               struct acl_subject_label *curr;
17667 +                               curr = task->acl;
17668 +
17669 +                               task->is_writable = 0;
17670 +                               /* ignore additional mmap checks for processes that are writable 
17671 +                                  by the default ACL */
17672 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
17673 +                               if (unlikely(obj->mode & GR_WRITE))
17674 +                                       task->is_writable = 1;
17675 +                               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, task->role->root_label);
17676 +                               if (unlikely(obj->mode & GR_WRITE))
17677 +                                       task->is_writable = 1;
17678 +
17679 +                               gr_set_proc_res(task);
17680 +
17681 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
17682 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
17683 +#endif
17684 +                       } else {
17685 +                               read_unlock(&grsec_exec_file_lock);
17686 +                               read_unlock(&tasklist_lock);
17687 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
17688 +                               return 1;
17689 +                       }
17690 +               } else {
17691 +                       // it's a kernel process
17692 +                       task->role = kernel_role;
17693 +                       task->acl = kernel_role->root_label;
17694 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
17695 +                       task->acl->mode &= ~GR_PROCFIND;
17696 +#endif
17697 +               }
17698 +       } while_each_thread(task2, task);
17699 +       read_unlock(&grsec_exec_file_lock);
17700 +       read_unlock(&tasklist_lock);
17701 +       return 0;
17702 +}
17703 +
17704 +void
17705 +gr_learn_resource(const struct task_struct *task,
17706 +                 const int res, const unsigned long wanted, const int gt)
17707 +{
17708 +       struct acl_subject_label *acl;
17709 +
17710 +       if (unlikely((gr_status & GR_READY) &&
17711 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
17712 +               goto skip_reslog;
17713 +
17714 +#ifdef CONFIG_GRKERNSEC_RESLOG
17715 +       gr_log_resource(task, res, wanted, gt);
17716 +#endif
17717 +      skip_reslog:
17718 +
17719 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
17720 +               return;
17721 +
17722 +       acl = task->acl;
17723 +
17724 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
17725 +                  !(acl->resmask & (1 << (unsigned short) res))))
17726 +               return;
17727 +
17728 +       if (wanted >= acl->res[res].rlim_cur) {
17729 +               unsigned long res_add;
17730 +
17731 +               res_add = wanted;
17732 +               switch (res) {
17733 +               case RLIMIT_CPU:
17734 +                       res_add += GR_RLIM_CPU_BUMP;
17735 +                       break;
17736 +               case RLIMIT_FSIZE:
17737 +                       res_add += GR_RLIM_FSIZE_BUMP;
17738 +                       break;
17739 +               case RLIMIT_DATA:
17740 +                       res_add += GR_RLIM_DATA_BUMP;
17741 +                       break;
17742 +               case RLIMIT_STACK:
17743 +                       res_add += GR_RLIM_STACK_BUMP;
17744 +                       break;
17745 +               case RLIMIT_CORE:
17746 +                       res_add += GR_RLIM_CORE_BUMP;
17747 +                       break;
17748 +               case RLIMIT_RSS:
17749 +                       res_add += GR_RLIM_RSS_BUMP;
17750 +                       break;
17751 +               case RLIMIT_NPROC:
17752 +                       res_add += GR_RLIM_NPROC_BUMP;
17753 +                       break;
17754 +               case RLIMIT_NOFILE:
17755 +                       res_add += GR_RLIM_NOFILE_BUMP;
17756 +                       break;
17757 +               case RLIMIT_MEMLOCK:
17758 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
17759 +                       break;
17760 +               case RLIMIT_AS:
17761 +                       res_add += GR_RLIM_AS_BUMP;
17762 +                       break;
17763 +               case RLIMIT_LOCKS:
17764 +                       res_add += GR_RLIM_LOCKS_BUMP;
17765 +                       break;
17766 +               }
17767 +
17768 +               acl->res[res].rlim_cur = res_add;
17769 +
17770 +               if (wanted > acl->res[res].rlim_max)
17771 +                       acl->res[res].rlim_max = res_add;
17772 +
17773 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
17774 +                              task->role->roletype, acl->filename,
17775 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
17776 +                              "", (unsigned long) res);
17777 +       }
17778 +
17779 +       return;
17780 +}
17781 +
17782 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
17783 +void
17784 +pax_set_initial_flags(struct linux_binprm *bprm)
17785 +{
17786 +       struct task_struct *task = current;
17787 +        struct acl_subject_label *proc;
17788 +       unsigned long flags;
17789 +
17790 +        if (unlikely(!(gr_status & GR_READY)))
17791 +                return;
17792 +
17793 +       flags = pax_get_flags(task);
17794 +
17795 +        proc = task->acl;
17796 +
17797 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
17798 +               flags &= ~MF_PAX_PAGEEXEC;
17799 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
17800 +               flags &= ~MF_PAX_SEGMEXEC;
17801 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
17802 +               flags &= ~MF_PAX_RANDMMAP;
17803 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
17804 +               flags &= ~MF_PAX_EMUTRAMP;
17805 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
17806 +               flags &= ~MF_PAX_MPROTECT;
17807 +
17808 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
17809 +               flags |= MF_PAX_PAGEEXEC;
17810 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
17811 +               flags |= MF_PAX_SEGMEXEC;
17812 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
17813 +               flags |= MF_PAX_RANDMMAP;
17814 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
17815 +               flags |= MF_PAX_EMUTRAMP;
17816 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
17817 +               flags |= MF_PAX_MPROTECT;
17818 +
17819 +       pax_set_flags(task, flags);
17820 +
17821 +        return;
17822 +}
17823 +#endif
17824 +
17825 +#ifdef CONFIG_SYSCTL
17826 +extern struct proc_dir_entry *proc_sys_root;
17827 +
17828 +/* the following function is called under the BKL */
17829 +
17830 +__u32
17831 +gr_handle_sysctl(const struct ctl_table *table, const void *oldval,
17832 +                const void *newval)
17833 +{
17834 +       struct proc_dir_entry *tmp;
17835 +       struct nameidata nd;
17836 +       const char *proc_sys = "/proc/sys";
17837 +       char *path;
17838 +       struct acl_object_label *obj;
17839 +       unsigned short len = 0, pos = 0, depth = 0, i;
17840 +       __u32 err = 0;
17841 +       __u32 mode = 0;
17842 +
17843 +       if (unlikely(!(gr_status & GR_READY)))
17844 +               return 1;
17845 +
17846 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
17847 +
17848 +       if (oldval)
17849 +               mode |= GR_READ;
17850 +       if (newval)
17851 +               mode |= GR_WRITE;
17852 +
17853 +       /* convert the requested sysctl entry into a pathname */
17854 +
17855 +       for (tmp = table->de; tmp != proc_sys_root; tmp = tmp->parent) {
17856 +               len += strlen(tmp->name);
17857 +               len++;
17858 +               depth++;
17859 +       }
17860 +
17861 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE)
17862 +               return 0;       /* deny */
17863 +
17864 +       memset(path, 0, PAGE_SIZE);
17865 +
17866 +       memcpy(path, proc_sys, strlen(proc_sys));
17867 +
17868 +       pos += strlen(proc_sys);
17869 +
17870 +       for (; depth > 0; depth--) {
17871 +               path[pos] = '/';
17872 +               pos++;
17873 +               for (i = 1, tmp = table->de; tmp != proc_sys_root;
17874 +                    tmp = tmp->parent) {
17875 +                       if (depth == i) {
17876 +                               memcpy(path + pos, tmp->name,
17877 +                                      strlen(tmp->name));
17878 +                               pos += strlen(tmp->name);
17879 +                       }
17880 +                       i++;
17881 +               }
17882 +       }
17883 +
17884 +       err = path_lookup(path, LOOKUP_FOLLOW, &nd);
17885 +
17886 +       if (err)
17887 +               goto out;
17888 +
17889 +       obj = chk_obj_label(nd.dentry, nd.mnt, current->acl);
17890 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
17891 +
17892 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
17893 +                    ((err & mode) != mode))) {
17894 +               __u32 new_mode = mode;
17895 +
17896 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
17897 +
17898 +               err = new_mode;
17899 +               gr_log_learn(current, nd.dentry, nd.mnt, new_mode);
17900 +       } else if ((err & mode) != mode && !(err & GR_SUPPRESS)) {
17901 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
17902 +                              path, (mode & GR_READ) ? " reading" : "",
17903 +                              (mode & GR_WRITE) ? " writing" : "");
17904 +               err = 0;
17905 +       } else if ((err & mode) != mode) {
17906 +               err = 0;
17907 +       } else if (((err & mode) == mode) && (err & GR_AUDITS)) {
17908 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
17909 +                              path, (mode & GR_READ) ? " reading" : "",
17910 +                              (mode & GR_WRITE) ? " writing" : "");
17911 +       }
17912 +
17913 +       path_release(&nd);
17914 +
17915 +      out:
17916 +       return err;
17917 +}
17918 +#endif
17919 +
17920 +int
17921 +gr_handle_proc_ptrace(struct task_struct *task)
17922 +{
17923 +       struct file *filp;
17924 +       struct task_struct *tmp = task;
17925 +       struct task_struct *curtemp = current;
17926 +       __u32 retmode;
17927 +
17928 +       if (unlikely(!(gr_status & GR_READY)))
17929 +               return 0;
17930 +
17931 +       read_lock(&tasklist_lock);
17932 +       read_lock(&grsec_exec_file_lock);
17933 +       filp = task->exec_file;
17934 +
17935 +       while (tmp->pid > 0) {
17936 +               if (tmp == curtemp)
17937 +                       break;
17938 +               tmp = tmp->parent;
17939 +       }
17940 +
17941 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
17942 +               read_unlock(&grsec_exec_file_lock);
17943 +               read_unlock(&tasklist_lock);
17944 +               return 1;
17945 +       }
17946 +
17947 +       retmode = gr_search_file(filp->f_dentry, GR_NOPTRACE, filp->f_vfsmnt);
17948 +       read_unlock(&grsec_exec_file_lock);
17949 +       read_unlock(&tasklist_lock);
17950 +
17951 +       if (retmode & GR_NOPTRACE)
17952 +               return 1;
17953 +
17954 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
17955 +           && (current->acl != task->acl || (current->acl != current->role->root_label
17956 +           && current->pid != task->pid)))
17957 +               return 1;
17958 +
17959 +       return 0;
17960 +}
17961 +
17962 +int
17963 +gr_handle_ptrace(struct task_struct *task, const long request)
17964 +{
17965 +       struct task_struct *tmp = task;
17966 +       struct task_struct *curtemp = current;
17967 +       __u32 retmode;
17968 +
17969 +       if (unlikely(!(gr_status & GR_READY)))
17970 +               return 0;
17971 +
17972 +       read_lock(&tasklist_lock);
17973 +       while (tmp->pid > 0) {
17974 +               if (tmp == curtemp)
17975 +                       break;
17976 +               tmp = tmp->parent;
17977 +       }
17978 +
17979 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
17980 +               read_unlock(&tasklist_lock);
17981 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
17982 +               return 1;
17983 +       }
17984 +       read_unlock(&tasklist_lock);
17985 +
17986 +       read_lock(&grsec_exec_file_lock);
17987 +       if (unlikely(!task->exec_file)) {
17988 +               read_unlock(&grsec_exec_file_lock);
17989 +               return 0;
17990 +       }
17991 +
17992 +       retmode = gr_search_file(task->exec_file->f_dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_vfsmnt);
17993 +       read_unlock(&grsec_exec_file_lock);
17994 +
17995 +       if (retmode & GR_NOPTRACE) {
17996 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
17997 +               return 1;
17998 +       }
17999 +               
18000 +       if (retmode & GR_PTRACERD) {
18001 +               switch (request) {
18002 +               case PTRACE_POKETEXT:
18003 +               case PTRACE_POKEDATA:
18004 +               case PTRACE_POKEUSR:
18005 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
18006 +               case PTRACE_SETREGS:
18007 +               case PTRACE_SETFPREGS:
18008 +#endif
18009 +#ifdef CONFIG_X86
18010 +               case PTRACE_SETFPXREGS:
18011 +#endif
18012 +#ifdef CONFIG_ALTIVEC
18013 +               case PTRACE_SETVRREGS:
18014 +#endif
18015 +                       return 1;
18016 +               default:
18017 +                       return 0;
18018 +               }
18019 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
18020 +                  !(current->role->roletype & GR_ROLE_GOD) &&
18021 +                  (current->acl != task->acl)) {
18022 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
18023 +               return 1;
18024 +       }
18025 +
18026 +       return 0;
18027 +}
18028 +
18029 +static int is_writable_mmap(const struct file *filp)
18030 +{
18031 +       struct task_struct *task = current;
18032 +       struct acl_object_label *obj, *obj2;
18033 +
18034 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
18035 +           !task->is_writable && S_ISREG(filp->f_dentry->d_inode->i_mode)) {
18036 +               obj = chk_obj_label(filp->f_dentry, filp->f_vfsmnt, default_role->root_label);
18037 +               obj2 = chk_obj_label(filp->f_dentry, filp->f_vfsmnt,
18038 +                                    task->role->root_label);
18039 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
18040 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_dentry, filp->f_vfsmnt);
18041 +                       return 1;
18042 +               }
18043 +       }
18044 +       return 0;
18045 +}
18046 +
18047 +int
18048 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
18049 +{
18050 +       __u32 mode;
18051 +
18052 +       if (unlikely(!file || !(prot & PROT_EXEC)))
18053 +               return 1;
18054 +
18055 +       if (is_writable_mmap(file))
18056 +               return 0;
18057 +
18058 +       mode =
18059 +           gr_search_file(file->f_dentry,
18060 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
18061 +                          file->f_vfsmnt);
18062 +
18063 +       if (!gr_tpe_allow(file))
18064 +               return 0;
18065 +
18066 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
18067 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18068 +               return 0;
18069 +       } else if (unlikely(!(mode & GR_EXEC))) {
18070 +               return 0;
18071 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
18072 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18073 +               return 1;
18074 +       }
18075 +
18076 +       return 1;
18077 +}
18078 +
18079 +int
18080 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
18081 +{
18082 +       __u32 mode;
18083 +
18084 +       if (unlikely(!file || !(prot & PROT_EXEC)))
18085 +               return 1;
18086 +
18087 +       if (is_writable_mmap(file))
18088 +               return 0;
18089 +
18090 +       mode =
18091 +           gr_search_file(file->f_dentry,
18092 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
18093 +                          file->f_vfsmnt);
18094 +
18095 +       if (!gr_tpe_allow(file))
18096 +               return 0;
18097 +
18098 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
18099 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18100 +               return 0;
18101 +       } else if (unlikely(!(mode & GR_EXEC))) {
18102 +               return 0;
18103 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
18104 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_dentry, file->f_vfsmnt);
18105 +               return 1;
18106 +       }
18107 +
18108 +       return 1;
18109 +}
18110 +
18111 +void
18112 +gr_acl_handle_psacct(struct task_struct *task, const long code)
18113 +{
18114 +       unsigned long runtime;
18115 +       unsigned long cputime;
18116 +       unsigned int wday, cday;
18117 +       __u8 whr, chr;
18118 +       __u8 wmin, cmin;
18119 +       __u8 wsec, csec;
18120 +
18121 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
18122 +                    !(task->acl->mode & GR_PROCACCT)))
18123 +               return;
18124 +
18125 +       runtime = xtime.tv_sec - task->start_time.tv_sec;
18126 +       wday = runtime / (3600 * 24);
18127 +       runtime -= wday * (3600 * 24);
18128 +       whr = runtime / 3600;
18129 +       runtime -= whr * 3600;
18130 +       wmin = runtime / 60;
18131 +       runtime -= wmin * 60;
18132 +       wsec = runtime;
18133 +
18134 +       cputime = (task->utime + task->stime) / HZ;
18135 +       cday = cputime / (3600 * 24);
18136 +       cputime -= cday * (3600 * 24);
18137 +       chr = cputime / 3600;
18138 +       cputime -= chr * 3600;
18139 +       cmin = cputime / 60;
18140 +       cputime -= cmin * 60;
18141 +       csec = cputime;
18142 +
18143 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
18144 +
18145 +       return;
18146 +}
18147 +
18148 +void gr_set_kernel_label(struct task_struct *task)
18149 +{
18150 +       if (gr_status & GR_READY) {
18151 +               task->role = kernel_role;
18152 +               task->acl = kernel_role->root_label;
18153 +       }
18154 +       return;
18155 +}
18156 +
18157 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
18158 +{
18159 +       struct task_struct *task = current;
18160 +       struct dentry *dentry = file->f_dentry;
18161 +       struct vfsmount *mnt = file->f_vfsmnt;
18162 +       struct acl_object_label *obj, *tmp;
18163 +       struct acl_subject_label *subj;
18164 +       unsigned int bufsize;
18165 +       int is_not_root;
18166 +       char *path;
18167 +
18168 +       if (unlikely(!(gr_status & GR_READY)))
18169 +               return 1;
18170 +
18171 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
18172 +               return 1;
18173 +
18174 +       subj = task->acl;
18175 +       do {
18176 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
18177 +               if (obj != NULL)
18178 +                       return (obj->mode & GR_FIND) ? 1 : 0;
18179 +       } while ((subj = subj->parent_subject));
18180 +       
18181 +       obj = chk_obj_label(dentry, mnt, task->acl);
18182 +       if (obj->globbed == NULL)
18183 +               return (obj->mode & GR_FIND) ? 1 : 0;
18184 +
18185 +       is_not_root = ((obj->filename[0] == '/') &&
18186 +                  (obj->filename[1] == '\0')) ? 0 : 1;
18187 +       bufsize = PAGE_SIZE - namelen - is_not_root;
18188 +
18189 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
18190 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
18191 +               return 1;
18192 +
18193 +       preempt_disable();
18194 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
18195 +                          bufsize);
18196 +
18197 +       bufsize = strlen(path);
18198 +
18199 +       /* if base is "/", don't append an additional slash */
18200 +       if (is_not_root)
18201 +               *(path + bufsize) = '/';
18202 +       memcpy(path + bufsize + is_not_root, name, namelen);
18203 +       *(path + bufsize + namelen + is_not_root) = '\0';
18204 +
18205 +       tmp = obj->globbed;
18206 +       while (tmp) {
18207 +               if (!glob_match(tmp->filename, path)) {
18208 +                       preempt_enable();
18209 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
18210 +               }
18211 +               tmp = tmp->next;
18212 +       }
18213 +       preempt_enable();
18214 +       return (obj->mode & GR_FIND) ? 1 : 0;
18215 +}
18216 +
18217 +EXPORT_SYMBOL(gr_learn_resource);
18218 +EXPORT_SYMBOL(gr_set_kernel_label);
18219 +#ifdef CONFIG_SECURITY
18220 +EXPORT_SYMBOL(gr_check_user_change);
18221 +EXPORT_SYMBOL(gr_check_group_change);
18222 +#endif
18223 +
18224 diff -urNp linux-2.6.20.3/grsecurity/gracl_cap.c linux-2.6.20.3/grsecurity/gracl_cap.c
18225 --- linux-2.6.20.3/grsecurity/gracl_cap.c       1969-12-31 19:00:00.000000000 -0500
18226 +++ linux-2.6.20.3/grsecurity/gracl_cap.c       2007-03-23 08:11:31.000000000 -0400
18227 @@ -0,0 +1,110 @@
18228 +#include <linux/kernel.h>
18229 +#include <linux/module.h>
18230 +#include <linux/sched.h>
18231 +#include <linux/capability.h>
18232 +#include <linux/gracl.h>
18233 +#include <linux/grsecurity.h>
18234 +#include <linux/grinternal.h>
18235 +
18236 +static const char *captab_log[] = {
18237 +       "CAP_CHOWN",
18238 +       "CAP_DAC_OVERRIDE",
18239 +       "CAP_DAC_READ_SEARCH",
18240 +       "CAP_FOWNER",
18241 +       "CAP_FSETID",
18242 +       "CAP_KILL",
18243 +       "CAP_SETGID",
18244 +       "CAP_SETUID",
18245 +       "CAP_SETPCAP",
18246 +       "CAP_LINUX_IMMUTABLE",
18247 +       "CAP_NET_BIND_SERVICE",
18248 +       "CAP_NET_BROADCAST",
18249 +       "CAP_NET_ADMIN",
18250 +       "CAP_NET_RAW",
18251 +       "CAP_IPC_LOCK",
18252 +       "CAP_IPC_OWNER",
18253 +       "CAP_SYS_MODULE",
18254 +       "CAP_SYS_RAWIO",
18255 +       "CAP_SYS_CHROOT",
18256 +       "CAP_SYS_PTRACE",
18257 +       "CAP_SYS_PACCT",
18258 +       "CAP_SYS_ADMIN",
18259 +       "CAP_SYS_BOOT",
18260 +       "CAP_SYS_NICE",
18261 +       "CAP_SYS_RESOURCE",
18262 +       "CAP_SYS_TIME",
18263 +       "CAP_SYS_TTY_CONFIG",
18264 +       "CAP_MKNOD",
18265 +       "CAP_LEASE"
18266 +};
18267 +
18268 +EXPORT_SYMBOL(gr_task_is_capable);
18269 +EXPORT_SYMBOL(gr_is_capable_nolog);
18270 +
18271 +int
18272 +gr_task_is_capable(struct task_struct *task, const int cap)
18273 +{
18274 +       struct acl_subject_label *curracl;
18275 +       __u32 cap_drop = 0, cap_mask = 0;
18276 +
18277 +       if (!gr_acl_is_enabled())
18278 +               return 1;
18279 +
18280 +       curracl = task->acl;
18281 +
18282 +       cap_drop = curracl->cap_lower;
18283 +       cap_mask = curracl->cap_mask;
18284 +
18285 +       while ((curracl = curracl->parent_subject)) {
18286 +               if (!(cap_mask & (1 << cap)) && (curracl->cap_mask & (1 << cap)))
18287 +                       cap_drop |= curracl->cap_lower & (1 << cap);
18288 +               cap_mask |= curracl->cap_mask;
18289 +       }
18290 +
18291 +       if (!cap_raised(cap_drop, cap))
18292 +               return 1;
18293 +
18294 +       curracl = task->acl;
18295 +
18296 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
18297 +           && cap_raised(task->cap_effective, cap)) {
18298 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
18299 +                              task->role->roletype, task->uid,
18300 +                              task->gid, task->exec_file ?
18301 +                              gr_to_filename(task->exec_file->f_dentry,
18302 +                              task->exec_file->f_vfsmnt) : curracl->filename,
18303 +                              curracl->filename, 0UL,
18304 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
18305 +               return 1;
18306 +       }
18307 +
18308 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
18309 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
18310 +       return 0;
18311 +}
18312 +
18313 +int
18314 +gr_is_capable_nolog(const int cap)
18315 +{
18316 +       struct acl_subject_label *curracl;
18317 +       __u32 cap_drop = 0, cap_mask = 0;
18318 +
18319 +       if (!gr_acl_is_enabled())
18320 +               return 1;
18321 +
18322 +       curracl = current->acl;
18323 +
18324 +       cap_drop = curracl->cap_lower;
18325 +       cap_mask = curracl->cap_mask;
18326 +
18327 +       while ((curracl = curracl->parent_subject)) {
18328 +               cap_drop |= curracl->cap_lower & (cap_mask & ~curracl->cap_mask);
18329 +               cap_mask |= curracl->cap_mask;
18330 +       }
18331 +
18332 +       if (!cap_raised(cap_drop, cap))
18333 +               return 1;
18334 +
18335 +       return 0;
18336 +}
18337 +
18338 diff -urNp linux-2.6.20.3/grsecurity/gracl_fs.c linux-2.6.20.3/grsecurity/gracl_fs.c
18339 --- linux-2.6.20.3/grsecurity/gracl_fs.c        1969-12-31 19:00:00.000000000 -0500
18340 +++ linux-2.6.20.3/grsecurity/gracl_fs.c        2007-03-23 08:11:31.000000000 -0400
18341 @@ -0,0 +1,423 @@
18342 +#include <linux/kernel.h>
18343 +#include <linux/sched.h>
18344 +#include <linux/types.h>
18345 +#include <linux/fs.h>
18346 +#include <linux/file.h>
18347 +#include <linux/stat.h>
18348 +#include <linux/grsecurity.h>
18349 +#include <linux/grinternal.h>
18350 +#include <linux/gracl.h>
18351 +
18352 +__u32
18353 +gr_acl_handle_hidden_file(const struct dentry * dentry,
18354 +                         const struct vfsmount * mnt)
18355 +{
18356 +       __u32 mode;
18357 +
18358 +       if (unlikely(!dentry->d_inode))
18359 +               return GR_FIND;
18360 +
18361 +       mode =
18362 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
18363 +
18364 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
18365 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
18366 +               return mode;
18367 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
18368 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
18369 +               return 0;
18370 +       } else if (unlikely(!(mode & GR_FIND)))
18371 +               return 0;
18372 +
18373 +       return GR_FIND;
18374 +}
18375 +
18376 +__u32
18377 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
18378 +                  const int fmode)
18379 +{
18380 +       __u32 reqmode = GR_FIND;
18381 +       __u32 mode;
18382 +
18383 +       if (unlikely(!dentry->d_inode))
18384 +               return reqmode;
18385 +
18386 +       if (unlikely(fmode & O_APPEND))
18387 +               reqmode |= GR_APPEND;
18388 +       else if (unlikely(fmode & FMODE_WRITE))
18389 +               reqmode |= GR_WRITE;
18390 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
18391 +               reqmode |= GR_READ;
18392 +
18393 +       mode =
18394 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
18395 +                          mnt);
18396 +
18397 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
18398 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
18399 +                              reqmode & GR_READ ? " reading" : "",
18400 +                              reqmode & GR_WRITE ? " writing" : reqmode &
18401 +                              GR_APPEND ? " appending" : "");
18402 +               return reqmode;
18403 +       } else
18404 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
18405 +       {
18406 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
18407 +                              reqmode & GR_READ ? " reading" : "",
18408 +                              reqmode & GR_WRITE ? " writing" : reqmode &
18409 +                              GR_APPEND ? " appending" : "");
18410 +               return 0;
18411 +       } else if (unlikely((mode & reqmode) != reqmode))
18412 +               return 0;
18413 +
18414 +       return reqmode;
18415 +}
18416 +
18417 +__u32
18418 +gr_acl_handle_creat(const struct dentry * dentry,
18419 +                   const struct dentry * p_dentry,
18420 +                   const struct vfsmount * p_mnt, const int fmode,
18421 +                   const int imode)
18422 +{
18423 +       __u32 reqmode = GR_WRITE | GR_CREATE;
18424 +       __u32 mode;
18425 +
18426 +       if (unlikely(fmode & O_APPEND))
18427 +               reqmode |= GR_APPEND;
18428 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
18429 +               reqmode |= GR_READ;
18430 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
18431 +               reqmode |= GR_SETID;
18432 +
18433 +       mode =
18434 +           gr_check_create(dentry, p_dentry, p_mnt,
18435 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
18436 +
18437 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
18438 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
18439 +                              reqmode & GR_READ ? " reading" : "",
18440 +                              reqmode & GR_WRITE ? " writing" : reqmode &
18441 +                              GR_APPEND ? " appending" : "");
18442 +               return reqmode;
18443 +       } else
18444 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
18445 +       {
18446 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
18447 +                              reqmode & GR_READ ? " reading" : "",
18448 +                              reqmode & GR_WRITE ? " writing" : reqmode &
18449 +                              GR_APPEND ? " appending" : "");
18450 +               return 0;
18451 +       } else if (unlikely((mode & reqmode) != reqmode))
18452 +               return 0;
18453 +
18454 +       return reqmode;
18455 +}
18456 +
18457 +__u32
18458 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
18459 +                    const int fmode)
18460 +{
18461 +       __u32 mode, reqmode = GR_FIND;
18462 +
18463 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
18464 +               reqmode |= GR_EXEC;
18465 +       if (fmode & S_IWOTH)
18466 +               reqmode |= GR_WRITE;
18467 +       if (fmode & S_IROTH)
18468 +               reqmode |= GR_READ;
18469 +
18470 +       mode =
18471 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
18472 +                          mnt);
18473 +
18474 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
18475 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
18476 +                              reqmode & GR_READ ? " reading" : "",
18477 +                              reqmode & GR_WRITE ? " writing" : "",
18478 +                              reqmode & GR_EXEC ? " executing" : "");
18479 +               return reqmode;
18480 +       } else
18481 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
18482 +       {
18483 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
18484 +                              reqmode & GR_READ ? " reading" : "",
18485 +                              reqmode & GR_WRITE ? " writing" : "",
18486 +                              reqmode & GR_EXEC ? " executing" : "");
18487 +               return 0;
18488 +       } else if (unlikely((mode & reqmode) != reqmode))
18489 +               return 0;
18490 +
18491 +       return reqmode;
18492 +}
18493 +
18494 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
18495 +{
18496 +       __u32 mode;
18497 +
18498 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
18499 +
18500 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
18501 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
18502 +               return mode;
18503 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
18504 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
18505 +               return 0;
18506 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
18507 +               return 0;
18508 +
18509 +       return (reqmode);
18510 +}
18511 +
18512 +__u32
18513 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
18514 +{
18515 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
18516 +}
18517 +
18518 +__u32
18519 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
18520 +{
18521 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
18522 +}
18523 +
18524 +__u32
18525 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
18526 +{
18527 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
18528 +}
18529 +
18530 +__u32
18531 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
18532 +{
18533 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
18534 +}
18535 +
18536 +__u32
18537 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
18538 +                    mode_t mode)
18539 +{
18540 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
18541 +               return 1;
18542 +
18543 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
18544 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
18545 +                                  GR_FCHMOD_ACL_MSG);
18546 +       } else {
18547 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
18548 +       }
18549 +}
18550 +
18551 +__u32
18552 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
18553 +                   mode_t mode)
18554 +{
18555 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
18556 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
18557 +                                  GR_CHMOD_ACL_MSG);
18558 +       } else {
18559 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
18560 +       }
18561 +}
18562 +
18563 +__u32
18564 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
18565 +{
18566 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
18567 +}
18568 +
18569 +__u32
18570 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
18571 +{
18572 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
18573 +}
18574 +
18575 +__u32
18576 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
18577 +{
18578 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
18579 +                          GR_UNIXCONNECT_ACL_MSG);
18580 +}
18581 +
18582 +/* hardlinks require at minimum create permission,
18583 +   any additional privilege required is based on the
18584 +   privilege of the file being linked to
18585 +*/
18586 +__u32
18587 +gr_acl_handle_link(const struct dentry * new_dentry,
18588 +                  const struct dentry * parent_dentry,
18589 +                  const struct vfsmount * parent_mnt,
18590 +                  const struct dentry * old_dentry,
18591 +                  const struct vfsmount * old_mnt, const char *to)
18592 +{
18593 +       __u32 mode;
18594 +       __u32 needmode = GR_CREATE | GR_LINK;
18595 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
18596 +
18597 +       mode =
18598 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
18599 +                         old_mnt);
18600 +
18601 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
18602 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
18603 +               return mode;
18604 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
18605 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
18606 +               return 0;
18607 +       } else if (unlikely((mode & needmode) != needmode))
18608 +               return 0;
18609 +
18610 +       return 1;
18611 +}
18612 +
18613 +__u32
18614 +gr_acl_handle_symlink(const struct dentry * new_dentry,
18615 +                     const struct dentry * parent_dentry,
18616 +                     const struct vfsmount * parent_mnt, const char *from)
18617 +{
18618 +       __u32 needmode = GR_WRITE | GR_CREATE;
18619 +       __u32 mode;
18620 +
18621 +       mode =
18622 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
18623 +                           GR_CREATE | GR_AUDIT_CREATE |
18624 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
18625 +
18626 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
18627 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
18628 +               return mode;
18629 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
18630 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
18631 +               return 0;
18632 +       } else if (unlikely((mode & needmode) != needmode))
18633 +               return 0;
18634 +
18635 +       return (GR_WRITE | GR_CREATE);
18636 +}
18637 +
18638 +static __u32 generic_fs_create_handler(const struct dentry *new_dentry, const struct dentry *parent_dentry, const struct vfsmount *parent_mnt, __u32 reqmode, const char *fmt)
18639 +{
18640 +       __u32 mode;
18641 +
18642 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
18643 +
18644 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
18645 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
18646 +               return mode;
18647 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
18648 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
18649 +               return 0;
18650 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
18651 +               return 0;
18652 +
18653 +       return (reqmode);
18654 +}
18655 +
18656 +__u32
18657 +gr_acl_handle_mknod(const struct dentry * new_dentry,
18658 +                   const struct dentry * parent_dentry,
18659 +                   const struct vfsmount * parent_mnt,
18660 +                   const int mode)
18661 +{
18662 +       __u32 reqmode = GR_WRITE | GR_CREATE;
18663 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
18664 +               reqmode |= GR_SETID;
18665 +
18666 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
18667 +                                 reqmode, GR_MKNOD_ACL_MSG);
18668 +}
18669 +
18670 +__u32
18671 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
18672 +                   const struct dentry *parent_dentry,
18673 +                   const struct vfsmount *parent_mnt)
18674 +{
18675 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
18676 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
18677 +}
18678 +
18679 +#define RENAME_CHECK_SUCCESS(old, new) \
18680 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
18681 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
18682 +
18683 +int
18684 +gr_acl_handle_rename(struct dentry *new_dentry,
18685 +                    struct dentry *parent_dentry,
18686 +                    const struct vfsmount *parent_mnt,
18687 +                    struct dentry *old_dentry,
18688 +                    struct inode *old_parent_inode,
18689 +                    struct vfsmount *old_mnt, const char *newname)
18690 +{
18691 +       __u32 comp1, comp2;
18692 +       int error = 0;
18693 +
18694 +       if (unlikely(!gr_acl_is_enabled()))
18695 +               return 0;
18696 +
18697 +       if (!new_dentry->d_inode) {
18698 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
18699 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
18700 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
18701 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
18702 +                                      GR_DELETE | GR_AUDIT_DELETE |
18703 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
18704 +                                      GR_SUPPRESS, old_mnt);
18705 +       } else {
18706 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
18707 +                                      GR_CREATE | GR_DELETE |
18708 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
18709 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
18710 +                                      GR_SUPPRESS, parent_mnt);
18711 +               comp2 =
18712 +                   gr_search_file(old_dentry,
18713 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
18714 +                                  GR_DELETE | GR_AUDIT_DELETE |
18715 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
18716 +       }
18717 +
18718 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
18719 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
18720 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
18721 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
18722 +                && !(comp2 & GR_SUPPRESS)) {
18723 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
18724 +               error = -EACCES;
18725 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
18726 +               error = -EACCES;
18727 +
18728 +       return error;
18729 +}
18730 +
18731 +void
18732 +gr_acl_handle_exit(void)
18733 +{
18734 +       u16 id;
18735 +       char *rolename;
18736 +       struct file *exec_file;
18737 +
18738 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
18739 +               id = current->acl_role_id;
18740 +               rolename = current->role->rolename;
18741 +               gr_set_acls(1);
18742 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
18743 +       }
18744 +
18745 +       write_lock(&grsec_exec_file_lock);
18746 +       exec_file = current->exec_file;
18747 +       current->exec_file = NULL;
18748 +       write_unlock(&grsec_exec_file_lock);
18749 +
18750 +       if (exec_file)
18751 +               fput(exec_file);
18752 +}
18753 +
18754 +int
18755 +gr_acl_handle_procpidmem(const struct task_struct *task)
18756 +{
18757 +       if (unlikely(!gr_acl_is_enabled()))
18758 +               return 0;
18759 +
18760 +       if (task->acl->mode & GR_PROTPROCFD)
18761 +               return -EACCES;
18762 +
18763 +       return 0;
18764 +}
18765 diff -urNp linux-2.6.20.3/grsecurity/gracl_ip.c linux-2.6.20.3/grsecurity/gracl_ip.c
18766 --- linux-2.6.20.3/grsecurity/gracl_ip.c        1969-12-31 19:00:00.000000000 -0500
18767 +++ linux-2.6.20.3/grsecurity/gracl_ip.c        2007-03-23 08:11:31.000000000 -0400
18768 @@ -0,0 +1,313 @@
18769 +#include <linux/kernel.h>
18770 +#include <asm/uaccess.h>
18771 +#include <asm/errno.h>
18772 +#include <net/sock.h>
18773 +#include <linux/file.h>
18774 +#include <linux/fs.h>
18775 +#include <linux/net.h>
18776 +#include <linux/in.h>
18777 +#include <linux/skbuff.h>
18778 +#include <linux/ip.h>
18779 +#include <linux/udp.h>
18780 +#include <linux/smp_lock.h>
18781 +#include <linux/types.h>
18782 +#include <linux/sched.h>
18783 +#include <linux/netdevice.h>
18784 +#include <linux/inetdevice.h>
18785 +#include <linux/gracl.h>
18786 +#include <linux/grsecurity.h>
18787 +#include <linux/grinternal.h>
18788 +
18789 +#define GR_BIND        0x01
18790 +#define GR_CONNECT     0x02
18791 +#define GR_INVERT      0x04
18792 +
18793 +static const char * gr_protocols[256] = {
18794 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
18795 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
18796 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
18797 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
18798 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
18799 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
18800 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
18801 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
18802 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
18803 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
18804 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
18805 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
18806 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
18807 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
18808 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
18809 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
18810 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
18811 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
18812 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
18813 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
18814 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
18815 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
18816 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
18817 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
18818 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
18819 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
18820 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
18821 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
18822 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
18823 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
18824 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
18825 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
18826 +       };
18827 +
18828 +static const char * gr_socktypes[11] = {
18829 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
18830 +       "unknown:7", "unknown:8", "unknown:9", "packet"
18831 +       };
18832 +
18833 +const char *
18834 +gr_proto_to_name(unsigned char proto)
18835 +{
18836 +       return gr_protocols[proto];
18837 +}
18838 +
18839 +const char *
18840 +gr_socktype_to_name(unsigned char type)
18841 +{
18842 +       return gr_socktypes[type];
18843 +}
18844 +
18845 +int
18846 +gr_search_socket(const int domain, const int type, const int protocol)
18847 +{
18848 +       struct acl_subject_label *curr;
18849 +
18850 +       if (unlikely(!gr_acl_is_enabled()))
18851 +               goto exit;
18852 +
18853 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
18854 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
18855 +               goto exit;      // let the kernel handle it
18856 +
18857 +       curr = current->acl;
18858 +
18859 +       if (!curr->ips)
18860 +               goto exit;
18861 +
18862 +       if ((curr->ip_type & (1 << type)) &&
18863 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
18864 +               goto exit;
18865 +
18866 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
18867 +               /* we don't place acls on raw sockets , and sometimes
18868 +                  dgram/ip sockets are opened for ioctl and not
18869 +                  bind/connect, so we'll fake a bind learn log */
18870 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
18871 +                       __u32 fakeip = 0;
18872 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
18873 +                                      current->role->roletype, current->uid,
18874 +                                      current->gid, current->exec_file ?
18875 +                                      gr_to_filename(current->exec_file->f_dentry,
18876 +                                      current->exec_file->f_vfsmnt) :
18877 +                                      curr->filename, curr->filename,
18878 +                                      NIPQUAD(fakeip), 0, type,
18879 +                                      protocol, GR_CONNECT, 
18880 +NIPQUAD(current->signal->curr_ip));
18881 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
18882 +                       __u32 fakeip = 0;
18883 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
18884 +                                      current->role->roletype, current->uid,
18885 +                                      current->gid, current->exec_file ?
18886 +                                      gr_to_filename(current->exec_file->f_dentry,
18887 +                                      current->exec_file->f_vfsmnt) :
18888 +                                      curr->filename, curr->filename,
18889 +                                      NIPQUAD(fakeip), 0, type,
18890 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
18891 +               }
18892 +               /* we'll log when they use connect or bind */
18893 +               goto exit;
18894 +       }
18895 +
18896 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
18897 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
18898 +
18899 +       return 0;
18900 +      exit:
18901 +       return 1;
18902 +}
18903 +
18904 +int check_ip_policy(struct acl_ip_label *ip, __u32 ip_addr, __u16 ip_port, __u8 protocol, const int mode, const int type, __u32 our_addr, __u32 our_netmask)
18905 +{
18906 +       if ((ip->mode & mode) &&
18907 +           (ip_port >= ip->low) &&
18908 +           (ip_port <= ip->high) &&
18909 +           ((ntohl(ip_addr) & our_netmask) ==
18910 +            (ntohl(our_addr) & our_netmask))
18911 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
18912 +           && (ip->type & (1 << type))) {
18913 +               if (ip->mode & GR_INVERT)
18914 +                       return 2; // specifically denied
18915 +               else
18916 +                       return 1; // allowed
18917 +       }
18918 +
18919 +       return 0; // not specifically allowed, may continue parsing
18920 +}
18921 +
18922 +static int
18923 +gr_search_connectbind(const int mode, const struct sock *sk,
18924 +                     const struct sockaddr_in *addr, const int type)
18925 +{
18926 +       char iface[IFNAMSIZ] = {0};
18927 +       struct acl_subject_label *curr;
18928 +       struct acl_ip_label *ip;
18929 +       struct net_device *dev;
18930 +       struct in_device *idev;
18931 +       unsigned long i;
18932 +       int ret;
18933 +       __u32 ip_addr = 0;
18934 +       __u32 our_addr;
18935 +       __u32 our_netmask;
18936 +       char *p;
18937 +       __u16 ip_port = 0;
18938 +
18939 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
18940 +               return 1;
18941 +
18942 +       curr = current->acl;
18943 +
18944 +       if (!curr->ips)
18945 +               return 1;
18946 +
18947 +       ip_addr = addr->sin_addr.s_addr;
18948 +       ip_port = ntohs(addr->sin_port);
18949 +
18950 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
18951 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
18952 +                              current->role->roletype, current->uid,
18953 +                              current->gid, current->exec_file ?
18954 +                              gr_to_filename(current->exec_file->f_dentry,
18955 +                              current->exec_file->f_vfsmnt) :
18956 +                              curr->filename, curr->filename,
18957 +                              NIPQUAD(ip_addr), ip_port, type,
18958 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
18959 +               return 1;
18960 +       }
18961 +
18962 +       for (i = 0; i < curr->ip_num; i++) {
18963 +               ip = *(curr->ips + i);
18964 +               if (ip->iface != NULL) {
18965 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
18966 +                       p = strchr(iface, ':');
18967 +                       if (p != NULL)
18968 +                               *p = '\0';
18969 +                       dev = dev_get_by_name(iface);
18970 +                       if (dev == NULL)
18971 +                               continue;
18972 +                       idev = in_dev_get(dev);
18973 +                       if (idev == NULL) {
18974 +                               dev_put(dev);
18975 +                               continue;
18976 +                       }
18977 +                       rcu_read_lock();
18978 +                       for_ifa(idev) {
18979 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
18980 +                                       our_addr = ifa->ifa_address;
18981 +                                       our_netmask = 0xffffffff;
18982 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
18983 +                                       if (ret == 1) {
18984 +                                               rcu_read_unlock();
18985 +                                               in_dev_put(idev);
18986 +                                               dev_put(dev);
18987 +                                               return 1;
18988 +                                       } else if (ret == 2) {
18989 +                                               rcu_read_unlock();
18990 +                                               in_dev_put(idev);
18991 +                                               dev_put(dev);
18992 +                                               goto denied;
18993 +                                       }
18994 +                               }
18995 +                       } endfor_ifa(idev);
18996 +                       rcu_read_unlock();
18997 +                       in_dev_put(idev);
18998 +                       dev_put(dev);
18999 +               } else {
19000 +                       our_addr = ip->addr;
19001 +                       our_netmask = ip->netmask;
19002 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
19003 +                       if (ret == 1)
19004 +                               return 1;
19005 +                       else if (ret == 2)
19006 +                               goto denied;
19007 +               }
19008 +       }
19009 +
19010 +denied:
19011 +       if (mode == GR_BIND)
19012 +               gr_log_int5_str2(GR_DONT_AUDIT, GR_BIND_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
19013 +       else if (mode == GR_CONNECT)
19014 +               gr_log_int5_str2(GR_DONT_AUDIT, GR_CONNECT_ACL_MSG, NIPQUAD(ip_addr), ip_port, gr_socktype_to_name(type), gr_proto_to_name(sk->sk_protocol));
19015 +
19016 +       return 0;
19017 +}
19018 +
19019 +int
19020 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
19021 +{
19022 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
19023 +}
19024 +
19025 +int
19026 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
19027 +{
19028 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
19029 +}
19030 +
19031 +int gr_search_listen(const struct socket *sock)
19032 +{
19033 +       struct sock *sk = sock->sk;
19034 +       struct sockaddr_in addr;
19035 +
19036 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
19037 +       addr.sin_port = inet_sk(sk)->sport;
19038 +
19039 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
19040 +}
19041 +
19042 +int gr_search_accept(const struct socket *sock)
19043 +{
19044 +       struct sock *sk = sock->sk;
19045 +       struct sockaddr_in addr;
19046 +
19047 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
19048 +       addr.sin_port = inet_sk(sk)->sport;
19049 +
19050 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
19051 +}
19052 +
19053 +int
19054 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
19055 +{
19056 +       if (addr)
19057 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
19058 +       else {
19059 +               struct sockaddr_in sin;
19060 +               const struct inet_sock *inet = inet_sk(sk);
19061 +
19062 +               sin.sin_addr.s_addr = inet->daddr;
19063 +               sin.sin_port = inet->dport;
19064 +
19065 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
19066 +       }
19067 +}
19068 +
19069 +int
19070 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
19071 +{
19072 +       struct sockaddr_in sin;
19073 +
19074 +       if (unlikely(skb->len < sizeof (struct udphdr)))
19075 +               return 1;       // skip this packet
19076 +
19077 +       sin.sin_addr.s_addr = skb->nh.iph->saddr;
19078 +       sin.sin_port = skb->h.uh->source;
19079 +
19080 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
19081 +}
19082 diff -urNp linux-2.6.20.3/grsecurity/gracl_learn.c linux-2.6.20.3/grsecurity/gracl_learn.c
19083 --- linux-2.6.20.3/grsecurity/gracl_learn.c     1969-12-31 19:00:00.000000000 -0500
19084 +++ linux-2.6.20.3/grsecurity/gracl_learn.c     2007-03-23 08:11:31.000000000 -0400
19085 @@ -0,0 +1,211 @@
19086 +#include <linux/kernel.h>
19087 +#include <linux/mm.h>
19088 +#include <linux/sched.h>
19089 +#include <linux/poll.h>
19090 +#include <linux/smp_lock.h>
19091 +#include <linux/string.h>
19092 +#include <linux/file.h>
19093 +#include <linux/types.h>
19094 +#include <linux/vmalloc.h>
19095 +#include <linux/grinternal.h>
19096 +
19097 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
19098 +                                  size_t count, loff_t *ppos);
19099 +extern int gr_acl_is_enabled(void);
19100 +
19101 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
19102 +static int gr_learn_attached;
19103 +
19104 +/* use a 512k buffer */
19105 +#define LEARN_BUFFER_SIZE (512 * 1024)
19106 +
19107 +static spinlock_t gr_learn_lock = SPIN_LOCK_UNLOCKED;
19108 +static DECLARE_MUTEX(gr_learn_user_sem);
19109 +
19110 +/* we need to maintain two buffers, so that the kernel context of grlearn
19111 +   uses a semaphore around the userspace copying, and the other kernel contexts
19112 +   use a spinlock when copying into the buffer, since they cannot sleep
19113 +*/
19114 +static char *learn_buffer;
19115 +static char *learn_buffer_user;
19116 +static int learn_buffer_len;
19117 +static int learn_buffer_user_len;
19118 +
19119 +static ssize_t
19120 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
19121 +{
19122 +       DECLARE_WAITQUEUE(wait, current);
19123 +       ssize_t retval = 0;
19124 +
19125 +       add_wait_queue(&learn_wait, &wait);
19126 +       set_current_state(TASK_INTERRUPTIBLE);
19127 +       do {
19128 +               down(&gr_learn_user_sem);
19129 +               spin_lock(&gr_learn_lock);
19130 +               if (learn_buffer_len)
19131 +                       break;
19132 +               spin_unlock(&gr_learn_lock);
19133 +               up(&gr_learn_user_sem);
19134 +               if (file->f_flags & O_NONBLOCK) {
19135 +                       retval = -EAGAIN;
19136 +                       goto out;
19137 +               }
19138 +               if (signal_pending(current)) {
19139 +                       retval = -ERESTARTSYS;
19140 +                       goto out;
19141 +               }
19142 +
19143 +               schedule();
19144 +       } while (1);
19145 +
19146 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
19147 +       learn_buffer_user_len = learn_buffer_len;
19148 +       retval = learn_buffer_len;
19149 +       learn_buffer_len = 0;
19150 +
19151 +       spin_unlock(&gr_learn_lock);
19152 +
19153 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
19154 +               retval = -EFAULT;
19155 +
19156 +       up(&gr_learn_user_sem);
19157 +out:
19158 +       set_current_state(TASK_RUNNING);
19159 +       remove_wait_queue(&learn_wait, &wait);
19160 +       return retval;
19161 +}
19162 +
19163 +static unsigned int
19164 +poll_learn(struct file * file, poll_table * wait)
19165 +{
19166 +       poll_wait(file, &learn_wait, wait);
19167 +
19168 +       if (learn_buffer_len)
19169 +               return (POLLIN | POLLRDNORM);
19170 +
19171 +       return 0;
19172 +}
19173 +
19174 +void
19175 +gr_clear_learn_entries(void)
19176 +{
19177 +       char *tmp;
19178 +
19179 +       down(&gr_learn_user_sem);
19180 +       if (learn_buffer != NULL) {
19181 +               spin_lock(&gr_learn_lock);
19182 +               tmp = learn_buffer;
19183 +               learn_buffer = NULL;
19184 +               spin_unlock(&gr_learn_lock);
19185 +               vfree(learn_buffer);
19186 +       }
19187 +       if (learn_buffer_user != NULL) {
19188 +               vfree(learn_buffer_user);
19189 +               learn_buffer_user = NULL;
19190 +       }
19191 +       learn_buffer_len = 0;
19192 +       up(&gr_learn_user_sem);
19193 +
19194 +       return;
19195 +}
19196 +
19197 +void
19198 +gr_add_learn_entry(const char *fmt, ...)
19199 +{
19200 +       va_list args;
19201 +       unsigned int len;
19202 +
19203 +       if (!gr_learn_attached)
19204 +               return;
19205 +
19206 +       spin_lock(&gr_learn_lock);
19207 +
19208 +       /* leave a gap at the end so we know when it's "full" but don't have to
19209 +          compute the exact length of the string we're trying to append
19210 +       */
19211 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
19212 +               spin_unlock(&gr_learn_lock);
19213 +               wake_up_interruptible(&learn_wait);
19214 +               return;
19215 +       }
19216 +       if (learn_buffer == NULL) {
19217 +               spin_unlock(&gr_learn_lock);
19218 +               return;
19219 +       }
19220 +
19221 +       va_start(args, fmt);
19222 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
19223 +       va_end(args);
19224 +
19225 +       learn_buffer_len += len + 1;
19226 +
19227 +       spin_unlock(&gr_learn_lock);
19228 +       wake_up_interruptible(&learn_wait);
19229 +
19230 +       return;
19231 +}
19232 +
19233 +static int
19234 +open_learn(struct inode *inode, struct file *file)
19235 +{
19236 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
19237 +               return -EBUSY;
19238 +       if (file->f_mode & FMODE_READ) {
19239 +               int retval = 0;
19240 +               down(&gr_learn_user_sem);
19241 +               if (learn_buffer == NULL)
19242 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
19243 +               if (learn_buffer_user == NULL)
19244 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
19245 +               if (learn_buffer == NULL) {
19246 +                       retval = -ENOMEM;
19247 +                       goto out_error;
19248 +               }
19249 +               if (learn_buffer_user == NULL) {
19250 +                       retval = -ENOMEM;
19251 +                       goto out_error;
19252 +               }
19253 +               learn_buffer_len = 0;
19254 +               learn_buffer_user_len = 0;
19255 +               gr_learn_attached = 1;
19256 +out_error:
19257 +               up(&gr_learn_user_sem);
19258 +               return retval;
19259 +       }
19260 +       return 0;
19261 +}
19262 +
19263 +static int
19264 +close_learn(struct inode *inode, struct file *file)
19265 +{
19266 +       char *tmp;
19267 +
19268 +       if (file->f_mode & FMODE_READ) {
19269 +               down(&gr_learn_user_sem);
19270 +               if (learn_buffer != NULL) {
19271 +                       spin_lock(&gr_learn_lock);
19272 +                       tmp = learn_buffer;
19273 +                       learn_buffer = NULL;
19274 +                       spin_unlock(&gr_learn_lock);
19275 +                       vfree(tmp);
19276 +               }
19277 +               if (learn_buffer_user != NULL) {
19278 +                       vfree(learn_buffer_user);
19279 +                       learn_buffer_user = NULL;
19280 +               }
19281 +               learn_buffer_len = 0;
19282 +               learn_buffer_user_len = 0;
19283 +               gr_learn_attached = 0;
19284 +               up(&gr_learn_user_sem);
19285 +       }
19286 +
19287 +       return 0;
19288 +}
19289 +               
19290 +struct file_operations grsec_fops = {
19291 +       .read           = read_learn,
19292 +       .write          = write_grsec_handler,
19293 +       .open           = open_learn,
19294 +       .release        = close_learn,
19295 +       .poll           = poll_learn,
19296 +};
19297 diff -urNp linux-2.6.20.3/grsecurity/gracl_res.c linux-2.6.20.3/grsecurity/gracl_res.c
19298 --- linux-2.6.20.3/grsecurity/gracl_res.c       1969-12-31 19:00:00.000000000 -0500
19299 +++ linux-2.6.20.3/grsecurity/gracl_res.c       2007-03-23 08:11:31.000000000 -0400
19300 @@ -0,0 +1,45 @@
19301 +#include <linux/kernel.h>
19302 +#include <linux/sched.h>
19303 +#include <linux/gracl.h>
19304 +#include <linux/grinternal.h>
19305 +
19306 +static const char *restab_log[] = {
19307 +       [RLIMIT_CPU] = "RLIMIT_CPU",
19308 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
19309 +       [RLIMIT_DATA] = "RLIMIT_DATA",
19310 +       [RLIMIT_STACK] = "RLIMIT_STACK",
19311 +       [RLIMIT_CORE] = "RLIMIT_CORE",
19312 +       [RLIMIT_RSS] = "RLIMIT_RSS",
19313 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
19314 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
19315 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
19316 +       [RLIMIT_AS] = "RLIMIT_AS",
19317 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
19318 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
19319 +};
19320 +
19321 +void
19322 +gr_log_resource(const struct task_struct *task,
19323 +               const int res, const unsigned long wanted, const int gt)
19324 +{
19325 +       if (res == RLIMIT_NPROC && 
19326 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
19327 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
19328 +               return;
19329 +       else if (res == RLIMIT_MEMLOCK &&
19330 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
19331 +               return;
19332 +
19333 +       if (!gr_acl_is_enabled() && !grsec_resource_logging)
19334 +               return;
19335 +
19336 +       preempt_disable();
19337 +
19338 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
19339 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
19340 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
19341 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
19342 +       preempt_enable_no_resched();
19343 +
19344 +       return;
19345 +}
19346 diff -urNp linux-2.6.20.3/grsecurity/gracl_segv.c linux-2.6.20.3/grsecurity/gracl_segv.c
19347 --- linux-2.6.20.3/grsecurity/gracl_segv.c      1969-12-31 19:00:00.000000000 -0500
19348 +++ linux-2.6.20.3/grsecurity/gracl_segv.c      2007-03-23 08:11:31.000000000 -0400
19349 @@ -0,0 +1,295 @@
19350 +#include <linux/kernel.h>
19351 +#include <linux/mm.h>
19352 +#include <asm/uaccess.h>
19353 +#include <asm/errno.h>
19354 +#include <asm/mman.h>
19355 +#include <net/sock.h>
19356 +#include <linux/file.h>
19357 +#include <linux/fs.h>
19358 +#include <linux/net.h>
19359 +#include <linux/in.h>
19360 +#include <linux/smp_lock.h>
19361 +#include <linux/slab.h>
19362 +#include <linux/types.h>
19363 +#include <linux/sched.h>
19364 +#include <linux/timer.h>
19365 +#include <linux/gracl.h>
19366 +#include <linux/grsecurity.h>
19367 +#include <linux/grinternal.h>
19368 +
19369 +static struct crash_uid *uid_set;
19370 +static unsigned short uid_used;
19371 +static spinlock_t gr_uid_lock = SPIN_LOCK_UNLOCKED;
19372 +extern rwlock_t gr_inode_lock;
19373 +extern struct acl_subject_label *
19374 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
19375 +                             struct acl_role_label *role);
19376 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
19377 +
19378 +int
19379 +gr_init_uidset(void)
19380 +{
19381 +       uid_set =
19382 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
19383 +       uid_used = 0;
19384 +
19385 +       return uid_set ? 1 : 0;
19386 +}
19387 +
19388 +void
19389 +gr_free_uidset(void)
19390 +{
19391 +       if (uid_set)
19392 +               kfree(uid_set);
19393 +
19394 +       return;
19395 +}
19396 +
19397 +int
19398 +gr_find_uid(const uid_t uid)
19399 +{
19400 +       struct crash_uid *tmp = uid_set;
19401 +       uid_t buid;
19402 +       int low = 0, high = uid_used - 1, mid;
19403 +
19404 +       while (high >= low) {
19405 +               mid = (low + high) >> 1;
19406 +               buid = tmp[mid].uid;
19407 +               if (buid == uid)
19408 +                       return mid;
19409 +               if (buid > uid)
19410 +                       high = mid - 1;
19411 +               if (buid < uid)
19412 +                       low = mid + 1;
19413 +       }
19414 +
19415 +       return -1;
19416 +}
19417 +
19418 +static __inline__ void
19419 +gr_insertsort(void)
19420 +{
19421 +       unsigned short i, j;
19422 +       struct crash_uid index;
19423 +
19424 +       for (i = 1; i < uid_used; i++) {
19425 +               index = uid_set[i];
19426 +               j = i;
19427 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
19428 +                       uid_set[j] = uid_set[j - 1];
19429 +                       j--;
19430 +               }
19431 +               uid_set[j] = index;
19432 +       }
19433 +
19434 +       return;
19435 +}
19436 +
19437 +static __inline__ void
19438 +gr_insert_uid(const uid_t uid, const unsigned long expires)
19439 +{
19440 +       int loc;
19441 +
19442 +       if (uid_used == GR_UIDTABLE_MAX)
19443 +               return;
19444 +
19445 +       loc = gr_find_uid(uid);
19446 +
19447 +       if (loc >= 0) {
19448 +               uid_set[loc].expires = expires;
19449 +               return;
19450 +       }
19451 +
19452 +       uid_set[uid_used].uid = uid;
19453 +       uid_set[uid_used].expires = expires;
19454 +       uid_used++;
19455 +
19456 +       gr_insertsort();
19457 +
19458 +       return;
19459 +}
19460 +
19461 +void
19462 +gr_remove_uid(const unsigned short loc)
19463 +{
19464 +       unsigned short i;
19465 +
19466 +       for (i = loc + 1; i < uid_used; i++)
19467 +               uid_set[i - 1] = uid_set[i];
19468 +
19469 +       uid_used--;
19470 +
19471 +       return;
19472 +}
19473 +
19474 +int
19475 +gr_check_crash_uid(const uid_t uid)
19476 +{
19477 +       int loc;
19478 +       int ret = 0;
19479 +
19480 +       if (unlikely(!gr_acl_is_enabled()))
19481 +               return 0;
19482 +
19483 +       spin_lock(&gr_uid_lock);
19484 +       loc = gr_find_uid(uid);
19485 +
19486 +       if (loc < 0)
19487 +               goto out_unlock;
19488 +
19489 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
19490 +               gr_remove_uid(loc);
19491 +       else
19492 +               ret = 1;
19493 +
19494 +out_unlock:
19495 +       spin_unlock(&gr_uid_lock);
19496 +       return ret;
19497 +}
19498 +
19499 +static __inline__ int
19500 +proc_is_setxid(const struct task_struct *task)
19501 +{
19502 +       if (task->uid != task->euid || task->uid != task->suid ||
19503 +           task->uid != task->fsuid)
19504 +               return 1;
19505 +       if (task->gid != task->egid || task->gid != task->sgid ||
19506 +           task->gid != task->fsgid)
19507 +               return 1;
19508 +
19509 +       return 0;
19510 +}
19511 +static __inline__ int
19512 +gr_fake_force_sig(int sig, struct task_struct *t)
19513 +{
19514 +       unsigned long int flags;
19515 +       int ret;
19516 +
19517 +       spin_lock_irqsave(&t->sighand->siglock, flags);
19518 +       if (sigismember(&t->blocked, sig) || t->sighand->action[sig-1].sa.sa_handler == SIG_IGN) {
19519 +               t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
19520 +               sigdelset(&t->blocked, sig);
19521 +               recalc_sigpending_tsk(t);
19522 +       }
19523 +       ret = specific_send_sig_info(sig, (void*)1L, t);
19524 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
19525 +
19526 +       return ret;
19527 +}
19528 +
19529 +void
19530 +gr_handle_crash(struct task_struct *task, const int sig)
19531 +{
19532 +       struct acl_subject_label *curr;
19533 +       struct acl_subject_label *curr2;
19534 +       struct task_struct *tsk, *tsk2;
19535 +
19536 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
19537 +               return;
19538 +
19539 +       if (unlikely(!gr_acl_is_enabled()))
19540 +               return;
19541 +
19542 +       curr = task->acl;
19543 +
19544 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
19545 +               return;
19546 +
19547 +       if (time_before_eq(curr->expires, get_seconds())) {
19548 +               curr->expires = 0;
19549 +               curr->crashes = 0;
19550 +       }
19551 +
19552 +       curr->crashes++;
19553 +
19554 +       if (!curr->expires)
19555 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
19556 +
19557 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
19558 +           time_after(curr->expires, get_seconds())) {
19559 +               if (task->uid && proc_is_setxid(task)) {
19560 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
19561 +                       spin_lock(&gr_uid_lock);
19562 +                       gr_insert_uid(task->uid, curr->expires);
19563 +                       spin_unlock(&gr_uid_lock);
19564 +                       curr->expires = 0;
19565 +                       curr->crashes = 0;
19566 +                       read_lock(&tasklist_lock);
19567 +                       do_each_thread(tsk2, tsk) {
19568 +                               if (tsk != task && tsk->uid == task->uid)
19569 +                                       gr_fake_force_sig(SIGKILL, tsk);
19570 +                       } while_each_thread(tsk2, tsk);
19571 +                       read_unlock(&tasklist_lock);
19572 +               } else {
19573 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
19574 +                       read_lock(&tasklist_lock);
19575 +                       do_each_thread(tsk2, tsk) {
19576 +                               if (likely(tsk != task)) {
19577 +                                       curr2 = tsk->acl;
19578 +
19579 +                                       if (curr2->device == curr->device &&
19580 +                                           curr2->inode == curr->inode)
19581 +                                               gr_fake_force_sig(SIGKILL, tsk);
19582 +                               }
19583 +                       } while_each_thread(tsk2, tsk);
19584 +                       read_unlock(&tasklist_lock);
19585 +               }
19586 +       }
19587 +
19588 +       return;
19589 +}
19590 +
19591 +int
19592 +gr_check_crash_exec(const struct file *filp)
19593 +{
19594 +       struct acl_subject_label *curr;
19595 +
19596 +       if (unlikely(!gr_acl_is_enabled()))
19597 +               return 0;
19598 +
19599 +       read_lock(&gr_inode_lock);
19600 +       curr = lookup_acl_subj_label(filp->f_dentry->d_inode->i_ino,
19601 +                                    filp->f_dentry->d_inode->i_sb->s_dev,
19602 +                                    current->role);
19603 +       read_unlock(&gr_inode_lock);
19604 +
19605 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
19606 +           (!curr->crashes && !curr->expires))
19607 +               return 0;
19608 +
19609 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
19610 +           time_after(curr->expires, get_seconds()))
19611 +               return 1;
19612 +       else if (time_before_eq(curr->expires, get_seconds())) {
19613 +               curr->crashes = 0;
19614 +               curr->expires = 0;
19615 +       }
19616 +
19617 +       return 0;
19618 +}
19619 +
19620 +void
19621 +gr_handle_alertkill(struct task_struct *task)
19622 +{
19623 +       struct acl_subject_label *curracl;
19624 +       __u32 curr_ip;
19625 +       struct task_struct *p, *p2;
19626 +
19627 +       if (unlikely(!gr_acl_is_enabled()))
19628 +               return;
19629 +
19630 +       curracl = task->acl;
19631 +       curr_ip = task->signal->curr_ip;
19632 +
19633 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
19634 +               read_lock(&tasklist_lock);
19635 +               do_each_thread(p2, p) {
19636 +                       if (p->signal->curr_ip == curr_ip)
19637 +                               gr_fake_force_sig(SIGKILL, p);
19638 +               } while_each_thread(p2, p);
19639 +               read_unlock(&tasklist_lock);
19640 +       } else if (curracl->mode & GR_KILLPROC)
19641 +               gr_fake_force_sig(SIGKILL, task);
19642 +
19643 +       return;
19644 +}
19645 diff -urNp linux-2.6.20.3/grsecurity/gracl_shm.c linux-2.6.20.3/grsecurity/gracl_shm.c
19646 --- linux-2.6.20.3/grsecurity/gracl_shm.c       1969-12-31 19:00:00.000000000 -0500
19647 +++ linux-2.6.20.3/grsecurity/gracl_shm.c       2007-03-23 08:11:31.000000000 -0400
19648 @@ -0,0 +1,33 @@
19649 +#include <linux/kernel.h>
19650 +#include <linux/mm.h>
19651 +#include <linux/sched.h>
19652 +#include <linux/file.h>
19653 +#include <linux/ipc.h>
19654 +#include <linux/gracl.h>
19655 +#include <linux/grsecurity.h>
19656 +#include <linux/grinternal.h>
19657 +
19658 +int
19659 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19660 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
19661 +{
19662 +       struct task_struct *task;
19663 +
19664 +       if (!gr_acl_is_enabled())
19665 +               return 1;
19666 +
19667 +       task = find_task_by_pid(shm_cprid);
19668 +
19669 +       if (unlikely(!task))
19670 +               task = find_task_by_pid(shm_lapid);
19671 +
19672 +       if (unlikely(task && (time_before((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
19673 +                             (task->pid == shm_lapid)) &&
19674 +                    (task->acl->mode & GR_PROTSHM) &&
19675 +                    (task->acl != current->acl))) {
19676 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
19677 +               return 0;
19678 +       }
19679 +
19680 +       return 1;
19681 +}
19682 diff -urNp linux-2.6.20.3/grsecurity/grsec_chdir.c linux-2.6.20.3/grsecurity/grsec_chdir.c
19683 --- linux-2.6.20.3/grsecurity/grsec_chdir.c     1969-12-31 19:00:00.000000000 -0500
19684 +++ linux-2.6.20.3/grsecurity/grsec_chdir.c     2007-03-23 08:11:31.000000000 -0400
19685 @@ -0,0 +1,19 @@
19686 +#include <linux/kernel.h>
19687 +#include <linux/sched.h>
19688 +#include <linux/fs.h>
19689 +#include <linux/file.h>
19690 +#include <linux/grsecurity.h>
19691 +#include <linux/grinternal.h>
19692 +
19693 +void
19694 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
19695 +{
19696 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
19697 +       if ((grsec_enable_chdir && grsec_enable_group &&
19698 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
19699 +                                             !grsec_enable_group)) {
19700 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
19701 +       }
19702 +#endif
19703 +       return;
19704 +}
19705 diff -urNp linux-2.6.20.3/grsecurity/grsec_chroot.c linux-2.6.20.3/grsecurity/grsec_chroot.c
19706 --- linux-2.6.20.3/grsecurity/grsec_chroot.c    1969-12-31 19:00:00.000000000 -0500
19707 +++ linux-2.6.20.3/grsecurity/grsec_chroot.c    2007-03-23 08:11:31.000000000 -0400
19708 @@ -0,0 +1,335 @@
19709 +#include <linux/kernel.h>
19710 +#include <linux/module.h>
19711 +#include <linux/sched.h>
19712 +#include <linux/file.h>
19713 +#include <linux/fs.h>
19714 +#include <linux/mount.h>
19715 +#include <linux/types.h>
19716 +#include <linux/pid_namespace.h>
19717 +#include <linux/grsecurity.h>
19718 +#include <linux/grinternal.h>
19719 +
19720 +int
19721 +gr_handle_chroot_unix(const pid_t pid)
19722 +{
19723 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
19724 +       struct pid *spid = NULL;
19725 +
19726 +       if (unlikely(!grsec_enable_chroot_unix))
19727 +               return 1;
19728 +
19729 +       if (likely(!proc_is_chrooted(current)))
19730 +               return 1;
19731 +
19732 +       read_lock(&tasklist_lock);
19733 +
19734 +       spid = find_pid(pid);
19735 +       if (spid) {
19736 +               struct task_struct *p;
19737 +               p = pid_task(spid, PIDTYPE_PID);
19738 +               task_lock(p);
19739 +               if (unlikely(!have_same_root(current, p))) {
19740 +                       task_unlock(p);
19741 +                       read_unlock(&tasklist_lock);
19742 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
19743 +                       return 0;
19744 +               }
19745 +               task_unlock(p);
19746 +       }
19747 +       read_unlock(&tasklist_lock);
19748 +#endif
19749 +       return 1;
19750 +}
19751 +
19752 +int
19753 +gr_handle_chroot_nice(void)
19754 +{
19755 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
19756 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
19757 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
19758 +               return -EPERM;
19759 +       }
19760 +#endif
19761 +       return 0;
19762 +}
19763 +
19764 +int
19765 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
19766 +{
19767 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
19768 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
19769 +                       && proc_is_chrooted(current)) {
19770 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
19771 +               return -EACCES;
19772 +       }
19773 +#endif
19774 +       return 0;
19775 +}
19776 +
19777 +int
19778 +gr_handle_chroot_rawio(const struct inode *inode)
19779 +{
19780 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
19781 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
19782 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
19783 +               return 1;
19784 +#endif
19785 +       return 0;
19786 +}
19787 +
19788 +int
19789 +gr_pid_is_chrooted(struct task_struct *p)
19790 +{
19791 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
19792 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
19793 +               return 0;
19794 +
19795 +       task_lock(p);
19796 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
19797 +           !have_same_root(current, p)) {
19798 +               task_unlock(p);
19799 +               return 1;
19800 +       }
19801 +       task_unlock(p);
19802 +#endif
19803 +       return 0;
19804 +}
19805 +
19806 +EXPORT_SYMBOL(gr_pid_is_chrooted);
19807 +
19808 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
19809 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
19810 +{
19811 +       struct dentry *dentry = (struct dentry *)u_dentry;
19812 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
19813 +       struct dentry *realroot;
19814 +       struct vfsmount *realrootmnt;
19815 +       struct dentry *currentroot;
19816 +       struct vfsmount *currentmnt;
19817 +       struct task_struct *reaper = child_reaper(current);
19818 +       int ret = 1;
19819 +
19820 +       read_lock(&reaper->fs->lock);
19821 +       realrootmnt = mntget(reaper->fs->rootmnt);
19822 +       realroot = dget(reaper->fs->root);
19823 +       read_unlock(&reaper->fs->lock);
19824 +
19825 +       read_lock(&current->fs->lock);
19826 +       currentmnt = mntget(current->fs->rootmnt);
19827 +       currentroot = dget(current->fs->root);
19828 +       read_unlock(&current->fs->lock);
19829 +
19830 +       spin_lock(&dcache_lock);
19831 +       for (;;) {
19832 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
19833 +                    || (dentry == currentroot && mnt == currentmnt)))
19834 +                       break;
19835 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
19836 +                       if (mnt->mnt_parent == mnt)
19837 +                               break;
19838 +                       dentry = mnt->mnt_mountpoint;
19839 +                       mnt = mnt->mnt_parent;
19840 +                       continue;
19841 +               }
19842 +               dentry = dentry->d_parent;
19843 +       }
19844 +       spin_unlock(&dcache_lock);
19845 +
19846 +       dput(currentroot);
19847 +       mntput(currentmnt);
19848 +
19849 +       /* access is outside of chroot */
19850 +       if (dentry == realroot && mnt == realrootmnt)
19851 +               ret = 0;
19852 +
19853 +       dput(realroot);
19854 +       mntput(realrootmnt);
19855 +       return ret;
19856 +}
19857 +#endif
19858 +
19859 +int
19860 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
19861 +{
19862 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
19863 +       if (!grsec_enable_chroot_fchdir)
19864 +               return 1;
19865 +
19866 +       if (!proc_is_chrooted(current))
19867 +               return 1;
19868 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
19869 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
19870 +               return 0;
19871 +       }
19872 +#endif
19873 +       return 1;
19874 +}
19875 +
19876 +int
19877 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
19878 +               const time_t shm_createtime)
19879 +{
19880 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
19881 +       struct pid *pid = NULL;
19882 +       time_t starttime;
19883 +
19884 +       if (unlikely(!grsec_enable_chroot_shmat))
19885 +               return 1;
19886 +
19887 +       if (likely(!proc_is_chrooted(current)))
19888 +               return 1;
19889 +
19890 +       read_lock(&tasklist_lock);
19891 +
19892 +       pid = find_pid(shm_cprid);
19893 +       if (pid) {
19894 +               struct task_struct *p;
19895 +               p = pid_task(pid, PIDTYPE_PID);
19896 +               task_lock(p);
19897 +               starttime = p->start_time.tv_sec;
19898 +               if (unlikely(!have_same_root(current, p) &&
19899 +                            time_before((unsigned long)starttime, (unsigned long)shm_createtime))) {
19900 +                       task_unlock(p);
19901 +                       read_unlock(&tasklist_lock);
19902 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
19903 +                       return 0;
19904 +               }
19905 +               task_unlock(p);
19906 +       } else {
19907 +               pid = find_pid(shm_lapid);
19908 +               if (pid) {
19909 +                       struct task_struct *p;
19910 +                       p = pid_task(pid, PIDTYPE_PID);
19911 +                       task_lock(p);
19912 +                       if (unlikely(!have_same_root(current, p))) {
19913 +                               task_unlock(p);
19914 +                               read_unlock(&tasklist_lock);
19915 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
19916 +                               return 0;
19917 +                       }
19918 +                       task_unlock(p);
19919 +               }
19920 +       }
19921 +
19922 +       read_unlock(&tasklist_lock);
19923 +#endif
19924 +       return 1;
19925 +}
19926 +
19927 +void
19928 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
19929 +{
19930 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
19931 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
19932 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
19933 +#endif
19934 +       return;
19935 +}
19936 +
19937 +int
19938 +gr_handle_chroot_mknod(const struct dentry *dentry,
19939 +                      const struct vfsmount *mnt, const int mode)
19940 +{
19941 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
19942 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
19943 +           proc_is_chrooted(current)) {
19944 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
19945 +               return -EPERM;
19946 +       }
19947 +#endif
19948 +       return 0;
19949 +}
19950 +
19951 +int
19952 +gr_handle_chroot_mount(const struct dentry *dentry,
19953 +                      const struct vfsmount *mnt, const char *dev_name)
19954 +{
19955 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
19956 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
19957 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
19958 +               return -EPERM;
19959 +       }
19960 +#endif
19961 +       return 0;
19962 +}
19963 +
19964 +int
19965 +gr_handle_chroot_pivot(void)
19966 +{
19967 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
19968 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
19969 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
19970 +               return -EPERM;
19971 +       }
19972 +#endif
19973 +       return 0;
19974 +}
19975 +
19976 +int
19977 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
19978 +{
19979 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
19980 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
19981 +           !gr_is_outside_chroot(dentry, mnt)) {
19982 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
19983 +               return -EPERM;
19984 +       }
19985 +#endif
19986 +       return 0;
19987 +}
19988 +
19989 +void
19990 +gr_handle_chroot_caps(struct task_struct *task)
19991 +{
19992 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
19993 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
19994 +               task->cap_permitted =
19995 +                   cap_drop(task->cap_permitted, GR_CHROOT_CAPS);
19996 +               task->cap_inheritable =
19997 +                   cap_drop(task->cap_inheritable, GR_CHROOT_CAPS);
19998 +               task->cap_effective =
19999 +                   cap_drop(task->cap_effective, GR_CHROOT_CAPS);
20000 +       }
20001 +#endif
20002 +       return;
20003 +}
20004 +
20005 +int
20006 +gr_handle_chroot_sysctl(const int op)
20007 +{
20008 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
20009 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
20010 +           && (op & 002))
20011 +               return -EACCES;
20012 +#endif
20013 +       return 0;
20014 +}
20015 +
20016 +void
20017 +gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt)
20018 +{
20019 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
20020 +       if (grsec_enable_chroot_chdir)
20021 +               set_fs_pwd(current->fs, mnt, dentry);
20022 +#endif
20023 +       return;
20024 +}
20025 +
20026 +int
20027 +gr_handle_chroot_chmod(const struct dentry *dentry,
20028 +                      const struct vfsmount *mnt, const int mode)
20029 +{
20030 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
20031 +       if (grsec_enable_chroot_chmod &&
20032 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
20033 +           proc_is_chrooted(current)) {
20034 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
20035 +               return -EPERM;
20036 +       }
20037 +#endif
20038 +       return 0;
20039 +}
20040 +
20041 +#ifdef CONFIG_SECURITY
20042 +EXPORT_SYMBOL(gr_handle_chroot_caps);
20043 +#endif
20044 diff -urNp linux-2.6.20.3/grsecurity/grsec_disabled.c linux-2.6.20.3/grsecurity/grsec_disabled.c
20045 --- linux-2.6.20.3/grsecurity/grsec_disabled.c  1969-12-31 19:00:00.000000000 -0500
20046 +++ linux-2.6.20.3/grsecurity/grsec_disabled.c  2007-03-23 08:11:31.000000000 -0400
20047 @@ -0,0 +1,418 @@
20048 +#include <linux/kernel.h>
20049 +#include <linux/module.h>
20050 +#include <linux/sched.h>
20051 +#include <linux/file.h>
20052 +#include <linux/fs.h>
20053 +#include <linux/kdev_t.h>
20054 +#include <linux/net.h>
20055 +#include <linux/in.h>
20056 +#include <linux/ip.h>
20057 +#include <linux/skbuff.h>
20058 +#include <linux/sysctl.h>
20059 +
20060 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20061 +void
20062 +pax_set_initial_flags(struct linux_binprm *bprm)
20063 +{
20064 +       return;
20065 +}
20066 +#endif
20067 +
20068 +#ifdef CONFIG_SYSCTL
20069 +__u32
20070 +gr_handle_sysctl(const struct ctl_table * table, __u32 mode)
20071 +{
20072 +       return mode;
20073 +}
20074 +#endif
20075 +
20076 +int
20077 +gr_acl_is_enabled(void)
20078 +{
20079 +       return 0;
20080 +}
20081 +
20082 +int
20083 +gr_handle_rawio(const struct inode *inode)
20084 +{
20085 +       return 0;
20086 +}
20087 +
20088 +void
20089 +gr_acl_handle_psacct(struct task_struct *task, const long code)
20090 +{
20091 +       return;
20092 +}
20093 +
20094 +int
20095 +gr_handle_ptrace(struct task_struct *task, const long request)
20096 +{
20097 +       return 0;
20098 +}
20099 +
20100 +int
20101 +gr_handle_proc_ptrace(struct task_struct *task)
20102 +{
20103 +       return 0;
20104 +}
20105 +
20106 +void
20107 +gr_learn_resource(const struct task_struct *task,
20108 +                 const int res, const unsigned long wanted, const int gt)
20109 +{
20110 +       return;
20111 +}
20112 +
20113 +int
20114 +gr_set_acls(const int type)
20115 +{
20116 +       return 0;
20117 +}
20118 +
20119 +int
20120 +gr_check_hidden_task(const struct task_struct *tsk)
20121 +{
20122 +       return 0;
20123 +}
20124 +
20125 +int
20126 +gr_check_protected_task(const struct task_struct *task)
20127 +{
20128 +       return 0;
20129 +}
20130 +
20131 +void
20132 +gr_copy_label(struct task_struct *tsk)
20133 +{
20134 +       return;
20135 +}
20136 +
20137 +void
20138 +gr_set_pax_flags(struct task_struct *task)
20139 +{
20140 +       return;
20141 +}
20142 +
20143 +int
20144 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
20145 +{
20146 +       return 0;
20147 +}
20148 +
20149 +void
20150 +gr_handle_delete(const ino_t ino, const dev_t dev)
20151 +{
20152 +       return;
20153 +}
20154 +
20155 +void
20156 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
20157 +{
20158 +       return;
20159 +}
20160 +
20161 +void
20162 +gr_handle_crash(struct task_struct *task, const int sig)
20163 +{
20164 +       return;
20165 +}
20166 +
20167 +int
20168 +gr_check_crash_exec(const struct file *filp)
20169 +{
20170 +       return 0;
20171 +}
20172 +
20173 +int
20174 +gr_check_crash_uid(const uid_t uid)
20175 +{
20176 +       return 0;
20177 +}
20178 +
20179 +void
20180 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20181 +                struct dentry *old_dentry,
20182 +                struct dentry *new_dentry,
20183 +                struct vfsmount *mnt, const __u8 replace)
20184 +{
20185 +       return;
20186 +}
20187 +
20188 +int
20189 +gr_search_socket(const int family, const int type, const int protocol)
20190 +{
20191 +       return 1;
20192 +}
20193 +
20194 +int
20195 +gr_search_connectbind(const int mode, const struct socket *sock,
20196 +                     const struct sockaddr_in *addr)
20197 +{
20198 +       return 1;
20199 +}
20200 +
20201 +int
20202 +gr_task_is_capable(struct task_struct *task, const int cap)
20203 +{
20204 +       return 1;
20205 +}
20206 +
20207 +int
20208 +gr_is_capable_nolog(const int cap)
20209 +{
20210 +       return 1;
20211 +}
20212 +
20213 +void
20214 +gr_handle_alertkill(struct task_struct *task)
20215 +{
20216 +       return;
20217 +}
20218 +
20219 +__u32
20220 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
20221 +{
20222 +       return 1;
20223 +}
20224 +
20225 +__u32
20226 +gr_acl_handle_hidden_file(const struct dentry * dentry,
20227 +                         const struct vfsmount * mnt)
20228 +{
20229 +       return 1;
20230 +}
20231 +
20232 +__u32
20233 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
20234 +                  const int fmode)
20235 +{
20236 +       return 1;
20237 +}
20238 +
20239 +__u32
20240 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
20241 +{
20242 +       return 1;
20243 +}
20244 +
20245 +__u32
20246 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
20247 +{
20248 +       return 1;
20249 +}
20250 +
20251 +int
20252 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
20253 +                  unsigned int *vm_flags)
20254 +{
20255 +       return 1;
20256 +}
20257 +
20258 +__u32
20259 +gr_acl_handle_truncate(const struct dentry * dentry,
20260 +                      const struct vfsmount * mnt)
20261 +{
20262 +       return 1;
20263 +}
20264 +
20265 +__u32
20266 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
20267 +{
20268 +       return 1;
20269 +}
20270 +
20271 +__u32
20272 +gr_acl_handle_access(const struct dentry * dentry,
20273 +                    const struct vfsmount * mnt, const int fmode)
20274 +{
20275 +       return 1;
20276 +}
20277 +
20278 +__u32
20279 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
20280 +                    mode_t mode)
20281 +{
20282 +       return 1;
20283 +}
20284 +
20285 +__u32
20286 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
20287 +                   mode_t mode)
20288 +{
20289 +       return 1;
20290 +}
20291 +
20292 +__u32
20293 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
20294 +{
20295 +       return 1;
20296 +}
20297 +
20298 +void
20299 +grsecurity_init(void)
20300 +{
20301 +       return;
20302 +}
20303 +
20304 +__u32
20305 +gr_acl_handle_mknod(const struct dentry * new_dentry,
20306 +                   const struct dentry * parent_dentry,
20307 +                   const struct vfsmount * parent_mnt,
20308 +                   const int mode)
20309 +{
20310 +       return 1;
20311 +}
20312 +
20313 +__u32
20314 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
20315 +                   const struct dentry * parent_dentry,
20316 +                   const struct vfsmount * parent_mnt)
20317 +{
20318 +       return 1;
20319 +}
20320 +
20321 +__u32
20322 +gr_acl_handle_symlink(const struct dentry * new_dentry,
20323 +                     const struct dentry * parent_dentry,
20324 +                     const struct vfsmount * parent_mnt, const char *from)
20325 +{
20326 +       return 1;
20327 +}
20328 +
20329 +__u32
20330 +gr_acl_handle_link(const struct dentry * new_dentry,
20331 +                  const struct dentry * parent_dentry,
20332 +                  const struct vfsmount * parent_mnt,
20333 +                  const struct dentry * old_dentry,
20334 +                  const struct vfsmount * old_mnt, const char *to)
20335 +{
20336 +       return 1;
20337 +}
20338 +
20339 +int
20340 +gr_acl_handle_rename(const struct dentry *new_dentry,
20341 +                    const struct dentry *parent_dentry,
20342 +                    const struct vfsmount *parent_mnt,
20343 +                    const struct dentry *old_dentry,
20344 +                    const struct inode *old_parent_inode,
20345 +                    const struct vfsmount *old_mnt, const char *newname)
20346 +{
20347 +       return 0;
20348 +}
20349 +
20350 +int
20351 +gr_acl_handle_filldir(const struct file *file, const char *name,
20352 +                     const int namelen, const ino_t ino)
20353 +{
20354 +       return 1;
20355 +}
20356 +
20357 +int
20358 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
20359 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
20360 +{
20361 +       return 1;
20362 +}
20363 +
20364 +int
20365 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
20366 +{
20367 +       return 1;
20368 +}
20369 +
20370 +int
20371 +gr_search_accept(const struct socket *sock)
20372 +{
20373 +       return 1;
20374 +}
20375 +
20376 +int
20377 +gr_search_listen(const struct socket *sock)
20378 +{
20379 +       return 1;
20380 +}
20381 +
20382 +int
20383 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
20384 +{
20385 +       return 1;
20386 +}
20387 +
20388 +__u32
20389 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
20390 +{
20391 +       return 1;
20392 +}
20393 +
20394 +__u32
20395 +gr_acl_handle_creat(const struct dentry * dentry,
20396 +                   const struct dentry * p_dentry,
20397 +                   const struct vfsmount * p_mnt, const int fmode,
20398 +                   const int imode)
20399 +{
20400 +       return 1;
20401 +}
20402 +
20403 +void
20404 +gr_acl_handle_exit(void)
20405 +{
20406 +       return;
20407 +}
20408 +
20409 +int
20410 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
20411 +{
20412 +       return 1;
20413 +}
20414 +
20415 +void
20416 +gr_set_role_label(const uid_t uid, const gid_t gid)
20417 +{
20418 +       return;
20419 +}
20420 +
20421 +int
20422 +gr_acl_handle_procpidmem(const struct task_struct *task)
20423 +{
20424 +       return 0;
20425 +}
20426 +
20427 +int
20428 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
20429 +{
20430 +       return 1;
20431 +}
20432 +
20433 +int
20434 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
20435 +{
20436 +       return 1;
20437 +}
20438 +
20439 +void
20440 +gr_set_kernel_label(struct task_struct *task)
20441 +{
20442 +       return;
20443 +}
20444 +
20445 +int
20446 +gr_check_user_change(int real, int effective, int fs)
20447 +{
20448 +       return 0;
20449 +}
20450 +
20451 +int
20452 +gr_check_group_change(int real, int effective, int fs)
20453 +{
20454 +       return 0;
20455 +}
20456 +
20457 +
20458 +EXPORT_SYMBOL(gr_task_is_capable);
20459 +EXPORT_SYMBOL(gr_is_capable_nolog);
20460 +EXPORT_SYMBOL(gr_learn_resource);
20461 +EXPORT_SYMBOL(gr_set_kernel_label);
20462 +#ifdef CONFIG_SECURITY
20463 +EXPORT_SYMBOL(gr_check_user_change);
20464 +EXPORT_SYMBOL(gr_check_group_change);
20465 +#endif
20466 diff -urNp linux-2.6.20.3/grsecurity/grsec_exec.c linux-2.6.20.3/grsecurity/grsec_exec.c
20467 --- linux-2.6.20.3/grsecurity/grsec_exec.c      1969-12-31 19:00:00.000000000 -0500
20468 +++ linux-2.6.20.3/grsecurity/grsec_exec.c      2007-03-23 08:11:31.000000000 -0400
20469 @@ -0,0 +1,88 @@
20470 +#include <linux/kernel.h>
20471 +#include <linux/sched.h>
20472 +#include <linux/file.h>
20473 +#include <linux/binfmts.h>
20474 +#include <linux/smp_lock.h>
20475 +#include <linux/fs.h>
20476 +#include <linux/types.h>
20477 +#include <linux/grdefs.h>
20478 +#include <linux/grinternal.h>
20479 +#include <linux/capability.h>
20480 +
20481 +#include <asm/uaccess.h>
20482 +
20483 +#ifdef CONFIG_GRKERNSEC_EXECLOG
20484 +static char gr_exec_arg_buf[132];
20485 +static DECLARE_MUTEX(gr_exec_arg_sem);
20486 +#endif
20487 +
20488 +int
20489 +gr_handle_nproc(void)
20490 +{
20491 +#ifdef CONFIG_GRKERNSEC_EXECVE
20492 +       if (grsec_enable_execve && current->user &&
20493 +           (atomic_read(&current->user->processes) >
20494 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
20495 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
20496 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
20497 +               return -EAGAIN;
20498 +       }
20499 +#endif
20500 +       return 0;
20501 +}
20502 +
20503 +void
20504 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
20505 +{
20506 +#ifdef CONFIG_GRKERNSEC_EXECLOG
20507 +       char *grarg = gr_exec_arg_buf;
20508 +       unsigned int i, x, execlen = 0;
20509 +       char c;
20510 +
20511 +       if (!((grsec_enable_execlog && grsec_enable_group &&
20512 +              in_group_p(grsec_audit_gid))
20513 +             || (grsec_enable_execlog && !grsec_enable_group)))
20514 +               return;
20515 +
20516 +       down(&gr_exec_arg_sem);
20517 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
20518 +
20519 +       if (unlikely(argv == NULL))
20520 +               goto log;
20521 +
20522 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
20523 +               const char __user *p;
20524 +               unsigned int len;
20525 +
20526 +               if (copy_from_user(&p, argv + i, sizeof(p)))
20527 +                       goto log;
20528 +               if (!p)
20529 +                       goto log;
20530 +               len = strnlen_user(p, 128 - execlen);
20531 +               if (len > 128 - execlen)
20532 +                       len = 128 - execlen;
20533 +               else if (len > 0)
20534 +                       len--;
20535 +               if (copy_from_user(grarg + execlen, p, len))
20536 +                       goto log;
20537 +
20538 +               /* rewrite unprintable characters */
20539 +               for (x = 0; x < len; x++) {
20540 +                       c = *(grarg + execlen + x);
20541 +                       if (c < 32 || c > 126)
20542 +                               *(grarg + execlen + x) = ' ';
20543 +               }
20544 +
20545 +               execlen += len;
20546 +               *(grarg + execlen) = ' ';
20547 +               *(grarg + execlen + 1) = '\0';
20548 +               execlen++;
20549 +       }
20550 +
20551 +      log:
20552 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_dentry,
20553 +                       bprm->file->f_vfsmnt, grarg);
20554 +       up(&gr_exec_arg_sem);
20555 +#endif
20556 +       return;
20557 +}
20558 diff -urNp linux-2.6.20.3/grsecurity/grsec_fifo.c linux-2.6.20.3/grsecurity/grsec_fifo.c
20559 --- linux-2.6.20.3/grsecurity/grsec_fifo.c      1969-12-31 19:00:00.000000000 -0500
20560 +++ linux-2.6.20.3/grsecurity/grsec_fifo.c      2007-03-23 08:11:31.000000000 -0400
20561 @@ -0,0 +1,22 @@
20562 +#include <linux/kernel.h>
20563 +#include <linux/sched.h>
20564 +#include <linux/fs.h>
20565 +#include <linux/file.h>
20566 +#include <linux/grinternal.h>
20567 +
20568 +int
20569 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
20570 +              const struct dentry *dir, const int flag, const int acc_mode)
20571 +{
20572 +#ifdef CONFIG_GRKERNSEC_FIFO
20573 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
20574 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
20575 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
20576 +           (current->fsuid != dentry->d_inode->i_uid)) {
20577 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
20578 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
20579 +               return -EACCES;
20580 +       }
20581 +#endif
20582 +       return 0;
20583 +}
20584 diff -urNp linux-2.6.20.3/grsecurity/grsec_fork.c linux-2.6.20.3/grsecurity/grsec_fork.c
20585 --- linux-2.6.20.3/grsecurity/grsec_fork.c      1969-12-31 19:00:00.000000000 -0500
20586 +++ linux-2.6.20.3/grsecurity/grsec_fork.c      2007-03-23 08:11:31.000000000 -0400
20587 @@ -0,0 +1,15 @@
20588 +#include <linux/kernel.h>
20589 +#include <linux/sched.h>
20590 +#include <linux/grsecurity.h>
20591 +#include <linux/grinternal.h>
20592 +#include <linux/errno.h>
20593 +
20594 +void
20595 +gr_log_forkfail(const int retval)
20596 +{
20597 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
20598 +       if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
20599 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
20600 +#endif
20601 +       return;
20602 +}
20603 diff -urNp linux-2.6.20.3/grsecurity/grsec_init.c linux-2.6.20.3/grsecurity/grsec_init.c
20604 --- linux-2.6.20.3/grsecurity/grsec_init.c      1969-12-31 19:00:00.000000000 -0500
20605 +++ linux-2.6.20.3/grsecurity/grsec_init.c      2007-03-23 08:11:31.000000000 -0400
20606 @@ -0,0 +1,232 @@
20607 +#include <linux/kernel.h>
20608 +#include <linux/sched.h>
20609 +#include <linux/mm.h>
20610 +#include <linux/smp_lock.h>
20611 +#include <linux/gracl.h>
20612 +#include <linux/slab.h>
20613 +#include <linux/vmalloc.h>
20614 +#include <linux/percpu.h>
20615 +
20616 +int grsec_enable_shm;
20617 +int grsec_enable_link;
20618 +int grsec_enable_dmesg;
20619 +int grsec_enable_fifo;
20620 +int grsec_enable_execve;
20621 +int grsec_enable_execlog;
20622 +int grsec_enable_signal;
20623 +int grsec_enable_forkfail;
20624 +int grsec_enable_time;
20625 +int grsec_enable_audit_textrel;
20626 +int grsec_enable_group;
20627 +int grsec_audit_gid;
20628 +int grsec_enable_chdir;
20629 +int grsec_enable_audit_ipc;
20630 +int grsec_enable_mount;
20631 +int grsec_enable_chroot_findtask;
20632 +int grsec_enable_chroot_mount;
20633 +int grsec_enable_chroot_shmat;
20634 +int grsec_enable_chroot_fchdir;
20635 +int grsec_enable_chroot_double;
20636 +int grsec_enable_chroot_pivot;
20637 +int grsec_enable_chroot_chdir;
20638 +int grsec_enable_chroot_chmod;
20639 +int grsec_enable_chroot_mknod;
20640 +int grsec_enable_chroot_nice;
20641 +int grsec_enable_chroot_execlog;
20642 +int grsec_enable_chroot_caps;
20643 +int grsec_enable_chroot_sysctl;
20644 +int grsec_enable_chroot_unix;
20645 +int grsec_enable_tpe;
20646 +int grsec_tpe_gid;
20647 +int grsec_enable_tpe_all;
20648 +int grsec_enable_socket_all;
20649 +int grsec_socket_all_gid;
20650 +int grsec_enable_socket_client;
20651 +int grsec_socket_client_gid;
20652 +int grsec_enable_socket_server;
20653 +int grsec_socket_server_gid;
20654 +int grsec_resource_logging;
20655 +int grsec_lock;
20656 +
20657 +spinlock_t grsec_alert_lock = SPIN_LOCK_UNLOCKED;
20658 +unsigned long grsec_alert_wtime = 0;
20659 +unsigned long grsec_alert_fyet = 0;
20660 +
20661 +spinlock_t grsec_audit_lock = SPIN_LOCK_UNLOCKED;
20662 +
20663 +rwlock_t grsec_exec_file_lock = RW_LOCK_UNLOCKED;
20664 +
20665 +char *gr_shared_page[4];
20666 +
20667 +char *gr_alert_log_fmt;
20668 +char *gr_audit_log_fmt;
20669 +char *gr_alert_log_buf;
20670 +char *gr_audit_log_buf;
20671 +
20672 +extern struct gr_arg *gr_usermode;
20673 +extern unsigned char *gr_system_salt;
20674 +extern unsigned char *gr_system_sum;
20675 +
20676 +void
20677 +grsecurity_init(void)
20678 +{
20679 +       int j;
20680 +       /* create the per-cpu shared pages */
20681 +
20682 +       preempt_disable();
20683 +       for (j = 0; j < 4; j++) {
20684 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
20685 +               if (gr_shared_page[j] == NULL) {
20686 +                       panic("Unable to allocate grsecurity shared page");
20687 +                       return;
20688 +               }
20689 +       }
20690 +       preempt_enable();
20691 +
20692 +       /* allocate log buffers */
20693 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
20694 +       if (!gr_alert_log_fmt) {
20695 +               panic("Unable to allocate grsecurity alert log format buffer");
20696 +               return;
20697 +       }
20698 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
20699 +       if (!gr_audit_log_fmt) {
20700 +               panic("Unable to allocate grsecurity audit log format buffer");
20701 +               return;
20702 +       }
20703 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
20704 +       if (!gr_alert_log_buf) {
20705 +               panic("Unable to allocate grsecurity alert log buffer");
20706 +               return;
20707 +       }
20708 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
20709 +       if (!gr_audit_log_buf) {
20710 +               panic("Unable to allocate grsecurity audit log buffer");
20711 +               return;
20712 +       }
20713 +
20714 +       /* allocate memory for authentication structure */
20715 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
20716 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
20717 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
20718 +
20719 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
20720 +               panic("Unable to allocate grsecurity authentication structure");
20721 +               return;
20722 +       }
20723 +
20724 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
20725 +#ifndef CONFIG_GRKERNSEC_SYSCTL
20726 +       grsec_lock = 1;
20727 +#endif
20728 +#ifdef CONFIG_GRKERNSEC_SHM
20729 +       grsec_enable_shm = 1;
20730 +#endif
20731 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
20732 +       grsec_enable_audit_textrel = 1;
20733 +#endif
20734 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
20735 +       grsec_enable_group = 1;
20736 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
20737 +#endif
20738 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
20739 +       grsec_enable_chdir = 1;
20740 +#endif
20741 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20742 +       grsec_enable_audit_ipc = 1;
20743 +#endif
20744 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
20745 +       grsec_enable_mount = 1;
20746 +#endif
20747 +#ifdef CONFIG_GRKERNSEC_LINK
20748 +       grsec_enable_link = 1;
20749 +#endif
20750 +#ifdef CONFIG_GRKERNSEC_DMESG
20751 +       grsec_enable_dmesg = 1;
20752 +#endif
20753 +#ifdef CONFIG_GRKERNSEC_FIFO
20754 +       grsec_enable_fifo = 1;
20755 +#endif
20756 +#ifdef CONFIG_GRKERNSEC_EXECVE
20757 +       grsec_enable_execve = 1;
20758 +#endif
20759 +#ifdef CONFIG_GRKERNSEC_EXECLOG
20760 +       grsec_enable_execlog = 1;
20761 +#endif
20762 +#ifdef CONFIG_GRKERNSEC_SIGNAL
20763 +       grsec_enable_signal = 1;
20764 +#endif
20765 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
20766 +       grsec_enable_forkfail = 1;
20767 +#endif
20768 +#ifdef CONFIG_GRKERNSEC_TIME
20769 +       grsec_enable_time = 1;
20770 +#endif
20771 +#ifdef CONFIG_GRKERNSEC_RESLOG
20772 +       grsec_resource_logging = 1;
20773 +#endif
20774 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
20775 +       grsec_enable_chroot_findtask = 1;
20776 +#endif
20777 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
20778 +       grsec_enable_chroot_unix = 1;
20779 +#endif
20780 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
20781 +       grsec_enable_chroot_mount = 1;
20782 +#endif
20783 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
20784 +       grsec_enable_chroot_fchdir = 1;
20785 +#endif
20786 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
20787 +       grsec_enable_chroot_shmat = 1;
20788 +#endif
20789 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
20790 +       grsec_enable_chroot_double = 1;
20791 +#endif
20792 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
20793 +       grsec_enable_chroot_pivot = 1;
20794 +#endif
20795 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
20796 +       grsec_enable_chroot_chdir = 1;
20797 +#endif
20798 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
20799 +       grsec_enable_chroot_chmod = 1;
20800 +#endif
20801 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
20802 +       grsec_enable_chroot_mknod = 1;
20803 +#endif
20804 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
20805 +       grsec_enable_chroot_nice = 1;
20806 +#endif
20807 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
20808 +       grsec_enable_chroot_execlog = 1;
20809 +#endif
20810 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
20811 +       grsec_enable_chroot_caps = 1;
20812 +#endif
20813 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
20814 +       grsec_enable_chroot_sysctl = 1;
20815 +#endif
20816 +#ifdef CONFIG_GRKERNSEC_TPE
20817 +       grsec_enable_tpe = 1;
20818 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
20819 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
20820 +       grsec_enable_tpe_all = 1;
20821 +#endif
20822 +#endif
20823 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
20824 +       grsec_enable_socket_all = 1;
20825 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
20826 +#endif
20827 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
20828 +       grsec_enable_socket_client = 1;
20829 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
20830 +#endif
20831 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
20832 +       grsec_enable_socket_server = 1;
20833 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
20834 +#endif
20835 +#endif
20836 +
20837 +       return;
20838 +}
20839 diff -urNp linux-2.6.20.3/grsecurity/grsec_ipc.c linux-2.6.20.3/grsecurity/grsec_ipc.c
20840 --- linux-2.6.20.3/grsecurity/grsec_ipc.c       1969-12-31 19:00:00.000000000 -0500
20841 +++ linux-2.6.20.3/grsecurity/grsec_ipc.c       2007-03-23 08:11:31.000000000 -0400
20842 @@ -0,0 +1,81 @@
20843 +#include <linux/kernel.h>
20844 +#include <linux/sched.h>
20845 +#include <linux/types.h>
20846 +#include <linux/ipc.h>
20847 +#include <linux/grsecurity.h>
20848 +#include <linux/grinternal.h>
20849 +
20850 +void
20851 +gr_log_msgget(const int ret, const int msgflg)
20852 +{
20853 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20854 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20855 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
20856 +                                         !grsec_enable_group)) && (ret >= 0)
20857 +           && (msgflg & IPC_CREAT))
20858 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
20859 +#endif
20860 +       return;
20861 +}
20862 +
20863 +void
20864 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
20865 +{
20866 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20867 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20868 +            grsec_enable_audit_ipc) ||
20869 +           (grsec_enable_audit_ipc && !grsec_enable_group))
20870 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
20871 +#endif
20872 +       return;
20873 +}
20874 +
20875 +void
20876 +gr_log_semget(const int err, const int semflg)
20877 +{
20878 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20879 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20880 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
20881 +                                         !grsec_enable_group)) && (err >= 0)
20882 +           && (semflg & IPC_CREAT))
20883 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
20884 +#endif
20885 +       return;
20886 +}
20887 +
20888 +void
20889 +gr_log_semrm(const uid_t uid, const uid_t cuid)
20890 +{
20891 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20892 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20893 +            grsec_enable_audit_ipc) ||
20894 +           (grsec_enable_audit_ipc && !grsec_enable_group))
20895 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
20896 +#endif
20897 +       return;
20898 +}
20899 +
20900 +void
20901 +gr_log_shmget(const int err, const int shmflg, const size_t size)
20902 +{
20903 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20904 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20905 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
20906 +                                         !grsec_enable_group)) && (err >= 0)
20907 +           && (shmflg & IPC_CREAT))
20908 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
20909 +#endif
20910 +       return;
20911 +}
20912 +
20913 +void
20914 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
20915 +{
20916 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
20917 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
20918 +            grsec_enable_audit_ipc) ||
20919 +           (grsec_enable_audit_ipc && !grsec_enable_group))
20920 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
20921 +#endif
20922 +       return;
20923 +}
20924 diff -urNp linux-2.6.20.3/grsecurity/grsec_link.c linux-2.6.20.3/grsecurity/grsec_link.c
20925 --- linux-2.6.20.3/grsecurity/grsec_link.c      1969-12-31 19:00:00.000000000 -0500
20926 +++ linux-2.6.20.3/grsecurity/grsec_link.c      2007-03-23 08:11:31.000000000 -0400
20927 @@ -0,0 +1,39 @@
20928 +#include <linux/kernel.h>
20929 +#include <linux/sched.h>
20930 +#include <linux/fs.h>
20931 +#include <linux/file.h>
20932 +#include <linux/grinternal.h>
20933 +
20934 +int
20935 +gr_handle_follow_link(const struct inode *parent,
20936 +                     const struct inode *inode,
20937 +                     const struct dentry *dentry, const struct vfsmount *mnt)
20938 +{
20939 +#ifdef CONFIG_GRKERNSEC_LINK
20940 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
20941 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
20942 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
20943 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
20944 +               return -EACCES;
20945 +       }
20946 +#endif
20947 +       return 0;
20948 +}
20949 +
20950 +int
20951 +gr_handle_hardlink(const struct dentry *dentry,
20952 +                  const struct vfsmount *mnt,
20953 +                  struct inode *inode, const int mode, const char *to)
20954 +{
20955 +#ifdef CONFIG_GRKERNSEC_LINK
20956 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
20957 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
20958 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
20959 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
20960 +           !capable(CAP_FOWNER) && current->uid) {
20961 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
20962 +               return -EPERM;
20963 +       }
20964 +#endif
20965 +       return 0;
20966 +}
20967 diff -urNp linux-2.6.20.3/grsecurity/grsec_log.c linux-2.6.20.3/grsecurity/grsec_log.c
20968 --- linux-2.6.20.3/grsecurity/grsec_log.c       1969-12-31 19:00:00.000000000 -0500
20969 +++ linux-2.6.20.3/grsecurity/grsec_log.c       2007-03-23 08:11:31.000000000 -0400
20970 @@ -0,0 +1,265 @@
20971 +#include <linux/kernel.h>
20972 +#include <linux/sched.h>
20973 +#include <linux/file.h>
20974 +#include <linux/tty.h>
20975 +#include <linux/fs.h>
20976 +#include <linux/grinternal.h>
20977 +
20978 +#define BEGIN_LOCKS(x) \
20979 +       read_lock(&tasklist_lock); \
20980 +       read_lock(&grsec_exec_file_lock); \
20981 +       if (x != GR_DO_AUDIT) \
20982 +               spin_lock(&grsec_alert_lock); \
20983 +       else \
20984 +               spin_lock(&grsec_audit_lock)
20985 +
20986 +#define END_LOCKS(x) \
20987 +       if (x != GR_DO_AUDIT) \
20988 +               spin_unlock(&grsec_alert_lock); \
20989 +       else \
20990 +               spin_unlock(&grsec_audit_lock); \
20991 +       read_unlock(&grsec_exec_file_lock); \
20992 +       read_unlock(&tasklist_lock); \
20993 +       if (x == GR_DONT_AUDIT) \
20994 +               gr_handle_alertkill(current)
20995 +
20996 +enum {
20997 +       FLOODING,
20998 +       NO_FLOODING
20999 +};
21000 +
21001 +extern char *gr_alert_log_fmt;
21002 +extern char *gr_audit_log_fmt;
21003 +extern char *gr_alert_log_buf;
21004 +extern char *gr_audit_log_buf;
21005 +
21006 +static int gr_log_start(int audit)
21007 +{
21008 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
21009 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
21010 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21011 +
21012 +       if (audit == GR_DO_AUDIT)
21013 +               goto set_fmt;
21014 +
21015 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
21016 +               grsec_alert_wtime = jiffies;
21017 +               grsec_alert_fyet = 0;
21018 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
21019 +               grsec_alert_fyet++;
21020 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
21021 +               grsec_alert_wtime = jiffies;
21022 +               grsec_alert_fyet++;
21023 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
21024 +               return FLOODING;
21025 +       } else return FLOODING;
21026 +
21027 +set_fmt:
21028 +       memset(buf, 0, PAGE_SIZE);
21029 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
21030 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
21031 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
21032 +       } else if (current->signal->curr_ip) {
21033 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
21034 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
21035 +       } else if (gr_acl_is_enabled()) {
21036 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
21037 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
21038 +       } else {
21039 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
21040 +               strcpy(buf, fmt);
21041 +       }
21042 +
21043 +       return NO_FLOODING;
21044 +}
21045 +
21046 +static void gr_log_middle(int audit, const char *msg, va_list ap)
21047 +{
21048 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21049 +       unsigned int len = strlen(buf);
21050 +
21051 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
21052 +
21053 +       return;
21054 +}
21055 +
21056 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
21057 +{
21058 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21059 +       unsigned int len = strlen(buf);
21060 +       va_list ap;
21061 +
21062 +       va_start(ap, msg);
21063 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
21064 +       va_end(ap);
21065 +
21066 +       return;
21067 +}
21068 +
21069 +static void gr_log_end(int audit)
21070 +{
21071 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
21072 +       unsigned int len = strlen(buf);
21073 +
21074 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
21075 +       printk("%s\n", buf);
21076 +
21077 +       return;
21078 +}
21079 +
21080 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
21081 +{
21082 +       int logtype;
21083 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
21084 +       char *str1, *str2, *str3;
21085 +       int num1, num2;
21086 +       unsigned long ulong1, ulong2;
21087 +       struct dentry *dentry;
21088 +       struct vfsmount *mnt;
21089 +       struct file *file;
21090 +       struct task_struct *task;
21091 +       va_list ap;
21092 +
21093 +       BEGIN_LOCKS(audit);
21094 +       logtype = gr_log_start(audit);
21095 +       if (logtype == FLOODING) {
21096 +               END_LOCKS(audit);
21097 +               return;
21098 +       }
21099 +       va_start(ap, argtypes);
21100 +       switch (argtypes) {
21101 +       case GR_TTYSNIFF:
21102 +               task = va_arg(ap, struct task_struct *);
21103 +               gr_log_middle_varargs(audit, msg, NIPQUAD(task->signal->curr_ip), gr_task_fullpath0(task), task->comm, task->pid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid);
21104 +               break;
21105 +       case GR_RBAC:
21106 +               dentry = va_arg(ap, struct dentry *);
21107 +               mnt = va_arg(ap, struct vfsmount *);
21108 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
21109 +               break;
21110 +       case GR_RBAC_STR:
21111 +               dentry = va_arg(ap, struct dentry *);
21112 +               mnt = va_arg(ap, struct vfsmount *);
21113 +               str1 = va_arg(ap, char *);
21114 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
21115 +               break;
21116 +       case GR_STR_RBAC:
21117 +               str1 = va_arg(ap, char *);
21118 +               dentry = va_arg(ap, struct dentry *);
21119 +               mnt = va_arg(ap, struct vfsmount *);
21120 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
21121 +               break;
21122 +       case GR_RBAC_MODE2:
21123 +               dentry = va_arg(ap, struct dentry *);
21124 +               mnt = va_arg(ap, struct vfsmount *);
21125 +               str1 = va_arg(ap, char *);
21126 +               str2 = va_arg(ap, char *);
21127 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
21128 +               break;
21129 +       case GR_RBAC_MODE3:
21130 +               dentry = va_arg(ap, struct dentry *);
21131 +               mnt = va_arg(ap, struct vfsmount *);
21132 +               str1 = va_arg(ap, char *);
21133 +               str2 = va_arg(ap, char *);
21134 +               str3 = va_arg(ap, char *);
21135 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
21136 +               break;
21137 +       case GR_FILENAME:
21138 +               dentry = va_arg(ap, struct dentry *);
21139 +               mnt = va_arg(ap, struct vfsmount *);
21140 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
21141 +               break;
21142 +       case GR_STR_FILENAME:
21143 +               str1 = va_arg(ap, char *);
21144 +               dentry = va_arg(ap, struct dentry *);
21145 +               mnt = va_arg(ap, struct vfsmount *);
21146 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
21147 +               break;
21148 +       case GR_FILENAME_STR:
21149 +               dentry = va_arg(ap, struct dentry *);
21150 +               mnt = va_arg(ap, struct vfsmount *);
21151 +               str1 = va_arg(ap, char *);
21152 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
21153 +               break;
21154 +       case GR_FILENAME_TWO_INT:
21155 +               dentry = va_arg(ap, struct dentry *);
21156 +               mnt = va_arg(ap, struct vfsmount *);
21157 +               num1 = va_arg(ap, int);
21158 +               num2 = va_arg(ap, int);
21159 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
21160 +               break;
21161 +       case GR_FILENAME_TWO_INT_STR:
21162 +               dentry = va_arg(ap, struct dentry *);
21163 +               mnt = va_arg(ap, struct vfsmount *);
21164 +               num1 = va_arg(ap, int);
21165 +               num2 = va_arg(ap, int);
21166 +               str1 = va_arg(ap, char *);
21167 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
21168 +               break;
21169 +       case GR_TEXTREL:
21170 +               file = va_arg(ap, struct file *);
21171 +               ulong1 = va_arg(ap, unsigned long);
21172 +               ulong2 = va_arg(ap, unsigned long);
21173 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_dentry, file->f_vfsmnt) : "<anonymous mapping>", ulong1, ulong2);
21174 +               break;
21175 +       case GR_PTRACE:
21176 +               task = va_arg(ap, struct task_struct *);
21177 +               gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_dentry, task->exec_file->f_vfsmnt) : "(none)", task->comm, task->pid);
21178 +               break;
21179 +       case GR_RESOURCE:
21180 +               task = va_arg(ap, struct task_struct *);
21181 +               ulong1 = va_arg(ap, unsigned long);
21182 +               str1 = va_arg(ap, char *);
21183 +               ulong2 = va_arg(ap, unsigned long);
21184 +               gr_log_middle_varargs(audit, msg, ulong1, str1, ulong2, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21185 +               break;
21186 +       case GR_CAP:
21187 +               task = va_arg(ap, struct task_struct *);
21188 +               str1 = va_arg(ap, char *);
21189 +               gr_log_middle_varargs(audit, msg, str1, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21190 +               break;
21191 +       case GR_SIG:
21192 +               task = va_arg(ap, struct task_struct *);
21193 +               num1 = va_arg(ap, int);
21194 +               gr_log_middle_varargs(audit, msg, num1, gr_task_fullpath0(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath0(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21195 +               break;
21196 +       case GR_CRASH1:
21197 +               task = va_arg(ap, struct task_struct *);
21198 +               ulong1 = va_arg(ap, unsigned long);
21199 +               gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, task->uid, ulong1);
21200 +               break;
21201 +       case GR_CRASH2:
21202 +               task = va_arg(ap, struct task_struct *);
21203 +               ulong1 = va_arg(ap, unsigned long);
21204 +               gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, task->uid, task->euid, task->gid, task->egid, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid, ulong1);
21205 +               break;
21206 +       case GR_PSACCT:
21207 +               {
21208 +                       unsigned int wday, cday;
21209 +                       __u8 whr, chr;
21210 +                       __u8 wmin, cmin;
21211 +                       __u8 wsec, csec;
21212 +                       char cur_tty[64] = { 0 };
21213 +                       char parent_tty[64] = { 0 };
21214 +
21215 +                       task = va_arg(ap, struct task_struct *);
21216 +                       wday = va_arg(ap, unsigned int);
21217 +                       cday = va_arg(ap, unsigned int);
21218 +                       whr = va_arg(ap, int);
21219 +                       chr = va_arg(ap, int);
21220 +                       wmin = va_arg(ap, int);
21221 +                       cmin = va_arg(ap, int);
21222 +                       wsec = va_arg(ap, int);
21223 +                       csec = va_arg(ap, int);
21224 +                       ulong1 = va_arg(ap, unsigned long);
21225 +
21226 +                       gr_log_middle_varargs(audit, msg, gr_task_fullpath(task), task->comm, task->pid, NIPQUAD(task->signal->curr_ip), tty_name(task->signal->tty, cur_tty), task->uid, task->euid, task->gid, task->egid, wday, whr, wmin, wsec, cday, chr, cmin, csec, (task->flags & PF_SIGNALED) ? "killed by signal" : "exited", ulong1, gr_parent_task_fullpath(task), task->parent->comm, task->parent->pid, NIPQUAD(task->parent->signal->curr_ip), tty_name(task->parent->signal->tty, parent_tty), task->parent->uid, task->parent->euid, task->parent->gid, task->parent->egid);
21227 +               }
21228 +               break;
21229 +       default:
21230 +               gr_log_middle(audit, msg, ap);
21231 +       }
21232 +       va_end(ap);
21233 +       gr_log_end(audit);
21234 +       END_LOCKS(audit);
21235 +}
21236 diff -urNp linux-2.6.20.3/grsecurity/grsec_mem.c linux-2.6.20.3/grsecurity/grsec_mem.c
21237 --- linux-2.6.20.3/grsecurity/grsec_mem.c       1969-12-31 19:00:00.000000000 -0500
21238 +++ linux-2.6.20.3/grsecurity/grsec_mem.c       2007-03-23 08:11:31.000000000 -0400
21239 @@ -0,0 +1,71 @@
21240 +#include <linux/kernel.h>
21241 +#include <linux/sched.h>
21242 +#include <linux/mm.h>
21243 +#include <linux/mman.h>
21244 +#include <linux/grinternal.h>
21245 +
21246 +void
21247 +gr_handle_ioperm(void)
21248 +{
21249 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
21250 +       return;
21251 +}
21252 +
21253 +void
21254 +gr_handle_iopl(void)
21255 +{
21256 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
21257 +       return;
21258 +}
21259 +
21260 +void
21261 +gr_handle_mem_write(void)
21262 +{
21263 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
21264 +       return;
21265 +}
21266 +
21267 +void
21268 +gr_handle_kmem_write(void)
21269 +{
21270 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
21271 +       return;
21272 +}
21273 +
21274 +void
21275 +gr_handle_open_port(void)
21276 +{
21277 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
21278 +       return;
21279 +}
21280 +
21281 +int
21282 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
21283 +{
21284 +       unsigned long start, end;
21285 +
21286 +       start = offset;
21287 +       end = start + vma->vm_end - vma->vm_start;
21288 +
21289 +       if (start > end) {
21290 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
21291 +               return -EPERM;
21292 +       }
21293 +
21294 +       /* allowed ranges : ISA I/O BIOS */
21295 +       if ((start >= __pa(high_memory))
21296 +#ifdef CONFIG_X86
21297 +           || (start >= 0x000a0000 && end <= 0x00100000)
21298 +           || (start >= 0x00000000 && end <= 0x00001000)
21299 +#endif
21300 +       )
21301 +               return 0;
21302 +
21303 +       if (vma->vm_flags & VM_WRITE) {
21304 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
21305 +               return -EPERM;
21306 +       } else
21307 +               vma->vm_flags &= ~VM_MAYWRITE;
21308 +
21309 +       return 0;
21310 +}
21311 diff -urNp linux-2.6.20.3/grsecurity/grsec_mount.c linux-2.6.20.3/grsecurity/grsec_mount.c
21312 --- linux-2.6.20.3/grsecurity/grsec_mount.c     1969-12-31 19:00:00.000000000 -0500
21313 +++ linux-2.6.20.3/grsecurity/grsec_mount.c     2007-03-23 08:11:31.000000000 -0400
21314 @@ -0,0 +1,34 @@
21315 +#include <linux/kernel.h>
21316 +#include <linux/sched.h>
21317 +#include <linux/grsecurity.h>
21318 +#include <linux/grinternal.h>
21319 +
21320 +void
21321 +gr_log_remount(const char *devname, const int retval)
21322 +{
21323 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
21324 +       if (grsec_enable_mount && (retval >= 0))
21325 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
21326 +#endif
21327 +       return;
21328 +}
21329 +
21330 +void
21331 +gr_log_unmount(const char *devname, const int retval)
21332 +{
21333 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
21334 +       if (grsec_enable_mount && (retval >= 0))
21335 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
21336 +#endif
21337 +       return;
21338 +}
21339 +
21340 +void
21341 +gr_log_mount(const char *from, const char *to, const int retval)
21342 +{
21343 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
21344 +       if (grsec_enable_mount && (retval >= 0))
21345 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
21346 +#endif
21347 +       return;
21348 +}
21349 diff -urNp linux-2.6.20.3/grsecurity/grsec_sig.c linux-2.6.20.3/grsecurity/grsec_sig.c
21350 --- linux-2.6.20.3/grsecurity/grsec_sig.c       1969-12-31 19:00:00.000000000 -0500
21351 +++ linux-2.6.20.3/grsecurity/grsec_sig.c       2007-03-23 08:11:31.000000000 -0400
21352 @@ -0,0 +1,59 @@
21353 +#include <linux/kernel.h>
21354 +#include <linux/sched.h>
21355 +#include <linux/grsecurity.h>
21356 +#include <linux/grinternal.h>
21357 +
21358 +void
21359 +gr_log_signal(const int sig, const struct task_struct *t)
21360 +{
21361 +#ifdef CONFIG_GRKERNSEC_SIGNAL
21362 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
21363 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
21364 +               if (t->pid == current->pid) {
21365 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
21366 +               } else {
21367 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
21368 +               }
21369 +       }
21370 +#endif
21371 +       return;
21372 +}
21373 +
21374 +int
21375 +gr_handle_signal(const struct task_struct *p, const int sig)
21376 +{
21377 +#ifdef CONFIG_GRKERNSEC
21378 +       if (current->pid > 1 && gr_check_protected_task(p)) {
21379 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
21380 +               return -EPERM;
21381 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
21382 +               return -EPERM;
21383 +       }
21384 +#endif
21385 +       return 0;
21386 +}
21387 +
21388 +void gr_handle_brute_attach(struct task_struct *p)
21389 +{
21390 +#ifdef CONFIG_GRKERNSEC_BRUTE
21391 +       read_lock(&tasklist_lock);
21392 +       read_lock(&grsec_exec_file_lock);
21393 +       if (p->parent && p->parent->exec_file == p->exec_file)
21394 +               p->parent->brute = 1;
21395 +       read_unlock(&grsec_exec_file_lock);
21396 +       read_unlock(&tasklist_lock);
21397 +#endif
21398 +       return;
21399 +}
21400 +
21401 +void gr_handle_brute_check(void)
21402 +{
21403 +#ifdef CONFIG_GRKERNSEC_BRUTE
21404 +       if (current->brute) {
21405 +               set_current_state(TASK_UNINTERRUPTIBLE);
21406 +               schedule_timeout(30 * HZ);
21407 +       }
21408 +#endif
21409 +       return;
21410 +}
21411 +
21412 diff -urNp linux-2.6.20.3/grsecurity/grsec_sock.c linux-2.6.20.3/grsecurity/grsec_sock.c
21413 --- linux-2.6.20.3/grsecurity/grsec_sock.c      1969-12-31 19:00:00.000000000 -0500
21414 +++ linux-2.6.20.3/grsecurity/grsec_sock.c      2007-03-23 08:11:31.000000000 -0400
21415 @@ -0,0 +1,263 @@
21416 +#include <linux/kernel.h>
21417 +#include <linux/module.h>
21418 +#include <linux/sched.h>
21419 +#include <linux/file.h>
21420 +#include <linux/net.h>
21421 +#include <linux/in.h>
21422 +#include <linux/ip.h>
21423 +#include <net/sock.h>
21424 +#include <net/inet_sock.h>
21425 +#include <linux/grsecurity.h>
21426 +#include <linux/grinternal.h>
21427 +#include <linux/gracl.h>
21428 +
21429 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
21430 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
21431 +EXPORT_SYMBOL(udp_v4_lookup);
21432 +#endif
21433 +
21434 +EXPORT_SYMBOL(gr_cap_rtnetlink);
21435 +
21436 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
21437 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
21438 +
21439 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
21440 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
21441 +
21442 +#ifdef CONFIG_UNIX_MODULE
21443 +EXPORT_SYMBOL(gr_acl_handle_unix);
21444 +EXPORT_SYMBOL(gr_acl_handle_mknod);
21445 +EXPORT_SYMBOL(gr_handle_chroot_unix);
21446 +EXPORT_SYMBOL(gr_handle_create);
21447 +#endif
21448 +
21449 +#ifdef CONFIG_GRKERNSEC
21450 +#define gr_conn_table_size 32749
21451 +struct conn_table_entry {
21452 +       struct conn_table_entry *next;
21453 +       struct signal_struct *sig;
21454 +};
21455 +
21456 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
21457 +spinlock_t gr_conn_table_lock = SPIN_LOCK_UNLOCKED;
21458 +
21459 +extern const char * gr_socktype_to_name(unsigned char type);
21460 +extern const char * gr_proto_to_name(unsigned char proto);
21461 +
21462 +static __inline__ int 
21463 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
21464 +{
21465 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
21466 +}
21467 +
21468 +static __inline__ int
21469 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
21470 +          __u16 sport, __u16 dport)
21471 +{
21472 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
21473 +                    sig->gr_sport == sport && sig->gr_dport == dport))
21474 +               return 1;
21475 +       else
21476 +               return 0;
21477 +}
21478 +
21479 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
21480 +{
21481 +       struct conn_table_entry **match;
21482 +       unsigned int index;
21483 +
21484 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
21485 +                         sig->gr_sport, sig->gr_dport, 
21486 +                         gr_conn_table_size);
21487 +
21488 +       newent->sig = sig;
21489 +       
21490 +       match = &gr_conn_table[index];
21491 +       newent->next = *match;
21492 +       *match = newent;
21493 +
21494 +       return;
21495 +}
21496 +
21497 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
21498 +{
21499 +       struct conn_table_entry *match, *last = NULL;
21500 +       unsigned int index;
21501 +
21502 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
21503 +                         sig->gr_sport, sig->gr_dport, 
21504 +                         gr_conn_table_size);
21505 +
21506 +       match = gr_conn_table[index];
21507 +       while (match && !conn_match(match->sig, 
21508 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
21509 +               sig->gr_dport)) {
21510 +               last = match;
21511 +               match = match->next;
21512 +       }
21513 +
21514 +       if (match) {
21515 +               if (last)
21516 +                       last->next = match->next;
21517 +               else
21518 +                       gr_conn_table[index] = NULL;
21519 +               kfree(match);
21520 +       }
21521 +
21522 +       return;
21523 +}
21524 +
21525 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
21526 +                                            __u16 sport, __u16 dport)
21527 +{
21528 +       struct conn_table_entry *match;
21529 +       unsigned int index;
21530 +
21531 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
21532 +
21533 +       match = gr_conn_table[index];
21534 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
21535 +               match = match->next;
21536 +
21537 +       if (match)
21538 +               return match->sig;
21539 +       else
21540 +               return NULL;
21541 +}
21542 +
21543 +#endif
21544 +
21545 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
21546 +{
21547 +#ifdef CONFIG_GRKERNSEC
21548 +       struct signal_struct *sig = task->signal;
21549 +       struct conn_table_entry *newent;
21550 +
21551 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
21552 +       if (newent == NULL)
21553 +               return;
21554 +       /* no bh lock needed since we are called with bh disabled */
21555 +       spin_lock(&gr_conn_table_lock);
21556 +       gr_del_task_from_ip_table_nolock(sig);
21557 +       sig->gr_saddr = inet->rcv_saddr;
21558 +       sig->gr_daddr = inet->daddr;
21559 +       sig->gr_sport = inet->sport;
21560 +       sig->gr_dport = inet->dport;
21561 +       gr_add_to_task_ip_table_nolock(sig, newent);
21562 +       spin_unlock(&gr_conn_table_lock);
21563 +#endif
21564 +       return;
21565 +}
21566 +
21567 +void gr_del_task_from_ip_table(struct task_struct *task)
21568 +{
21569 +#ifdef CONFIG_GRKERNSEC
21570 +       spin_lock(&gr_conn_table_lock);
21571 +       gr_del_task_from_ip_table_nolock(task->signal);
21572 +       spin_unlock(&gr_conn_table_lock);
21573 +#endif
21574 +       return;
21575 +}
21576 +
21577 +void
21578 +gr_attach_curr_ip(const struct sock *sk)
21579 +{
21580 +#ifdef CONFIG_GRKERNSEC
21581 +       struct signal_struct *p, *set;
21582 +       const struct inet_sock *inet = inet_sk(sk);     
21583 +
21584 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
21585 +               return;
21586 +
21587 +       set = current->signal;
21588 +
21589 +       spin_lock_bh(&gr_conn_table_lock);
21590 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
21591 +                                   inet->dport, inet->sport);
21592 +       if (unlikely(p != NULL)) {
21593 +               set->curr_ip = p->curr_ip;
21594 +               set->used_accept = 1;
21595 +               gr_del_task_from_ip_table_nolock(p);
21596 +               spin_unlock_bh(&gr_conn_table_lock);
21597 +               return;
21598 +       }
21599 +       spin_unlock_bh(&gr_conn_table_lock);
21600 +
21601 +       set->curr_ip = inet->daddr;
21602 +       set->used_accept = 1;
21603 +#endif
21604 +       return;
21605 +}
21606 +
21607 +int
21608 +gr_handle_sock_all(const int family, const int type, const int protocol)
21609 +{
21610 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
21611 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
21612 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
21613 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
21614 +               return -EACCES;
21615 +       }
21616 +#endif
21617 +       return 0;
21618 +}
21619 +
21620 +int
21621 +gr_handle_sock_server(const struct sockaddr *sck)
21622 +{
21623 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
21624 +       if (grsec_enable_socket_server &&
21625 +           in_group_p(grsec_socket_server_gid) &&
21626 +           sck && (sck->sa_family != AF_UNIX) &&
21627 +           (sck->sa_family != AF_LOCAL)) {
21628 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
21629 +               return -EACCES;
21630 +       }
21631 +#endif
21632 +       return 0;
21633 +}
21634 +
21635 +int
21636 +gr_handle_sock_server_other(const struct sock *sck)
21637 +{
21638 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
21639 +       if (grsec_enable_socket_server &&
21640 +           in_group_p(grsec_socket_server_gid) &&
21641 +           sck && (sck->sk_family != AF_UNIX) &&
21642 +           (sck->sk_family != AF_LOCAL)) {
21643 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
21644 +               return -EACCES;
21645 +       }
21646 +#endif
21647 +       return 0;
21648 +}
21649 +
21650 +int
21651 +gr_handle_sock_client(const struct sockaddr *sck)
21652 +{
21653 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
21654 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
21655 +           sck && (sck->sa_family != AF_UNIX) &&
21656 +           (sck->sa_family != AF_LOCAL)) {
21657 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
21658 +               return -EACCES;
21659 +       }
21660 +#endif
21661 +       return 0;
21662 +}
21663 +
21664 +__u32
21665 +gr_cap_rtnetlink(void)
21666 +{
21667 +#ifdef CONFIG_GRKERNSEC
21668 +       if (!gr_acl_is_enabled())
21669 +               return vx_mbcap(cap_effective);
21670 +       else if (cap_raised(vx_mbcap(cap_effective), CAP_NET_ADMIN) &&
21671 +                gr_task_is_capable(current, CAP_NET_ADMIN))
21672 +               vx_mbcap(cap_effective);
21673 +       else
21674 +               return 0;
21675 +#else
21676 +       vx_mbcap(cap_effective);
21677 +#endif
21678 +}
21679 diff -urNp linux-2.6.20.3/grsecurity/grsec_sysctl.c linux-2.6.20.3/grsecurity/grsec_sysctl.c
21680 --- linux-2.6.20.3/grsecurity/grsec_sysctl.c    1969-12-31 19:00:00.000000000 -0500
21681 +++ linux-2.6.20.3/grsecurity/grsec_sysctl.c    2007-03-23 08:11:31.000000000 -0400
21682 @@ -0,0 +1,456 @@
21683 +#include <linux/kernel.h>
21684 +#include <linux/sched.h>
21685 +#include <linux/sysctl.h>
21686 +#include <linux/grsecurity.h>
21687 +#include <linux/grinternal.h>
21688 +
21689 +#ifdef CONFIG_GRKERNSEC_MODSTOP
21690 +int grsec_modstop;
21691 +#endif
21692 +
21693 +int
21694 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
21695 +{
21696 +#ifdef CONFIG_GRKERNSEC_SYSCTL
21697 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & 002)) {
21698 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
21699 +               return -EACCES;
21700 +       }
21701 +#endif
21702 +#ifdef CONFIG_GRKERNSEC_MODSTOP
21703 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
21704 +           grsec_modstop && (op & 002)) {
21705 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
21706 +               return -EACCES;
21707 +       }
21708 +#endif
21709 +       return 0;
21710 +}
21711 +
21712 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
21713 +enum {GS_LINK=1, GS_FIFO, GS_EXECVE, GS_EXECLOG, GS_SIGNAL,
21714 +GS_FORKFAIL, GS_TIME, GS_CHROOT_SHMAT, GS_CHROOT_UNIX, GS_CHROOT_MNT,
21715 +GS_CHROOT_FCHDIR, GS_CHROOT_DBL, GS_CHROOT_PVT, GS_CHROOT_CD, GS_CHROOT_CM,
21716 +GS_CHROOT_MK, GS_CHROOT_NI, GS_CHROOT_EXECLOG, GS_CHROOT_CAPS,
21717 +GS_CHROOT_SYSCTL, GS_TPE, GS_TPE_GID, GS_TPE_ALL, GS_SIDCAPS,
21718 +GS_SOCKET_ALL, GS_SOCKET_ALL_GID, GS_SOCKET_CLIENT,
21719 +GS_SOCKET_CLIENT_GID, GS_SOCKET_SERVER, GS_SOCKET_SERVER_GID, 
21720 +GS_GROUP, GS_GID, GS_ACHDIR, GS_AMOUNT, GS_AIPC, GS_DMSG,
21721 +GS_TEXTREL, GS_FINDTASK, GS_SHM, GS_LOCK, GS_MODSTOP, GS_RESLOG};
21722 +
21723 +
21724 +ctl_table grsecurity_table[] = {
21725 +#ifdef CONFIG_GRKERNSEC_SYSCTL
21726 +#ifdef CONFIG_GRKERNSEC_LINK
21727 +       {
21728 +               .ctl_name       = GS_LINK,
21729 +               .procname       = "linking_restrictions",
21730 +               .data           = &grsec_enable_link,
21731 +               .maxlen         = sizeof(int),
21732 +               .mode           = 0600,
21733 +               .proc_handler   = &proc_dointvec,
21734 +       },
21735 +#endif
21736 +#ifdef CONFIG_GRKERNSEC_FIFO
21737 +       {
21738 +               .ctl_name       = GS_FIFO,
21739 +               .procname       = "fifo_restrictions",
21740 +               .data           = &grsec_enable_fifo,
21741 +               .maxlen         = sizeof(int),
21742 +               .mode           = 0600,
21743 +               .proc_handler   = &proc_dointvec,
21744 +       },
21745 +#endif
21746 +#ifdef CONFIG_GRKERNSEC_EXECVE
21747 +       {
21748 +               .ctl_name       = GS_EXECVE,
21749 +               .procname       = "execve_limiting",
21750 +               .data           = &grsec_enable_execve,
21751 +               .maxlen         = sizeof(int),
21752 +               .mode           = 0600,
21753 +               .proc_handler   = &proc_dointvec,
21754 +       },
21755 +#endif
21756 +#ifdef CONFIG_GRKERNSEC_EXECLOG
21757 +       {
21758 +               .ctl_name       = GS_EXECLOG,
21759 +               .procname       = "exec_logging",
21760 +               .data           = &grsec_enable_execlog,
21761 +               .maxlen         = sizeof(int),
21762 +               .mode           = 0600,
21763 +               .proc_handler   = &proc_dointvec,
21764 +       },
21765 +#endif
21766 +#ifdef CONFIG_GRKERNSEC_SIGNAL
21767 +       {
21768 +               .ctl_name       = GS_SIGNAL,
21769 +               .procname       = "signal_logging",
21770 +               .data           = &grsec_enable_signal,
21771 +               .maxlen         = sizeof(int),
21772 +               .mode           = 0600,
21773 +               .proc_handler   = &proc_dointvec,
21774 +       },
21775 +#endif
21776 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
21777 +       {
21778 +               .ctl_name       = GS_FORKFAIL,
21779 +               .procname       = "forkfail_logging",
21780 +               .data           = &grsec_enable_forkfail,
21781 +               .maxlen         = sizeof(int),
21782 +               .mode           = 0600,
21783 +               .proc_handler   = &proc_dointvec,
21784 +       },
21785 +#endif
21786 +#ifdef CONFIG_GRKERNSEC_TIME
21787 +       {
21788 +               .ctl_name       = GS_TIME,
21789 +               .procname       = "timechange_logging",
21790 +               .data           = &grsec_enable_time,
21791 +               .maxlen         = sizeof(int),
21792 +               .mode           = 0600,
21793 +               .proc_handler   = &proc_dointvec,
21794 +       },
21795 +#endif
21796 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
21797 +       {
21798 +               .ctl_name       = GS_CHROOT_SHMAT,
21799 +               .procname       = "chroot_deny_shmat",
21800 +               .data           = &grsec_enable_chroot_shmat,
21801 +               .maxlen         = sizeof(int),
21802 +               .mode           = 0600,
21803 +               .proc_handler   = &proc_dointvec,
21804 +       },
21805 +#endif
21806 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
21807 +       {
21808 +               .ctl_name       = GS_CHROOT_UNIX,
21809 +               .procname       = "chroot_deny_unix",
21810 +               .data           = &grsec_enable_chroot_unix,
21811 +               .maxlen         = sizeof(int),
21812 +               .mode           = 0600,
21813 +               .proc_handler   = &proc_dointvec,
21814 +       },
21815 +#endif
21816 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
21817 +       {
21818 +               .ctl_name       = GS_CHROOT_MNT,
21819 +               .procname       = "chroot_deny_mount",
21820 +               .data           = &grsec_enable_chroot_mount,
21821 +               .maxlen         = sizeof(int),
21822 +               .mode           = 0600,
21823 +               .proc_handler   = &proc_dointvec,
21824 +       },
21825 +#endif
21826 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
21827 +       {
21828 +               .ctl_name       = GS_CHROOT_FCHDIR,
21829 +               .procname       = "chroot_deny_fchdir",
21830 +               .data           = &grsec_enable_chroot_fchdir,
21831 +               .maxlen         = sizeof(int),
21832 +               .mode           = 0600,
21833 +               .proc_handler   = &proc_dointvec,
21834 +       },
21835 +#endif
21836 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
21837 +       {
21838 +               .ctl_name       = GS_CHROOT_DBL,
21839 +               .procname       = "chroot_deny_chroot",
21840 +               .data           = &grsec_enable_chroot_double,
21841 +               .maxlen         = sizeof(int),
21842 +               .mode           = 0600,
21843 +               .proc_handler   = &proc_dointvec,
21844 +       },
21845 +#endif
21846 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
21847 +       {
21848 +               .ctl_name       = GS_CHROOT_PVT,
21849 +               .procname       = "chroot_deny_pivot",
21850 +               .data           = &grsec_enable_chroot_pivot,
21851 +               .maxlen         = sizeof(int),
21852 +               .mode           = 0600,
21853 +               .proc_handler   = &proc_dointvec,
21854 +       },
21855 +#endif
21856 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
21857 +       {
21858 +               .ctl_name       = GS_CHROOT_CD,
21859 +               .procname       = "chroot_enforce_chdir",
21860 +               .data           = &grsec_enable_chroot_chdir,
21861 +               .maxlen         = sizeof(int),
21862 +               .mode           = 0600,
21863 +               .proc_handler   = &proc_dointvec,
21864 +       },
21865 +#endif
21866 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
21867 +       {
21868 +               .ctl_name       = GS_CHROOT_CM,
21869 +               .procname       = "chroot_deny_chmod",
21870 +               .data           = &grsec_enable_chroot_chmod,
21871 +               .maxlen         = sizeof(int),
21872 +               .mode           = 0600,
21873 +               .proc_handler   = &proc_dointvec,
21874 +       },
21875 +#endif
21876 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
21877 +       {
21878 +               .ctl_name       = GS_CHROOT_MK,
21879 +               .procname       = "chroot_deny_mknod",
21880 +               .data           = &grsec_enable_chroot_mknod,
21881 +               .maxlen         = sizeof(int),
21882 +               .mode           = 0600,
21883 +               .proc_handler   = &proc_dointvec,
21884 +       },
21885 +#endif
21886 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
21887 +       {
21888 +               .ctl_name       = GS_CHROOT_NI,
21889 +               .procname       = "chroot_restrict_nice",
21890 +               .data           = &grsec_enable_chroot_nice,
21891 +               .maxlen         = sizeof(int),
21892 +               .mode           = 0600,
21893 +               .proc_handler   = &proc_dointvec,
21894 +       },
21895 +#endif
21896 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
21897 +       {
21898 +               .ctl_name       = GS_CHROOT_EXECLOG,
21899 +               .procname       = "chroot_execlog",
21900 +               .data           = &grsec_enable_chroot_execlog,
21901 +               .maxlen         = sizeof(int),
21902 +               .mode           = 0600,
21903 +               .proc_handler   = &proc_dointvec,
21904 +       },
21905 +#endif
21906 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
21907 +       {
21908 +               .ctl_name       = GS_CHROOT_CAPS,
21909 +               .procname       = "chroot_caps",
21910 +               .data           = &grsec_enable_chroot_caps,
21911 +               .maxlen         = sizeof(int),
21912 +               .mode           = 0600,
21913 +               .proc_handler   = &proc_dointvec,
21914 +       },
21915 +#endif
21916 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
21917 +       {
21918 +               .ctl_name       = GS_CHROOT_SYSCTL,
21919 +               .procname       = "chroot_deny_sysctl",
21920 +               .data           = &grsec_enable_chroot_sysctl,
21921 +               .maxlen         = sizeof(int),
21922 +               .mode           = 0600,
21923 +               .proc_handler   = &proc_dointvec,
21924 +       },
21925 +#endif
21926 +#ifdef CONFIG_GRKERNSEC_TPE
21927 +       {
21928 +               .ctl_name       = GS_TPE,
21929 +               .procname       = "tpe",
21930 +               .data           = &grsec_enable_tpe,
21931 +               .maxlen         = sizeof(int),
21932 +               .mode           = 0600,
21933 +               .proc_handler   = &proc_dointvec,
21934 +       },
21935 +       {
21936 +               .ctl_name       = GS_TPE_GID,
21937 +               .procname       = "tpe_gid",
21938 +               .data           = &grsec_tpe_gid,
21939 +               .maxlen         = sizeof(int),
21940 +               .mode           = 0600,
21941 +               .proc_handler   = &proc_dointvec,
21942 +       },
21943 +#endif
21944 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
21945 +       {
21946 +               .ctl_name       = GS_TPE_ALL,
21947 +               .procname       = "tpe_restrict_all",
21948 +               .data           = &grsec_enable_tpe_all,
21949 +               .maxlen         = sizeof(int),
21950 +               .mode           = 0600,
21951 +               .proc_handler   = &proc_dointvec,
21952 +       },
21953 +#endif
21954 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
21955 +       {
21956 +               .ctl_name       = GS_SOCKET_ALL,
21957 +               .procname       = "socket_all",
21958 +               .data           = &grsec_enable_socket_all,
21959 +               .maxlen         = sizeof(int),
21960 +               .mode           = 0600,
21961 +               .proc_handler   = &proc_dointvec,
21962 +       },
21963 +       {
21964 +               .ctl_name       = GS_SOCKET_ALL_GID,
21965 +               .procname       = "socket_all_gid",
21966 +               .data           = &grsec_socket_all_gid,
21967 +               .maxlen         = sizeof(int),
21968 +               .mode           = 0600,
21969 +               .proc_handler   = &proc_dointvec,
21970 +       },
21971 +#endif
21972 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
21973 +       {
21974 +               .ctl_name       = GS_SOCKET_CLIENT,
21975 +               .procname       = "socket_client",
21976 +               .data           = &grsec_enable_socket_client,
21977 +               .maxlen         = sizeof(int),
21978 +               .mode           = 0600,
21979 +               .proc_handler   = &proc_dointvec,
21980 +       },
21981 +       {
21982 +               .ctl_name       = GS_SOCKET_CLIENT_GID,
21983 +               .procname       = "socket_client_gid",
21984 +               .data           = &grsec_socket_client_gid,
21985 +               .maxlen         = sizeof(int),
21986 +               .mode           = 0600,
21987 +               .proc_handler   = &proc_dointvec,
21988 +       },
21989 +#endif
21990 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
21991 +       {
21992 +               .ctl_name       = GS_SOCKET_SERVER,
21993 +               .procname       = "socket_server",
21994 +               .data           = &grsec_enable_socket_server,
21995 +               .maxlen         = sizeof(int),
21996 +               .mode           = 0600,
21997 +               .proc_handler   = &proc_dointvec,
21998 +       },
21999 +       {
22000 +               .ctl_name       = GS_SOCKET_SERVER_GID,
22001 +               .procname       = "socket_server_gid",
22002 +               .data           = &grsec_socket_server_gid,
22003 +               .maxlen         = sizeof(int),
22004 +               .mode           = 0600,
22005 +               .proc_handler   = &proc_dointvec,
22006 +       },
22007 +#endif
22008 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
22009 +       {
22010 +               .ctl_name       = GS_GROUP,
22011 +               .procname       = "audit_group",
22012 +               .data           = &grsec_enable_group,
22013 +               .maxlen         = sizeof(int),
22014 +               .mode           = 0600,
22015 +               .proc_handler   = &proc_dointvec,
22016 +       },
22017 +       {
22018 +               .ctl_name       = GS_GID,
22019 +               .procname       = "audit_gid",
22020 +               .data           = &grsec_audit_gid,
22021 +               .maxlen         = sizeof(int),
22022 +               .mode           = 0600,
22023 +               .proc_handler   = &proc_dointvec,
22024 +       },
22025 +#endif
22026 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22027 +       {
22028 +               .ctl_name       = GS_ACHDIR,
22029 +               .procname       = "audit_chdir",
22030 +               .data           = &grsec_enable_chdir,
22031 +               .maxlen         = sizeof(int),
22032 +               .mode           = 0600,
22033 +               .proc_handler   = &proc_dointvec,
22034 +       },
22035 +#endif
22036 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
22037 +       {
22038 +               .ctl_name       = GS_AMOUNT,
22039 +               .procname       = "audit_mount",
22040 +               .data           = &grsec_enable_mount,
22041 +               .maxlen         = sizeof(int),
22042 +               .mode           = 0600,
22043 +               .proc_handler   = &proc_dointvec,
22044 +       },
22045 +#endif
22046 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
22047 +       {
22048 +               .ctl_name       = GS_AIPC,
22049 +               .procname       = "audit_ipc",
22050 +               .data           = &grsec_enable_audit_ipc,
22051 +               .maxlen         = sizeof(int),
22052 +               .mode           = 0600,
22053 +               .proc_handler   = &proc_dointvec,
22054 +       },
22055 +#endif
22056 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
22057 +       {
22058 +               .ctl_name       = GS_TEXTREL,
22059 +               .procname       = "audit_textrel",
22060 +               .data           = &grsec_enable_audit_textrel,
22061 +               .maxlen         = sizeof(int),
22062 +               .mode           = 0600,
22063 +               .proc_handler   = &proc_dointvec,
22064 +       },
22065 +#endif
22066 +#ifdef CONFIG_GRKERNSEC_DMESG
22067 +       {
22068 +               .ctl_name       = GS_DMSG,
22069 +               .procname       = "dmesg",
22070 +               .data           = &grsec_enable_dmesg,
22071 +               .maxlen         = sizeof(int),
22072 +               .mode           = 0600,
22073 +               .proc_handler   = &proc_dointvec,
22074 +       },
22075 +#endif
22076 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22077 +       {
22078 +               .ctl_name       = GS_FINDTASK,
22079 +               .procname       = "chroot_findtask",
22080 +               .data           = &grsec_enable_chroot_findtask,
22081 +               .maxlen         = sizeof(int),
22082 +               .mode           = 0600,
22083 +               .proc_handler   = &proc_dointvec,
22084 +       },
22085 +#endif
22086 +#ifdef CONFIG_GRKERNSEC_SHM
22087 +       {
22088 +               .ctl_name       = GS_SHM,
22089 +               .procname       = "destroy_unused_shm",
22090 +               .data           = &grsec_enable_shm,
22091 +               .maxlen         = sizeof(int),
22092 +               .mode           = 0600,
22093 +               .proc_handler   = &proc_dointvec,
22094 +       },
22095 +#endif
22096 +#ifdef CONFIG_GRKERNSEC_RESLOG
22097 +       {
22098 +               .ctl_name       = GS_RESLOG,
22099 +               .procname       = "resource_logging",
22100 +               .data           = &grsec_resource_logging,
22101 +               .maxlen         = sizeof(int),
22102 +               .mode           = 0600,
22103 +               .proc_handler   = &proc_dointvec,
22104 +       },
22105 +#endif
22106 +       {
22107 +               .ctl_name       = GS_LOCK,
22108 +               .procname       = "grsec_lock",
22109 +               .data           = &grsec_lock,
22110 +               .maxlen         = sizeof(int),
22111 +               .mode           = 0600,
22112 +               .proc_handler   = &proc_dointvec,
22113 +       },
22114 +#endif
22115 +#ifdef CONFIG_GRKERNSEC_MODSTOP
22116 +       {
22117 +               .ctl_name       = GS_MODSTOP,
22118 +               .procname       = "disable_modules",
22119 +               .data           = &grsec_modstop,
22120 +               .maxlen         = sizeof(int),
22121 +               .mode           = 0600,
22122 +               .proc_handler   = &proc_dointvec,
22123 +       },
22124 +#endif
22125 +       { .ctl_name = 0 }
22126 +};
22127 +#endif
22128 +
22129 +int gr_check_modstop(void)
22130 +{
22131 +#ifdef CONFIG_GRKERNSEC_MODSTOP
22132 +       if (grsec_modstop == 1) {
22133 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
22134 +               return 1;
22135 +       }
22136 +#endif
22137 +       return 0;
22138 +}
22139 diff -urNp linux-2.6.20.3/grsecurity/grsec_textrel.c linux-2.6.20.3/grsecurity/grsec_textrel.c
22140 --- linux-2.6.20.3/grsecurity/grsec_textrel.c   1969-12-31 19:00:00.000000000 -0500
22141 +++ linux-2.6.20.3/grsecurity/grsec_textrel.c   2007-03-23 08:11:31.000000000 -0400
22142 @@ -0,0 +1,16 @@
22143 +#include <linux/kernel.h>
22144 +#include <linux/sched.h>
22145 +#include <linux/mm.h>
22146 +#include <linux/file.h>
22147 +#include <linux/grinternal.h>
22148 +#include <linux/grsecurity.h>
22149 +
22150 +void
22151 +gr_log_textrel(struct vm_area_struct * vma)
22152 +{
22153 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
22154 +       if (grsec_enable_audit_textrel)
22155 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
22156 +#endif
22157 +       return;
22158 +}
22159 diff -urNp linux-2.6.20.3/grsecurity/grsec_time.c linux-2.6.20.3/grsecurity/grsec_time.c
22160 --- linux-2.6.20.3/grsecurity/grsec_time.c      1969-12-31 19:00:00.000000000 -0500
22161 +++ linux-2.6.20.3/grsecurity/grsec_time.c      2007-03-23 08:11:31.000000000 -0400
22162 @@ -0,0 +1,13 @@
22163 +#include <linux/kernel.h>
22164 +#include <linux/sched.h>
22165 +#include <linux/grinternal.h>
22166 +
22167 +void
22168 +gr_log_timechange(void)
22169 +{
22170 +#ifdef CONFIG_GRKERNSEC_TIME
22171 +       if (grsec_enable_time)
22172 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
22173 +#endif
22174 +       return;
22175 +}
22176 diff -urNp linux-2.6.20.3/grsecurity/grsec_tpe.c linux-2.6.20.3/grsecurity/grsec_tpe.c
22177 --- linux-2.6.20.3/grsecurity/grsec_tpe.c       1969-12-31 19:00:00.000000000 -0500
22178 +++ linux-2.6.20.3/grsecurity/grsec_tpe.c       2007-03-23 08:11:31.000000000 -0400
22179 @@ -0,0 +1,37 @@
22180 +#include <linux/kernel.h>
22181 +#include <linux/sched.h>
22182 +#include <linux/file.h>
22183 +#include <linux/fs.h>
22184 +#include <linux/grinternal.h>
22185 +
22186 +extern int gr_acl_tpe_check(void);
22187 +
22188 +int
22189 +gr_tpe_allow(const struct file *file)
22190 +{
22191 +#ifdef CONFIG_GRKERNSEC
22192 +       struct inode *inode = file->f_dentry->d_parent->d_inode;
22193 +
22194 +       if (current->uid && ((grsec_enable_tpe &&
22195 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
22196 +           !in_group_p(grsec_tpe_gid)
22197 +#else
22198 +           in_group_p(grsec_tpe_gid)
22199 +#endif
22200 +           ) || gr_acl_tpe_check()) &&
22201 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
22202 +                                               (inode->i_mode & S_IWOTH))))) {
22203 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
22204 +               return 0;
22205 +       }
22206 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
22207 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
22208 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
22209 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
22210 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_dentry, file->f_vfsmnt);
22211 +               return 0;
22212 +       }
22213 +#endif
22214 +#endif
22215 +       return 1;
22216 +}
22217 diff -urNp linux-2.6.20.3/grsecurity/grsum.c linux-2.6.20.3/grsecurity/grsum.c
22218 --- linux-2.6.20.3/grsecurity/grsum.c   1969-12-31 19:00:00.000000000 -0500
22219 +++ linux-2.6.20.3/grsecurity/grsum.c   2007-03-23 08:11:31.000000000 -0400
22220 @@ -0,0 +1,58 @@
22221 +#include <linux/kernel.h>
22222 +#include <linux/sched.h>
22223 +#include <linux/mm.h>
22224 +#include <linux/scatterlist.h>
22225 +#include <linux/crypto.h>
22226 +#include <linux/gracl.h>
22227 +
22228 +
22229 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
22230 +#error "crypto and sha256 must be built into the kernel"
22231 +#endif
22232 +
22233 +int
22234 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
22235 +{
22236 +       char *p;
22237 +       struct crypto_hash *tfm;
22238 +       struct hash_desc desc;
22239 +       struct scatterlist sg;
22240 +       unsigned char temp_sum[GR_SHA_LEN];
22241 +       volatile int retval = 0;
22242 +       volatile int dummy = 0;
22243 +       unsigned int i;
22244 +
22245 +       tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
22246 +       if (IS_ERR(tfm)) {
22247 +               /* should never happen, since sha256 should be built in */
22248 +               return 1;
22249 +       }
22250 +
22251 +       desc.tfm = tfm;
22252 +       desc.flags = 0;
22253 +
22254 +       crypto_hash_init(&desc);
22255 +
22256 +       p = salt;
22257 +       sg_set_buf(&sg, p, GR_SALT_LEN);
22258 +       crypto_hash_update(&desc, &sg, sg.length);
22259 +
22260 +       p = entry->pw;
22261 +       sg_set_buf(&sg, p, strlen(p));
22262 +       
22263 +       crypto_hash_update(&desc, &sg, sg.length);
22264 +
22265 +       crypto_hash_final(&desc, temp_sum);
22266 +
22267 +       memset(entry->pw, 0, GR_PW_LEN);
22268 +
22269 +       for (i = 0; i < GR_SHA_LEN; i++)
22270 +               if (sum[i] != temp_sum[i])
22271 +                       retval = 1;
22272 +               else
22273 +                       dummy = 1;      // waste a cycle
22274 +
22275 +       crypto_free_hash(tfm);
22276 +
22277 +       return retval;
22278 +}
22279 diff -urNp linux-2.6.20.3/grsecurity/Kconfig linux-2.6.20.3/grsecurity/Kconfig
22280 --- linux-2.6.20.3/grsecurity/Kconfig   1969-12-31 19:00:00.000000000 -0500
22281 +++ linux-2.6.20.3/grsecurity/Kconfig   2007-03-23 08:11:31.000000000 -0400
22282 @@ -0,0 +1,872 @@
22283 +#
22284 +# grecurity configuration
22285 +#
22286 +
22287 +menu "Grsecurity"
22288 +
22289 +config GRKERNSEC
22290 +       bool "Grsecurity"
22291 +       select CRYPTO
22292 +       select CRYPTO_SHA256
22293 +       help
22294 +         If you say Y here, you will be able to configure many features
22295 +         that will enhance the security of your system.  It is highly
22296 +         recommended that you say Y here and read through the help
22297 +         for each option so that you fully understand the features and
22298 +         can evaluate their usefulness for your machine.
22299 +
22300 +choice
22301 +       prompt "Security Level"
22302 +       depends GRKERNSEC
22303 +       default GRKERNSEC_CUSTOM
22304 +
22305 +config GRKERNSEC_LOW
22306 +       bool "Low"
22307 +       select GRKERNSEC_LINK
22308 +       select GRKERNSEC_FIFO
22309 +       select GRKERNSEC_EXECVE
22310 +       select GRKERNSEC_RANDNET
22311 +       select GRKERNSEC_DMESG
22312 +       select GRKERNSEC_CHROOT_CHDIR
22313 +       select GRKERNSEC_MODSTOP if (MODULES)
22314 +
22315 +       help
22316 +         If you choose this option, several of the grsecurity options will
22317 +         be enabled that will give you greater protection against a number
22318 +         of attacks, while assuring that none of your software will have any
22319 +         conflicts with the additional security measures.  If you run a lot
22320 +         of unusual software, or you are having problems with the higher
22321 +         security levels, you should say Y here.  With this option, the
22322 +         following features are enabled:
22323 +
22324 +         - Linking restrictions
22325 +         - FIFO restrictions
22326 +         - Enforcing RLIMIT_NPROC on execve
22327 +         - Restricted dmesg
22328 +         - Enforced chdir("/") on chroot
22329 +         - Runtime module disabling
22330 +
22331 +config GRKERNSEC_MEDIUM
22332 +       bool "Medium"
22333 +       select PAX
22334 +       select PAX_EI_PAX
22335 +       select PAX_PT_PAX_FLAGS
22336 +       select PAX_HAVE_ACL_FLAGS
22337 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22338 +       select GRKERNSEC_CHROOT_SYSCTL
22339 +       select GRKERNSEC_LINK
22340 +       select GRKERNSEC_FIFO
22341 +       select GRKERNSEC_EXECVE
22342 +       select GRKERNSEC_DMESG
22343 +       select GRKERNSEC_RANDNET
22344 +       select GRKERNSEC_FORKFAIL
22345 +       select GRKERNSEC_TIME
22346 +       select GRKERNSEC_SIGNAL
22347 +       select GRKERNSEC_CHROOT
22348 +       select GRKERNSEC_CHROOT_UNIX
22349 +       select GRKERNSEC_CHROOT_MOUNT
22350 +       select GRKERNSEC_CHROOT_PIVOT
22351 +       select GRKERNSEC_CHROOT_DOUBLE
22352 +       select GRKERNSEC_CHROOT_CHDIR
22353 +       select GRKERNSEC_CHROOT_MKNOD
22354 +       select GRKERNSEC_PROC
22355 +       select GRKERNSEC_PROC_USERGROUP
22356 +       select GRKERNSEC_MODSTOP if (MODULES)
22357 +       select PAX_RANDUSTACK
22358 +       select PAX_ASLR
22359 +       select PAX_RANDMMAP
22360 +
22361 +       help
22362 +         If you say Y here, several features in addition to those included
22363 +         in the low additional security level will be enabled.  These
22364 +         features provide even more security to your system, though in rare
22365 +         cases they may be incompatible with very old or poorly written
22366 +         software.  If you enable this option, make sure that your auth
22367 +         service (identd) is running as gid 1001.  With this option, 
22368 +         the following features (in addition to those provided in the 
22369 +         low additional security level) will be enabled:
22370 +
22371 +         - Randomized TCP source ports
22372 +         - Failed fork logging
22373 +         - Time change logging
22374 +         - Signal logging
22375 +         - Deny mounts in chroot
22376 +         - Deny double chrooting
22377 +         - Deny sysctl writes in chroot
22378 +         - Deny mknod in chroot
22379 +         - Deny access to abstract AF_UNIX sockets out of chroot
22380 +         - Deny pivot_root in chroot
22381 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
22382 +         - /proc restrictions with special GID set to 10 (usually wheel)
22383 +         - Address Space Layout Randomization (ASLR)
22384 +
22385 +config GRKERNSEC_HIGH
22386 +       bool "High"
22387 +       select GRKERNSEC_LINK
22388 +       select GRKERNSEC_FIFO
22389 +       select GRKERNSEC_EXECVE
22390 +       select GRKERNSEC_DMESG
22391 +       select GRKERNSEC_FORKFAIL
22392 +       select GRKERNSEC_TIME
22393 +       select GRKERNSEC_SIGNAL
22394 +       select GRKERNSEC_CHROOT_SHMAT
22395 +       select GRKERNSEC_CHROOT_UNIX
22396 +       select GRKERNSEC_CHROOT_MOUNT
22397 +       select GRKERNSEC_CHROOT_FCHDIR
22398 +       select GRKERNSEC_CHROOT_PIVOT
22399 +       select GRKERNSEC_CHROOT_DOUBLE
22400 +       select GRKERNSEC_CHROOT_CHDIR
22401 +       select GRKERNSEC_CHROOT_MKNOD
22402 +       select GRKERNSEC_CHROOT_CAPS
22403 +       select GRKERNSEC_CHROOT_SYSCTL
22404 +       select GRKERNSEC_CHROOT_FINDTASK
22405 +       select GRKERNSEC_PROC
22406 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
22407 +       select GRKERNSEC_HIDESYM
22408 +       select GRKERNSEC_BRUTE
22409 +       select GRKERNSEC_SHM if (SYSVIPC)
22410 +       select GRKERNSEC_PROC_USERGROUP
22411 +       select GRKERNSEC_KMEM
22412 +       select GRKERNSEC_RESLOG
22413 +       select GRKERNSEC_RANDNET
22414 +       select GRKERNSEC_PROC_ADD
22415 +       select GRKERNSEC_CHROOT_CHMOD
22416 +       select GRKERNSEC_CHROOT_NICE
22417 +       select GRKERNSEC_AUDIT_MOUNT
22418 +       select GRKERNSEC_MODSTOP if (MODULES)
22419 +       select PAX
22420 +       select PAX_RANDUSTACK
22421 +       select PAX_ASLR
22422 +       select PAX_RANDMMAP
22423 +       select PAX_NOEXEC
22424 +       select PAX_MPROTECT
22425 +       select PAX_EI_PAX
22426 +       select PAX_PT_PAX_FLAGS
22427 +       select PAX_HAVE_ACL_FLAGS
22428 +       select PAX_KERNEXEC if (!X86_64 && !MODULES && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS)
22429 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
22430 +       select PAX_SEGMEXEC if (X86 && !X86_64)
22431 +       select PAX_PAGEEXEC if (!X86)
22432 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
22433 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
22434 +       select PAX_SYSCALL if (PPC32)
22435 +       select PAX_EMUTRAMP if (PARISC)
22436 +       select PAX_EMUSIGRT if (PARISC)
22437 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
22438 +       help
22439 +         If you say Y here, many of the features of grsecurity will be
22440 +         enabled, which will protect you against many kinds of attacks
22441 +         against your system.  The heightened security comes at a cost
22442 +         of an increased chance of incompatibilities with rare software
22443 +         on your machine.  Since this security level enables PaX, you should
22444 +         view <http://pax.grsecurity.net> and read about the PaX
22445 +         project.  While you are there, download chpax and run it on
22446 +         binaries that cause problems with PaX.  Also remember that
22447 +         since the /proc restrictions are enabled, you must run your
22448 +         identd as gid 1001.  This security level enables the following 
22449 +         features in addition to those listed in the low and medium 
22450 +         security levels:
22451 +
22452 +         - Additional /proc restrictions
22453 +         - Chmod restrictions in chroot
22454 +         - No signals, ptrace, or viewing of processes outside of chroot
22455 +         - Capability restrictions in chroot
22456 +         - Deny fchdir out of chroot
22457 +         - Priority restrictions in chroot
22458 +         - Segmentation-based implementation of PaX
22459 +         - Mprotect restrictions
22460 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
22461 +         - Kernel stack randomization
22462 +         - Mount/unmount/remount logging
22463 +         - Kernel symbol hiding
22464 +         - Destroy unused shared memory        
22465 +         - Prevention of memory exhaustion-based exploits
22466 +config GRKERNSEC_CUSTOM
22467 +       bool "Custom"
22468 +       help
22469 +         If you say Y here, you will be able to configure every grsecurity
22470 +         option, which allows you to enable many more features that aren't
22471 +         covered in the basic security levels.  These additional features
22472 +         include TPE, socket restrictions, and the sysctl system for
22473 +         grsecurity.  It is advised that you read through the help for
22474 +         each option to determine its usefulness in your situation.
22475 +
22476 +endchoice
22477 +
22478 +menu "Address Space Protection"
22479 +depends on GRKERNSEC
22480 +
22481 +config GRKERNSEC_KMEM
22482 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
22483 +       help
22484 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
22485 +         be written to via mmap or otherwise to modify the running kernel.
22486 +         /dev/port will also not be allowed to be opened. If you have module
22487 +         support disabled, enabling this will close up four ways that are
22488 +         currently used  to insert malicious code into the running kernel.
22489 +         Even with all these features enabled, we still highly recommend that
22490 +         you use the RBAC system, as it is still possible for an attacker to
22491 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
22492 +         If you are not using XFree86, you may be able to stop this additional
22493 +         case by enabling the 'Disable privileged I/O' option. Though nothing
22494 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
22495 +         but only to video memory, which is the only writing we allow in this
22496 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
22497 +         not be allowed to mprotect it with PROT_WRITE later.
22498 +         It is highly recommended that you say Y here if you meet all the
22499 +         conditions above.
22500 +
22501 +config GRKERNSEC_IO
22502 +       bool "Disable privileged I/O"
22503 +       depends on X86
22504 +       select RTC
22505 +       help
22506 +         If you say Y here, all ioperm and iopl calls will return an error.
22507 +         Ioperm and iopl can be used to modify the running kernel.
22508 +         Unfortunately, some programs need this access to operate properly,
22509 +         the most notable of which are XFree86 and hwclock.  hwclock can be
22510 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
22511 +         enabled if this option is enabled, to ensure that hwclock operates
22512 +         correctly.  XFree86 still will not operate correctly with this option
22513 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
22514 +         and you still want to protect your kernel against modification,
22515 +         use the RBAC system.
22516 +
22517 +config GRKERNSEC_PROC_MEMMAP
22518 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
22519 +       depends on PAX_NOEXEC || PAX_ASLR
22520 +       help
22521 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
22522 +         give no information about the addresses of its mappings if
22523 +         PaX features that rely on random addresses are enabled on the task.
22524 +         If you use PaX it is greatly recommended that you say Y here as it
22525 +         closes up a hole that makes the full ASLR useless for suid
22526 +         binaries.
22527 +
22528 +config GRKERNSEC_BRUTE
22529 +       bool "Deter exploit bruteforcing"
22530 +       help
22531 +         If you say Y here, attempts to bruteforce exploits against forking
22532 +         daemons such as apache or sshd will be deterred.  When a child of a
22533 +         forking daemon is killed by PaX or crashes due to an illegal
22534 +         instruction, the parent process will be delayed 30 seconds upon every
22535 +         subsequent fork until the administrator is able to assess the
22536 +         situation and restart the daemon.  It is recommended that you also
22537 +         enable signal logging in the auditing section so that logs are
22538 +         generated when a process performs an illegal instruction.
22539 +
22540 +config GRKERNSEC_MODSTOP
22541 +       bool "Runtime module disabling"
22542 +       depends on MODULES
22543 +       help
22544 +         If you say Y here, you will be able to disable the ability to (un)load
22545 +         modules at runtime.  This feature is useful if you need the ability
22546 +         to load kernel modules at boot time, but do not want to allow an
22547 +         attacker to load a rootkit kernel module into the system, or to remove
22548 +         a loaded kernel module important to system functioning.  You should
22549 +         enable the /dev/mem protection feature as well, since rootkits can be
22550 +         inserted into the kernel via other methods than kernel modules.  Since
22551 +         an untrusted module could still be loaded by modifying init scripts and
22552 +         rebooting the system, it is also recommended that you enable the RBAC
22553 +         system.  If you enable this option, a sysctl option with name
22554 +         "disable_modules" will be created.  Setting this option to "1" disables
22555 +         module loading.  After this option is set, no further writes to it are
22556 +         allowed until the system is rebooted.
22557 +
22558 +config GRKERNSEC_HIDESYM
22559 +       bool "Hide kernel symbols"
22560 +       help
22561 +         If you say Y here, getting information on loaded modules, and
22562 +         displaying all kernel symbols through a syscall will be restricted
22563 +         to users with CAP_SYS_MODULE.  This option is only effective
22564 +         provided the following conditions are met:
22565 +         1) The kernel using grsecurity is not precompiled by some distribution
22566 +         2) You are using the RBAC system and hiding other files such as your
22567 +            kernel image and System.map
22568 +         3) You have the additional /proc restrictions enabled, which removes
22569 +            /proc/kcore
22570 +         If the above conditions are met, this option will aid to provide a
22571 +         useful protection against local and remote kernel exploitation of
22572 +         overflows and arbitrary read/write vulnerabilities.
22573 +
22574 +endmenu
22575 +menu "Role Based Access Control Options"
22576 +depends on GRKERNSEC
22577 +
22578 +config GRKERNSEC_ACL_HIDEKERN
22579 +       bool "Hide kernel processes"
22580 +       help
22581 +         If you say Y here, all kernel threads will be hidden to all
22582 +         processes but those whose subject has the "view hidden processes"
22583 +         flag.
22584 +
22585 +config GRKERNSEC_ACL_MAXTRIES
22586 +       int "Maximum tries before password lockout"
22587 +       default 3
22588 +       help
22589 +         This option enforces the maximum number of times a user can attempt
22590 +         to authorize themselves with the grsecurity RBAC system before being
22591 +         denied the ability to attempt authorization again for a specified time.
22592 +         The lower the number, the harder it will be to brute-force a password.
22593 +
22594 +config GRKERNSEC_ACL_TIMEOUT
22595 +       int "Time to wait after max password tries, in seconds"
22596 +       default 30
22597 +       help
22598 +         This option specifies the time the user must wait after attempting to
22599 +         authorize to the RBAC system with the maximum number of invalid
22600 +         passwords.  The higher the number, the harder it will be to brute-force
22601 +         a password.
22602 +
22603 +endmenu
22604 +menu "Filesystem Protections"
22605 +depends on GRKERNSEC
22606 +
22607 +config GRKERNSEC_PROC
22608 +       bool "Proc restrictions"
22609 +       help
22610 +         If you say Y here, the permissions of the /proc filesystem
22611 +         will be altered to enhance system security and privacy.  You MUST
22612 +         choose either a user only restriction or a user and group restriction.
22613 +         Depending upon the option you choose, you can either restrict users to
22614 +         see only the processes they themselves run, or choose a group that can
22615 +         view all processes and files normally restricted to root if you choose
22616 +         the "restrict to user only" option.  NOTE: If you're running identd as
22617 +         a non-root user, you will have to run it as the group you specify here.
22618 +
22619 +config GRKERNSEC_PROC_USER
22620 +       bool "Restrict /proc to user only"
22621 +       depends on GRKERNSEC_PROC
22622 +       help
22623 +         If you say Y here, non-root users will only be able to view their own
22624 +         processes, and restricts them from viewing network-related information,
22625 +         and viewing kernel symbol and module information.
22626 +
22627 +config GRKERNSEC_PROC_USERGROUP
22628 +       bool "Allow special group"
22629 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
22630 +       help
22631 +         If you say Y here, you will be able to select a group that will be
22632 +         able to view all processes, network-related information, and
22633 +         kernel and symbol information.  This option is useful if you want
22634 +         to run identd as a non-root user.
22635 +
22636 +config GRKERNSEC_PROC_GID
22637 +       int "GID for special group"
22638 +       depends on GRKERNSEC_PROC_USERGROUP
22639 +       default 1001
22640 +
22641 +config GRKERNSEC_PROC_ADD
22642 +       bool "Additional restrictions"
22643 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
22644 +       help
22645 +         If you say Y here, additional restrictions will be placed on
22646 +         /proc that keep normal users from viewing device information and 
22647 +         slabinfo information that could be useful for exploits.
22648 +
22649 +config GRKERNSEC_LINK
22650 +       bool "Linking restrictions"
22651 +       help
22652 +         If you say Y here, /tmp race exploits will be prevented, since users
22653 +         will no longer be able to follow symlinks owned by other users in
22654 +         world-writable +t directories (i.e. /tmp), unless the owner of the
22655 +         symlink is the owner of the directory. users will also not be
22656 +         able to hardlink to files they do not own.  If the sysctl option is
22657 +         enabled, a sysctl option with name "linking_restrictions" is created.
22658 +
22659 +config GRKERNSEC_FIFO
22660 +       bool "FIFO restrictions"
22661 +       help
22662 +         If you say Y here, users will not be able to write to FIFOs they don't
22663 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
22664 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
22665 +         option is enabled, a sysctl option with name "fifo_restrictions" is
22666 +         created.
22667 +
22668 +config GRKERNSEC_CHROOT
22669 +       bool "Chroot jail restrictions"
22670 +       help
22671 +         If you say Y here, you will be able to choose several options that will
22672 +         make breaking out of a chrooted jail much more difficult.  If you
22673 +         encounter no software incompatibilities with the following options, it
22674 +         is recommended that you enable each one.
22675 +
22676 +config GRKERNSEC_CHROOT_MOUNT
22677 +       bool "Deny mounts"
22678 +       depends on GRKERNSEC_CHROOT
22679 +       help
22680 +         If you say Y here, processes inside a chroot will not be able to
22681 +         mount or remount filesystems.  If the sysctl option is enabled, a
22682 +         sysctl option with name "chroot_deny_mount" is created.
22683 +
22684 +config GRKERNSEC_CHROOT_DOUBLE
22685 +       bool "Deny double-chroots"
22686 +       depends on GRKERNSEC_CHROOT
22687 +       help
22688 +         If you say Y here, processes inside a chroot will not be able to chroot
22689 +         again outside the chroot.  This is a widely used method of breaking
22690 +         out of a chroot jail and should not be allowed.  If the sysctl 
22691 +         option is enabled, a sysctl option with name 
22692 +         "chroot_deny_chroot" is created.
22693 +
22694 +config GRKERNSEC_CHROOT_PIVOT
22695 +       bool "Deny pivot_root in chroot"
22696 +       depends on GRKERNSEC_CHROOT
22697 +       help
22698 +         If you say Y here, processes inside a chroot will not be able to use
22699 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
22700 +         works similar to chroot in that it changes the root filesystem.  This
22701 +         function could be misused in a chrooted process to attempt to break out
22702 +         of the chroot, and therefore should not be allowed.  If the sysctl
22703 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
22704 +         created.
22705 +
22706 +config GRKERNSEC_CHROOT_CHDIR
22707 +       bool "Enforce chdir(\"/\") on all chroots"
22708 +       depends on GRKERNSEC_CHROOT
22709 +       help
22710 +         If you say Y here, the current working directory of all newly-chrooted
22711 +         applications will be set to the the root directory of the chroot.
22712 +         The man page on chroot(2) states:
22713 +         Note that this call does not change  the  current  working
22714 +         directory,  so  that `.' can be outside the tree rooted at
22715 +         `/'.  In particular, the  super-user  can  escape  from  a
22716 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
22717 +
22718 +         It is recommended that you say Y here, since it's not known to break
22719 +         any software.  If the sysctl option is enabled, a sysctl option with
22720 +         name "chroot_enforce_chdir" is created.
22721 +
22722 +config GRKERNSEC_CHROOT_CHMOD
22723 +       bool "Deny (f)chmod +s"
22724 +       depends on GRKERNSEC_CHROOT
22725 +       help
22726 +         If you say Y here, processes inside a chroot will not be able to chmod
22727 +         or fchmod files to make them have suid or sgid bits.  This protects
22728 +         against another published method of breaking a chroot.  If the sysctl
22729 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
22730 +         created.
22731 +
22732 +config GRKERNSEC_CHROOT_FCHDIR
22733 +       bool "Deny fchdir out of chroot"
22734 +       depends on GRKERNSEC_CHROOT
22735 +       help
22736 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
22737 +         to a file descriptor of the chrooting process that points to a directory
22738 +         outside the filesystem will be stopped.  If the sysctl option
22739 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
22740 +
22741 +config GRKERNSEC_CHROOT_MKNOD
22742 +       bool "Deny mknod"
22743 +       depends on GRKERNSEC_CHROOT
22744 +       help
22745 +         If you say Y here, processes inside a chroot will not be allowed to
22746 +         mknod.  The problem with using mknod inside a chroot is that it
22747 +         would allow an attacker to create a device entry that is the same
22748 +         as one on the physical root of your system, which could range from
22749 +         anything from the console device to a device for your harddrive (which
22750 +         they could then use to wipe the drive or steal data).  It is recommended
22751 +         that you say Y here, unless you run into software incompatibilities.
22752 +         If the sysctl option is enabled, a sysctl option with name
22753 +         "chroot_deny_mknod" is created.
22754 +
22755 +config GRKERNSEC_CHROOT_SHMAT
22756 +       bool "Deny shmat() out of chroot"
22757 +       depends on GRKERNSEC_CHROOT
22758 +       help
22759 +         If you say Y here, processes inside a chroot will not be able to attach
22760 +         to shared memory segments that were created outside of the chroot jail.
22761 +         It is recommended that you say Y here.  If the sysctl option is enabled,
22762 +         a sysctl option with name "chroot_deny_shmat" is created.
22763 +
22764 +config GRKERNSEC_CHROOT_UNIX
22765 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
22766 +       depends on GRKERNSEC_CHROOT
22767 +       help
22768 +         If you say Y here, processes inside a chroot will not be able to
22769 +         connect to abstract (meaning not belonging to a filesystem) Unix
22770 +         domain sockets that were bound outside of a chroot.  It is recommended
22771 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
22772 +         with name "chroot_deny_unix" is created.
22773 +
22774 +config GRKERNSEC_CHROOT_FINDTASK
22775 +       bool "Protect outside processes"
22776 +       depends on GRKERNSEC_CHROOT
22777 +       help
22778 +         If you say Y here, processes inside a chroot will not be able to
22779 +         kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
22780 +         or view any process outside of the chroot.  If the sysctl
22781 +         option is enabled, a sysctl option with name "chroot_findtask" is
22782 +         created.
22783 +
22784 +config GRKERNSEC_CHROOT_NICE
22785 +       bool "Restrict priority changes"
22786 +       depends on GRKERNSEC_CHROOT
22787 +       help
22788 +         If you say Y here, processes inside a chroot will not be able to raise
22789 +         the priority of processes in the chroot, or alter the priority of
22790 +         processes outside the chroot.  This provides more security than simply
22791 +         removing CAP_SYS_NICE from the process' capability set.  If the
22792 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
22793 +         is created.
22794 +
22795 +config GRKERNSEC_CHROOT_SYSCTL
22796 +       bool "Deny sysctl writes"
22797 +       depends on GRKERNSEC_CHROOT
22798 +       help
22799 +         If you say Y here, an attacker in a chroot will not be able to
22800 +         write to sysctl entries, either by sysctl(2) or through a /proc
22801 +         interface.  It is strongly recommended that you say Y here. If the
22802 +         sysctl option is enabled, a sysctl option with name
22803 +         "chroot_deny_sysctl" is created.
22804 +
22805 +config GRKERNSEC_CHROOT_CAPS
22806 +       bool "Capability restrictions"
22807 +       depends on GRKERNSEC_CHROOT
22808 +       help
22809 +         If you say Y here, the capabilities on all root processes within a
22810 +         chroot jail will be lowered to stop module insertion, raw i/o,
22811 +         system and net admin tasks, rebooting the system, modifying immutable
22812 +         files, modifying IPC owned by another, and changing the system time.
22813 +         This is left an option because it can break some apps.  Disable this
22814 +         if your chrooted apps are having problems performing those kinds of
22815 +         tasks.  If the sysctl option is enabled, a sysctl option with
22816 +         name "chroot_caps" is created.
22817 +
22818 +endmenu
22819 +menu "Kernel Auditing"
22820 +depends on GRKERNSEC
22821 +
22822 +config GRKERNSEC_AUDIT_GROUP
22823 +       bool "Single group for auditing"
22824 +       help
22825 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
22826 +         will only operate on a group you specify.  This option is recommended
22827 +         if you only want to watch certain users instead of having a large
22828 +         amount of logs from the entire system.  If the sysctl option is enabled,
22829 +         a sysctl option with name "audit_group" is created.
22830 +
22831 +config GRKERNSEC_AUDIT_GID
22832 +       int "GID for auditing"
22833 +       depends on GRKERNSEC_AUDIT_GROUP
22834 +       default 1007
22835 +
22836 +config GRKERNSEC_EXECLOG
22837 +       bool "Exec logging"
22838 +       help
22839 +         If you say Y here, all execve() calls will be logged (since the
22840 +         other exec*() calls are frontends to execve(), all execution
22841 +         will be logged).  Useful for shell-servers that like to keep track
22842 +         of their users.  If the sysctl option is enabled, a sysctl option with
22843 +         name "exec_logging" is created.
22844 +         WARNING: This option when enabled will produce a LOT of logs, especially
22845 +         on an active system.
22846 +
22847 +config GRKERNSEC_RESLOG
22848 +       bool "Resource logging"
22849 +       help
22850 +         If you say Y here, all attempts to overstep resource limits will
22851 +         be logged with the resource name, the requested size, and the current
22852 +         limit.  It is highly recommended that you say Y here.  If the sysctl
22853 +         option is enabled, a sysctl option with name "resource_logging" is
22854 +         created.  If the RBAC system is enabled, the sysctl value is ignored.
22855 +
22856 +config GRKERNSEC_CHROOT_EXECLOG
22857 +       bool "Log execs within chroot"
22858 +       help
22859 +         If you say Y here, all executions inside a chroot jail will be logged
22860 +         to syslog.  This can cause a large amount of logs if certain
22861 +         applications (eg. djb's daemontools) are installed on the system, and
22862 +         is therefore left as an option.  If the sysctl option is enabled, a
22863 +         sysctl option with name "chroot_execlog" is created.
22864 +
22865 +config GRKERNSEC_AUDIT_CHDIR
22866 +       bool "Chdir logging"
22867 +       help
22868 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
22869 +         option is enabled, a sysctl option with name "audit_chdir" is created.
22870 +
22871 +config GRKERNSEC_AUDIT_MOUNT
22872 +       bool "(Un)Mount logging"
22873 +       help
22874 +         If you say Y here, all mounts and unmounts will be logged.  If the
22875 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
22876 +         created.
22877 +
22878 +config GRKERNSEC_AUDIT_IPC
22879 +       bool "IPC logging"
22880 +       help
22881 +         If you say Y here, creation and removal of message queues, semaphores,
22882 +         and shared memory will be logged.  If the sysctl option is enabled, a
22883 +         sysctl option with name "audit_ipc" is created.
22884 +
22885 +config GRKERNSEC_SIGNAL
22886 +       bool "Signal logging"
22887 +       help
22888 +         If you say Y here, certain important signals will be logged, such as
22889 +         SIGSEGV, which will as a result inform you of when a error in a program
22890 +         occurred, which in some cases could mean a possible exploit attempt.
22891 +         If the sysctl option is enabled, a sysctl option with name
22892 +         "signal_logging" is created.
22893 +
22894 +config GRKERNSEC_FORKFAIL
22895 +       bool "Fork failure logging"
22896 +       help
22897 +         If you say Y here, all failed fork() attempts will be logged.
22898 +         This could suggest a fork bomb, or someone attempting to overstep
22899 +         their process limit.  If the sysctl option is enabled, a sysctl option
22900 +         with name "forkfail_logging" is created.
22901 +
22902 +config GRKERNSEC_TIME
22903 +       bool "Time change logging"
22904 +       help
22905 +         If you say Y here, any changes of the system clock will be logged.
22906 +         If the sysctl option is enabled, a sysctl option with name
22907 +         "timechange_logging" is created.
22908 +
22909 +config GRKERNSEC_PROC_IPADDR
22910 +       bool "/proc/<pid>/ipaddr support"
22911 +       help
22912 +         If you say Y here, a new entry will be added to each /proc/<pid>
22913 +         directory that contains the IP address of the person using the task.
22914 +         The IP is carried across local TCP and AF_UNIX stream sockets.
22915 +         This information can be useful for IDS/IPSes to perform remote response
22916 +         to a local attack.  The entry is readable by only the owner of the
22917 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
22918 +         the RBAC system), and thus does not create privacy concerns.
22919 +
22920 +config GRKERNSEC_AUDIT_TEXTREL
22921 +       bool 'ELF text relocations logging (READ HELP)'
22922 +       depends on PAX_MPROTECT
22923 +       help
22924 +         If you say Y here, text relocations will be logged with the filename
22925 +         of the offending library or binary.  The purpose of the feature is
22926 +         to help Linux distribution developers get rid of libraries and
22927 +         binaries that need text relocations which hinder the future progress
22928 +         of PaX.  Only Linux distribution developers should say Y here, and
22929 +         never on a production machine, as this option creates an information
22930 +         leak that could aid an attacker in defeating the randomization of
22931 +         a single memory region.  If the sysctl option is enabled, a sysctl
22932 +         option with name "audit_textrel" is created.
22933 +
22934 +endmenu
22935 +
22936 +menu "Executable Protections"
22937 +depends on GRKERNSEC
22938 +
22939 +config GRKERNSEC_EXECVE
22940 +       bool "Enforce RLIMIT_NPROC on execs"
22941 +       help
22942 +         If you say Y here, users with a resource limit on processes will
22943 +         have the value checked during execve() calls.  The current system
22944 +         only checks the system limit during fork() calls.  If the sysctl option
22945 +         is enabled, a sysctl option with name "execve_limiting" is created.
22946 +
22947 +config GRKERNSEC_SHM
22948 +       bool "Destroy unused shared memory"
22949 +       depends on SYSVIPC
22950 +       help
22951 +         If you say Y here, shared memory will be destroyed when no one is
22952 +         attached to it.  Otherwise, resources involved with the shared
22953 +         memory can be used up and not be associated with any process (as the
22954 +         shared memory still exists, and the creating process has exited).  If
22955 +         the sysctl option is enabled, a sysctl option with name
22956 +         "destroy_unused_shm" is created.
22957 +
22958 +config GRKERNSEC_DMESG
22959 +       bool "Dmesg(8) restriction"
22960 +       help
22961 +         If you say Y here, non-root users will not be able to use dmesg(8)
22962 +         to view up to the last 4kb of messages in the kernel's log buffer.
22963 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
22964 +         created.
22965 +
22966 +config GRKERNSEC_TPE
22967 +       bool "Trusted Path Execution (TPE)"
22968 +       help
22969 +         If you say Y here, you will be able to choose a gid to add to the
22970 +         supplementary groups of users you want to mark as "untrusted."
22971 +         These users will not be able to execute any files that are not in
22972 +         root-owned directories writable only by root.  If the sysctl option
22973 +         is enabled, a sysctl option with name "tpe" is created.
22974 +
22975 +config GRKERNSEC_TPE_ALL
22976 +       bool "Partially restrict non-root users"
22977 +       depends on GRKERNSEC_TPE
22978 +       help
22979 +         If you say Y here, All non-root users other than the ones in the
22980 +         group specified in the main TPE option will only be allowed to
22981 +         execute files in directories they own that are not group or
22982 +         world-writable, or in directories owned by root and writable only by
22983 +         root.  If the sysctl option is enabled, a sysctl option with name
22984 +         "tpe_restrict_all" is created.
22985 +
22986 +config GRKERNSEC_TPE_INVERT
22987 +       bool "Invert GID option"
22988 +       depends on GRKERNSEC_TPE
22989 +       help
22990 +         If you say Y here, the group you specify in the TPE configuration will
22991 +         decide what group TPE restrictions will be *disabled* for.  This
22992 +         option is useful if you want TPE restrictions to be applied to most
22993 +         users on the system.
22994 +
22995 +config GRKERNSEC_TPE_GID
22996 +       int "GID for untrusted users"
22997 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
22998 +       default 1005
22999 +       help
23000 +         If you have selected the "Invert GID option" above, setting this
23001 +         GID determines what group TPE restrictions will be *disabled* for.
23002 +         If you have not selected the "Invert GID option" above, setting this
23003 +         GID determines what group TPE restrictions will be *enabled* for.
23004 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23005 +         is created.
23006 +
23007 +config GRKERNSEC_TPE_GID
23008 +       int "GID for trusted users"
23009 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
23010 +       default 1005
23011 +       help
23012 +         If you have selected the "Invert GID option" above, setting this
23013 +         GID determines what group TPE restrictions will be *disabled* for.
23014 +         If you have not selected the "Invert GID option" above, setting this
23015 +         GID determines what group TPE restrictions will be *enabled* for.
23016 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
23017 +         is created.
23018 +
23019 +endmenu
23020 +menu "Network Protections"
23021 +depends on GRKERNSEC
23022 +
23023 +config GRKERNSEC_RANDNET
23024 +       bool "Larger entropy pools"
23025 +       help
23026 +         If you say Y here, the entropy pools used for many features of Linux
23027 +         and grsecurity will be doubled in size.  Since several grsecurity
23028 +         features use additional randomness, it is recommended that you say Y
23029 +         here.  Saying Y here has a similar effect as modifying
23030 +         /proc/sys/kernel/random/poolsize.
23031 +
23032 +config GRKERNSEC_SOCKET
23033 +       bool "Socket restrictions"
23034 +       help
23035 +         If you say Y here, you will be able to choose from several options.
23036 +         If you assign a GID on your system and add it to the supplementary
23037 +         groups of users you want to restrict socket access to, this patch
23038 +         will perform up to three things, based on the option(s) you choose.
23039 +
23040 +config GRKERNSEC_SOCKET_ALL
23041 +       bool "Deny any sockets to group"
23042 +       depends on GRKERNSEC_SOCKET
23043 +       help
23044 +         If you say Y here, you will be able to choose a GID of whose users will
23045 +         be unable to connect to other hosts from your machine or run server
23046 +         applications from your machine.  If the sysctl option is enabled, a
23047 +         sysctl option with name "socket_all" is created.
23048 +
23049 +config GRKERNSEC_SOCKET_ALL_GID
23050 +       int "GID to deny all sockets for"
23051 +       depends on GRKERNSEC_SOCKET_ALL
23052 +       default 1004
23053 +       help
23054 +         Here you can choose the GID to disable socket access for. Remember to
23055 +         add the users you want socket access disabled for to the GID
23056 +         specified here.  If the sysctl option is enabled, a sysctl option
23057 +         with name "socket_all_gid" is created.
23058 +
23059 +config GRKERNSEC_SOCKET_CLIENT
23060 +       bool "Deny client sockets to group"
23061 +       depends on GRKERNSEC_SOCKET
23062 +       help
23063 +         If you say Y here, you will be able to choose a GID of whose users will
23064 +         be unable to connect to other hosts from your machine, but will be
23065 +         able to run servers.  If this option is enabled, all users in the group
23066 +         you specify will have to use passive mode when initiating ftp transfers
23067 +         from the shell on your machine.  If the sysctl option is enabled, a
23068 +         sysctl option with name "socket_client" is created.
23069 +
23070 +config GRKERNSEC_SOCKET_CLIENT_GID
23071 +       int "GID to deny client sockets for"
23072 +       depends on GRKERNSEC_SOCKET_CLIENT
23073 +       default 1003
23074 +       help
23075 +         Here you can choose the GID to disable client socket access for.
23076 +         Remember to add the users you want client socket access disabled for to
23077 +         the GID specified here.  If the sysctl option is enabled, a sysctl
23078 +         option with name "socket_client_gid" is created.
23079 +
23080 +config GRKERNSEC_SOCKET_SERVER
23081 +       bool "Deny server sockets to group"
23082 +       depends on GRKERNSEC_SOCKET
23083 +       help
23084 +         If you say Y here, you will be able to choose a GID of whose users will
23085 +         be unable to run server applications from your machine.  If the sysctl
23086 +         option is enabled, a sysctl option with name "socket_server" is created.
23087 +
23088 +config GRKERNSEC_SOCKET_SERVER_GID
23089 +       int "GID to deny server sockets for"
23090 +       depends on GRKERNSEC_SOCKET_SERVER
23091 +       default 1002
23092 +       help
23093 +         Here you can choose the GID to disable server socket access for.
23094 +         Remember to add the users you want server socket access disabled for to
23095 +         the GID specified here.  If the sysctl option is enabled, a sysctl
23096 +         option with name "socket_server_gid" is created.
23097 +
23098 +endmenu
23099 +menu "Sysctl support"
23100 +depends on GRKERNSEC && SYSCTL
23101 +
23102 +config GRKERNSEC_SYSCTL
23103 +       bool "Sysctl support"
23104 +       help
23105 +         If you say Y here, you will be able to change the options that
23106 +         grsecurity runs with at bootup, without having to recompile your
23107 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
23108 +         to enable (1) or disable (0) various features.  All the sysctl entries
23109 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
23110 +         All features enabled in the kernel configuration are disabled at boot
23111 +         if you do not say Y to the "Turn on features by default" option.
23112 +         All options should be set at startup, and the grsec_lock entry should
23113 +         be set to a non-zero value after all the options are set.
23114 +         *THIS IS EXTREMELY IMPORTANT*
23115 +
23116 +config GRKERNSEC_SYSCTL_ON
23117 +       bool "Turn on features by default"
23118 +       depends on GRKERNSEC_SYSCTL
23119 +       help
23120 +         If you say Y here, instead of having all features enabled in the
23121 +         kernel configuration disabled at boot time, the features will be
23122 +         enabled at boot time.  It is recommended you say Y here unless
23123 +         there is some reason you would want all sysctl-tunable features to
23124 +         be disabled by default.  As mentioned elsewhere, it is important
23125 +         to enable the grsec_lock entry once you have finished modifying
23126 +         the sysctl entries.
23127 +
23128 +endmenu
23129 +menu "Logging Options"
23130 +depends on GRKERNSEC
23131 +
23132 +config GRKERNSEC_FLOODTIME
23133 +       int "Seconds in between log messages (minimum)"
23134 +       default 10
23135 +       help
23136 +         This option allows you to enforce the number of seconds between
23137 +         grsecurity log messages.  The default should be suitable for most
23138 +         people, however, if you choose to change it, choose a value small enough
23139 +         to allow informative logs to be produced, but large enough to
23140 +         prevent flooding.
23141 +
23142 +config GRKERNSEC_FLOODBURST
23143 +       int "Number of messages in a burst (maximum)"
23144 +       default 4
23145 +       help
23146 +         This option allows you to choose the maximum number of messages allowed
23147 +         within the flood time interval you chose in a separate option.  The
23148 +         default should be suitable for most people, however if you find that
23149 +         many of your logs are being interpreted as flooding, you may want to
23150 +         raise this value.
23151 +
23152 +endmenu
23153 +
23154 +endmenu
23155 diff -urNp linux-2.6.20.3/grsecurity/Makefile linux-2.6.20.3/grsecurity/Makefile
23156 --- linux-2.6.20.3/grsecurity/Makefile  1969-12-31 19:00:00.000000000 -0500
23157 +++ linux-2.6.20.3/grsecurity/Makefile  2007-03-23 08:11:31.000000000 -0400
23158 @@ -0,0 +1,20 @@
23159 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
23160 +# during 2001-2005 it has been completely redesigned by Brad Spengler
23161 +# into an RBAC system
23162 +#
23163 +# All code in this directory and various hooks inserted throughout the kernel
23164 +# are copyright Brad Spengler, and released under the GPL v2 or higher
23165 +
23166 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
23167 +       grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
23168 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
23169 +
23170 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
23171 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
23172 +       gracl_learn.o grsec_log.o
23173 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
23174 +
23175 +ifndef CONFIG_GRKERNSEC
23176 +obj-y += grsec_disabled.o
23177 +endif
23178 +
23179 diff -urNp linux-2.6.20.3/include/acpi/acmacros.h linux-2.6.20.3/include/acpi/acmacros.h
23180 --- linux-2.6.20.3/include/acpi/acmacros.h      2007-03-13 14:27:08.000000000 -0400
23181 +++ linux-2.6.20.3/include/acpi/acmacros.h      2007-03-23 08:10:06.000000000 -0400
23182 @@ -672,7 +672,7 @@
23183  #define ACPI_DUMP_PATHNAME(a,b,c,d)
23184  #define ACPI_DUMP_RESOURCE_LIST(a)
23185  #define ACPI_DUMP_BUFFER(a,b)
23186 -#define ACPI_DEBUG_PRINT(pl)
23187 +#define ACPI_DEBUG_PRINT(pl) do {} while (0)
23188  #define ACPI_DEBUG_PRINT_RAW(pl)
23189  
23190  #define return_VOID                     return
23191 diff -urNp linux-2.6.20.3/include/asm-alpha/a.out.h linux-2.6.20.3/include/asm-alpha/a.out.h
23192 --- linux-2.6.20.3/include/asm-alpha/a.out.h    2007-03-13 14:27:08.000000000 -0400
23193 +++ linux-2.6.20.3/include/asm-alpha/a.out.h    2007-03-23 08:10:06.000000000 -0400
23194 @@ -98,7 +98,7 @@ struct exec
23195         set_personality (((BFPM->sh_bang || EX.ah.entry < 0x100000000L \
23196                            ? ADDR_LIMIT_32BIT : 0) | PER_OSF4))
23197  
23198 -#define STACK_TOP \
23199 +#define __STACK_TOP \
23200    (current->personality & ADDR_LIMIT_32BIT ? 0x80000000 : 0x00120000000UL)
23201  
23202  #endif
23203 diff -urNp linux-2.6.20.3/include/asm-alpha/elf.h linux-2.6.20.3/include/asm-alpha/elf.h
23204 --- linux-2.6.20.3/include/asm-alpha/elf.h      2007-03-13 14:27:08.000000000 -0400
23205 +++ linux-2.6.20.3/include/asm-alpha/elf.h      2007-03-23 08:10:06.000000000 -0400
23206 @@ -91,6 +91,17 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
23207  
23208  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
23209  
23210 +#ifdef CONFIG_PAX_ASLR
23211 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
23212 +
23213 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
23214 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
23215 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
23216 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 28)
23217 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
23218 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality & ADDR_LIMIT_32BIT ? 14 : 19)
23219 +#endif
23220 +
23221  /* $0 is set by ld.so to a pointer to a function which might be 
23222     registered using atexit.  This provides a mean for the dynamic
23223     linker to call DT_FINI functions for shared libraries that have
23224 diff -urNp linux-2.6.20.3/include/asm-alpha/kmap_types.h linux-2.6.20.3/include/asm-alpha/kmap_types.h
23225 --- linux-2.6.20.3/include/asm-alpha/kmap_types.h       2007-03-13 14:27:08.000000000 -0400
23226 +++ linux-2.6.20.3/include/asm-alpha/kmap_types.h       2007-03-23 08:10:06.000000000 -0400
23227 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
23228  D(10)  KM_IRQ1,
23229  D(11)  KM_SOFTIRQ0,
23230  D(12)  KM_SOFTIRQ1,
23231 -D(13)  KM_TYPE_NR
23232 +D(13)  KM_CLEARPAGE,
23233 +D(14)  KM_TYPE_NR
23234  };
23235  
23236  #undef D
23237 diff -urNp linux-2.6.20.3/include/asm-alpha/page.h linux-2.6.20.3/include/asm-alpha/page.h
23238 --- linux-2.6.20.3/include/asm-alpha/page.h     2007-03-13 14:27:08.000000000 -0400
23239 +++ linux-2.6.20.3/include/asm-alpha/page.h     2007-03-23 08:10:06.000000000 -0400
23240 @@ -93,6 +93,15 @@ typedef unsigned long pgprot_t;
23241  #define VM_DATA_DEFAULT_FLAGS          (VM_READ | VM_WRITE | VM_EXEC | \
23242                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
23243  
23244 +#ifdef CONFIG_PAX_PAGEEXEC
23245 +#ifdef CONFIG_PAX_MPROTECT
23246 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
23247 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
23248 +#else
23249 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
23250 +#endif
23251 +#endif
23252 +
23253  #include <asm-generic/memory_model.h>
23254  #include <asm-generic/page.h>
23255  
23256 diff -urNp linux-2.6.20.3/include/asm-alpha/pgtable.h linux-2.6.20.3/include/asm-alpha/pgtable.h
23257 --- linux-2.6.20.3/include/asm-alpha/pgtable.h  2007-03-13 14:27:08.000000000 -0400
23258 +++ linux-2.6.20.3/include/asm-alpha/pgtable.h  2007-03-23 08:10:06.000000000 -0400
23259 @@ -101,6 +101,17 @@ struct vm_area_struct;
23260  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
23261  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
23262  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
23263 +
23264 +#ifdef CONFIG_PAX_PAGEEXEC
23265 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
23266 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
23267 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
23268 +#else
23269 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
23270 +# define PAGE_COPY_NOEXEC      PAGE_COPY
23271 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
23272 +#endif
23273 +
23274  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
23275  
23276  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
23277 diff -urNp linux-2.6.20.3/include/asm-arm/a.out.h linux-2.6.20.3/include/asm-arm/a.out.h
23278 --- linux-2.6.20.3/include/asm-arm/a.out.h      2007-03-13 14:27:08.000000000 -0400
23279 +++ linux-2.6.20.3/include/asm-arm/a.out.h      2007-03-23 08:10:06.000000000 -0400
23280 @@ -28,7 +28,7 @@ struct exec
23281  #define M_ARM 103
23282  
23283  #ifdef __KERNEL__
23284 -#define STACK_TOP      ((current->personality == PER_LINUX_32BIT) ? \
23285 +#define __STACK_TOP    ((current->personality == PER_LINUX_32BIT) ? \
23286                          TASK_SIZE : TASK_SIZE_26)
23287  #endif
23288  
23289 diff -urNp linux-2.6.20.3/include/asm-arm/elf.h linux-2.6.20.3/include/asm-arm/elf.h
23290 --- linux-2.6.20.3/include/asm-arm/elf.h        2007-03-13 14:27:08.000000000 -0400
23291 +++ linux-2.6.20.3/include/asm-arm/elf.h        2007-03-23 08:10:06.000000000 -0400
23292 @@ -110,6 +110,17 @@ extern char elf_platform[];
23293  
23294  #define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
23295  
23296 +#ifdef CONFIG_PAX_ASLR
23297 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x00008000UL
23298 +
23299 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
23300 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
23301 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
23302 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
23303 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
23304 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk->personality == PER_LINUX_32BIT) ? 16 : 10)
23305 +#endif
23306 +
23307  /* When the program starts, a1 contains a pointer to a function to be 
23308     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
23309     have no such handler.  */
23310 diff -urNp linux-2.6.20.3/include/asm-arm/kmap_types.h linux-2.6.20.3/include/asm-arm/kmap_types.h
23311 --- linux-2.6.20.3/include/asm-arm/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23312 +++ linux-2.6.20.3/include/asm-arm/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23313 @@ -18,6 +18,7 @@ enum km_type {
23314         KM_IRQ1,
23315         KM_SOFTIRQ0,
23316         KM_SOFTIRQ1,
23317 +       KM_CLEARPAGE,
23318         KM_TYPE_NR
23319  };
23320  
23321 diff -urNp linux-2.6.20.3/include/asm-arm26/kmap_types.h linux-2.6.20.3/include/asm-arm26/kmap_types.h
23322 --- linux-2.6.20.3/include/asm-arm26/kmap_types.h       2007-03-13 14:27:08.000000000 -0400
23323 +++ linux-2.6.20.3/include/asm-arm26/kmap_types.h       2007-03-23 08:10:06.000000000 -0400
23324 @@ -6,7 +6,8 @@
23325   */
23326  enum km_type {
23327          KM_IRQ0,
23328 -        KM_USER1
23329 +        KM_USER1,
23330 +        KM_CLEARPAGE
23331  };
23332  
23333  #endif
23334 diff -urNp linux-2.6.20.3/include/asm-cris/kmap_types.h linux-2.6.20.3/include/asm-cris/kmap_types.h
23335 --- linux-2.6.20.3/include/asm-cris/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
23336 +++ linux-2.6.20.3/include/asm-cris/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
23337 @@ -19,6 +19,7 @@ enum km_type {
23338         KM_IRQ1,
23339         KM_SOFTIRQ0,
23340         KM_SOFTIRQ1,
23341 +       KM_CLEARPAGE,
23342         KM_TYPE_NR
23343  };
23344  
23345 diff -urNp linux-2.6.20.3/include/asm-frv/kmap_types.h linux-2.6.20.3/include/asm-frv/kmap_types.h
23346 --- linux-2.6.20.3/include/asm-frv/kmap_types.h 2007-03-13 14:27:08.000000000 -0400
23347 +++ linux-2.6.20.3/include/asm-frv/kmap_types.h 2007-03-23 08:10:06.000000000 -0400
23348 @@ -23,6 +23,7 @@ enum km_type {
23349         KM_IRQ1,
23350         KM_SOFTIRQ0,
23351         KM_SOFTIRQ1,
23352 +       KM_CLEARPAGE,
23353         KM_TYPE_NR
23354  };
23355  
23356 diff -urNp linux-2.6.20.3/include/asm-h8300/kmap_types.h linux-2.6.20.3/include/asm-h8300/kmap_types.h
23357 --- linux-2.6.20.3/include/asm-h8300/kmap_types.h       2007-03-13 14:27:08.000000000 -0400
23358 +++ linux-2.6.20.3/include/asm-h8300/kmap_types.h       2007-03-23 08:10:06.000000000 -0400
23359 @@ -15,6 +15,7 @@ enum km_type {
23360         KM_IRQ1,
23361         KM_SOFTIRQ0,
23362         KM_SOFTIRQ1,
23363 +       KM_CLEARPAGE,
23364         KM_TYPE_NR
23365  };
23366  
23367 diff -urNp linux-2.6.20.3/include/asm-i386/alternative.h linux-2.6.20.3/include/asm-i386/alternative.h
23368 --- linux-2.6.20.3/include/asm-i386/alternative.h       2007-03-13 14:27:08.000000000 -0400
23369 +++ linux-2.6.20.3/include/asm-i386/alternative.h       2007-03-23 08:10:06.000000000 -0400
23370 @@ -57,7 +57,7 @@ static inline void alternatives_smp_swit
23371                       "  .byte 662b-661b\n"       /* sourcelen */       \
23372                       "  .byte 664f-663f\n"       /* replacementlen */  \
23373                       ".previous\n"                                     \
23374 -                     ".section .altinstr_replacement,\"ax\"\n"         \
23375 +                     ".section .altinstr_replacement,\"a\"\n"          \
23376                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
23377                       ".previous" :: "i" (feature) : "memory")
23378  
23379 @@ -81,7 +81,7 @@ static inline void alternatives_smp_swit
23380                       "  .byte 662b-661b\n"       /* sourcelen */       \
23381                       "  .byte 664f-663f\n"       /* replacementlen */  \
23382                       ".previous\n"                                     \
23383 -                     ".section .altinstr_replacement,\"ax\"\n"         \
23384 +                     ".section .altinstr_replacement,\"a\"\n"          \
23385                       "663:\n\t" newinstr "\n664:\n"   /* replacement */\
23386                       ".previous" :: "i" (feature), ##input)
23387  
23388 diff -urNp linux-2.6.20.3/include/asm-i386/a.out.h linux-2.6.20.3/include/asm-i386/a.out.h
23389 --- linux-2.6.20.3/include/asm-i386/a.out.h     2007-03-13 14:27:08.000000000 -0400
23390 +++ linux-2.6.20.3/include/asm-i386/a.out.h     2007-03-23 08:10:06.000000000 -0400
23391 @@ -19,7 +19,11 @@ struct exec
23392  
23393  #ifdef __KERNEL__
23394  
23395 -#define STACK_TOP      TASK_SIZE
23396 +#ifdef CONFIG_PAX_SEGMEXEC
23397 +#define __STACK_TOP ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?TASK_SIZE/2:TASK_SIZE)
23398 +#else
23399 +#define __STACK_TOP TASK_SIZE
23400 +#endif
23401  
23402  #endif
23403  
23404 diff -urNp linux-2.6.20.3/include/asm-i386/apic.h linux-2.6.20.3/include/asm-i386/apic.h
23405 --- linux-2.6.20.3/include/asm-i386/apic.h      2007-03-13 14:27:08.000000000 -0400
23406 +++ linux-2.6.20.3/include/asm-i386/apic.h      2007-03-23 08:10:06.000000000 -0400
23407 @@ -7,7 +7,7 @@
23408  #include <asm/processor.h>
23409  #include <asm/system.h>
23410  
23411 -#define Dprintk(x...)
23412 +#define Dprintk(x...) do {} while (0)
23413  
23414  /*
23415   * Debugging macros
23416 diff -urNp linux-2.6.20.3/include/asm-i386/checksum.h linux-2.6.20.3/include/asm-i386/checksum.h
23417 --- linux-2.6.20.3/include/asm-i386/checksum.h  2007-03-13 14:27:08.000000000 -0400
23418 +++ linux-2.6.20.3/include/asm-i386/checksum.h  2007-03-23 08:10:06.000000000 -0400
23419 @@ -30,6 +30,12 @@ asmlinkage __wsum csum_partial(const voi
23420  asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst,
23421                                                   int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
23422  
23423 +asmlinkage __wsum csum_partial_copy_generic_to_user(const unsigned char *src, unsigned char *dst,
23424 +                                                 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
23425 +
23426 +asmlinkage __wsum csum_partial_copy_generic_from_user(const unsigned char *src, unsigned char *dst,
23427 +                                                 int len, __wsum sum, int *src_err_ptr, int *dst_err_ptr);
23428 +
23429  /*
23430   *     Note: when you get a NULL pointer exception here this means someone
23431   *     passed in an incorrect kernel address to one of these functions.
23432 @@ -49,7 +55,7 @@ __wsum csum_partial_copy_from_user(const
23433                                                 int len, __wsum sum, int *err_ptr)
23434  {
23435         might_sleep();
23436 -       return csum_partial_copy_generic((__force void *)src, dst,
23437 +       return csum_partial_copy_generic_from_user((__force void *)src, dst,
23438                                         len, sum, err_ptr, NULL);
23439  }
23440  
23441 @@ -180,7 +186,7 @@ static __inline__ __wsum csum_and_copy_t
23442  {
23443         might_sleep();
23444         if (access_ok(VERIFY_WRITE, dst, len))
23445 -               return csum_partial_copy_generic(src, (__force void *)dst, len, sum, NULL, err_ptr);
23446 +               return csum_partial_copy_generic_to_user(src, (__force void *)dst, len, sum, NULL, err_ptr);
23447  
23448         if (len)
23449                 *err_ptr = -EFAULT;
23450 diff -urNp linux-2.6.20.3/include/asm-i386/desc.h linux-2.6.20.3/include/asm-i386/desc.h
23451 --- linux-2.6.20.3/include/asm-i386/desc.h      2007-03-13 14:27:08.000000000 -0400
23452 +++ linux-2.6.20.3/include/asm-i386/desc.h      2007-03-23 08:10:06.000000000 -0400
23453 @@ -8,25 +8,22 @@
23454  
23455  #include <linux/preempt.h>
23456  #include <linux/smp.h>
23457 -#include <linux/percpu.h>
23458  
23459  #include <asm/mmu.h>
23460  
23461 -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES];
23462 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
23463  
23464  struct Xgt_desc_struct {
23465         unsigned short size;
23466 -       unsigned long address __attribute__((packed));
23467 +       struct desc_struct *address __attribute__((packed));
23468         unsigned short pad;
23469  } __attribute__ ((packed));
23470  
23471 -extern struct Xgt_desc_struct idt_descr;
23472 -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr);
23473 -
23474 +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS];
23475  
23476  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
23477  {
23478 -       return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address;
23479 +       return cpu_gdt_table[cpu];
23480  }
23481  
23482  extern struct desc_struct idt_table[];
23483 @@ -76,9 +73,21 @@ static inline void pack_gate(__u32 *a, _
23484  
23485  static inline void load_TLS(struct thread_struct *t, unsigned int cpu)
23486  {
23487 +
23488 +#ifdef CONFIG_PAX_KERNEXEC
23489 +       unsigned long cr0;
23490 +
23491 +       pax_open_kernel(cr0);
23492 +#endif
23493 +
23494  #define C(i) get_cpu_gdt_table(cpu)[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]
23495         C(0); C(1); C(2);
23496  #undef C
23497 +
23498 +#ifdef CONFIG_PAX_KERNEXEC
23499 +       pax_close_kernel(cr0);
23500 +#endif
23501 +
23502  }
23503  
23504  #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b)
23505 @@ -88,8 +97,20 @@ static inline void load_TLS(struct threa
23506  static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b)
23507  {
23508         __u32 *lp = (__u32 *)((char *)dt + entry*8);
23509 +
23510 +#ifdef CONFIG_PAX_KERNEXEC
23511 +       unsigned long cr0;
23512 +
23513 +       pax_open_kernel(cr0);
23514 +#endif
23515 +
23516         *lp = entry_a;
23517         *(lp+1) = entry_b;
23518 +
23519 +#ifdef CONFIG_PAX_KERNEXEC
23520 +       pax_close_kernel(cr0);
23521 +#endif
23522 +
23523  }
23524  
23525  #define set_ldt native_set_ldt
23526 @@ -144,7 +165,7 @@ static inline void __set_tss_desc(unsign
23527         ((info)->seg_32bit << 22) | \
23528         ((info)->limit_in_pages << 23) | \
23529         ((info)->useable << 20) | \
23530 -       0x7000)
23531 +       0x7100)
23532  
23533  #define LDT_empty(info) (\
23534         (info)->base_addr       == 0    && \
23535 @@ -176,15 +197,23 @@ static inline void load_LDT(mm_context_t
23536         preempt_enable();
23537  }
23538  
23539 -static inline unsigned long get_desc_base(unsigned long *desc)
23540 +static inline unsigned long get_desc_base(struct desc_struct *desc)
23541  {
23542         unsigned long base;
23543 -       base = ((desc[0] >> 16)  & 0x0000ffff) |
23544 -               ((desc[1] << 16) & 0x00ff0000) |
23545 -               (desc[1] & 0xff000000);
23546 +       base = ((desc->a >> 16)  & 0x0000ffff) |
23547 +               ((desc->b << 16) & 0x00ff0000) |
23548 +               (desc->b & 0xff000000);
23549         return base;
23550  }
23551  
23552 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
23553 +{
23554 +       __u32 a, b;
23555 +
23556 +       pack_descriptor(&a, &b, base, limit - 1, 0xFB, 0xC);
23557 +       write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b);
23558 +}
23559 +
23560  #else /* __ASSEMBLY__ */
23561  
23562  /*
23563 diff -urNp linux-2.6.20.3/include/asm-i386/elf.h linux-2.6.20.3/include/asm-i386/elf.h
23564 --- linux-2.6.20.3/include/asm-i386/elf.h       2007-03-13 14:27:08.000000000 -0400
23565 +++ linux-2.6.20.3/include/asm-i386/elf.h       2007-03-23 08:10:06.000000000 -0400
23566 @@ -75,7 +75,22 @@ typedef struct user_fxsr_struct elf_fpxr
23567     the loader.  We need to make sure that it is out of the way of the program
23568     that it will "exec", and that there is sufficient room for the brk.  */
23569  
23570 +#ifdef CONFIG_PAX_SEGMEXEC
23571 +#define ELF_ET_DYN_BASE         ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
23572 +#else
23573  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
23574 +#endif
23575 +
23576 +#ifdef CONFIG_PAX_ASLR
23577 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000000UL
23578 +
23579 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
23580 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
23581 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
23582 +#define PAX_DELTA_EXEC_LEN(tsk)                15
23583 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
23584 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
23585 +#endif
23586  
23587  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
23588     now struct_user_regs, they are different) */
23589 @@ -133,7 +148,7 @@ extern int dump_task_extended_fpu (struc
23590  #define ELF_CORE_COPY_XFPREGS(tsk, elf_xfpregs) dump_task_extended_fpu(tsk, elf_xfpregs)
23591  
23592  #define VDSO_HIGH_BASE         (__fix_to_virt(FIX_VDSO))
23593 -#define VDSO_BASE              ((unsigned long)current->mm->context.vdso)
23594 +#define VDSO_BASE              (current->mm->context.vdso)
23595  
23596  #ifdef CONFIG_COMPAT_VDSO
23597  # define VDSO_COMPAT_BASE      VDSO_HIGH_BASE
23598 diff -urNp linux-2.6.20.3/include/asm-i386/futex.h linux-2.6.20.3/include/asm-i386/futex.h
23599 --- linux-2.6.20.3/include/asm-i386/futex.h     2007-03-13 14:27:08.000000000 -0400
23600 +++ linux-2.6.20.3/include/asm-i386/futex.h     2007-03-23 08:11:31.000000000 -0400
23601 @@ -11,8 +11,11 @@
23602  
23603  #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg) \
23604    __asm__ __volatile (                                         \
23605 +       "movw   %w6, %%ds\n"\
23606  "1:    " insn "\n"                                             \
23607 -"2:    .section .fixup,\"ax\"\n\
23608 +"2:    pushl   %%ss\n\
23609 +       popl    %%ds\n\
23610 +       .section .fixup,\"ax\"\n\
23611  3:     mov     %3, %1\n\
23612         jmp     2b\n\
23613         .previous\n\
23614 @@ -21,16 +24,19 @@
23615         .long   1b,3b\n\
23616         .previous"                                              \
23617         : "=r" (oldval), "=r" (ret), "+m" (*uaddr)              \
23618 -       : "i" (-EFAULT), "0" (oparg), "1" (0))
23619 +       : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
23620  
23621  #define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg) \
23622    __asm__ __volatile (                                         \
23623 -"1:    movl    %2, %0\n\
23624 +"      movw    %w7, %%es\n\
23625 +1:     movl    %%es:%2, %0\n\
23626         movl    %0, %3\n"                                       \
23627         insn "\n"                                               \
23628 -"2:    " LOCK_PREFIX "cmpxchgl %3, %2\n\
23629 +"2:    " LOCK_PREFIX "cmpxchgl %3, %%es:%2\n\
23630         jnz     1b\n\
23631 -3:     .section .fixup,\"ax\"\n\
23632 +3:     pushl   %%ss\n\
23633 +       popl    %%es\n\
23634 +       .section .fixup,\"ax\"\n\
23635  4:     mov     %5, %1\n\
23636         jmp     3b\n\
23637         .previous\n\
23638 @@ -40,7 +46,7 @@
23639         .previous"                                              \
23640         : "=&a" (oldval), "=&r" (ret), "+m" (*uaddr),           \
23641           "=&r" (tem)                                           \
23642 -       : "r" (oparg), "i" (-EFAULT), "1" (0))
23643 +       : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
23644  
23645  static inline int
23646  futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
23647 @@ -59,7 +65,7 @@ futex_atomic_op_inuser (int encoded_op, 
23648         pagefault_disable();
23649  
23650         if (op == FUTEX_OP_SET)
23651 -               __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
23652 +               __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
23653         else {
23654  #ifndef CONFIG_X86_BSWAP
23655                 if (boot_cpu_data.x86 == 3)
23656 @@ -68,7 +74,7 @@ futex_atomic_op_inuser (int encoded_op, 
23657  #endif
23658                 switch (op) {
23659                 case FUTEX_OP_ADD:
23660 -                       __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %2", ret,
23661 +                       __futex_atomic_op1(LOCK_PREFIX "xaddl %0, %%ds:%2", ret,
23662                                            oldval, uaddr, oparg);
23663                         break;
23664                 case FUTEX_OP_OR:
23665 @@ -111,9 +117,11 @@ futex_atomic_cmpxchg_inatomic(int __user
23666                 return -EFAULT;
23667  
23668         __asm__ __volatile__(
23669 -               "1:     " LOCK_PREFIX "cmpxchgl %3, %1          \n"
23670 -
23671 -               "2:     .section .fixup, \"ax\"                 \n"
23672 +               "       movw %w5, %%ds                          \n"
23673 +               "1:     " LOCK_PREFIX "cmpxchgl %3, %%ds:%1     \n"
23674 +               "2:     pushl   %%ss                            \n"
23675 +               "       popl    %%ds                            \n"
23676 +               "       .section .fixup, \"ax\"                 \n"
23677                 "3:     mov     %2, %0                          \n"
23678                 "       jmp     2b                              \n"
23679                 "       .previous                               \n"
23680 @@ -124,7 +132,7 @@ futex_atomic_cmpxchg_inatomic(int __user
23681                 "       .previous                               \n"
23682  
23683                 : "=a" (oldval), "+m" (*uaddr)
23684 -               : "i" (-EFAULT), "r" (newval), "0" (oldval)
23685 +               : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
23686                 : "memory"
23687         );
23688  
23689 diff -urNp linux-2.6.20.3/include/asm-i386/i387.h linux-2.6.20.3/include/asm-i386/i387.h
23690 --- linux-2.6.20.3/include/asm-i386/i387.h      2007-03-13 14:27:08.000000000 -0400
23691 +++ linux-2.6.20.3/include/asm-i386/i387.h      2007-03-23 08:10:06.000000000 -0400
23692 @@ -40,13 +40,8 @@ extern void kernel_fpu_begin(void);
23693  #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
23694  
23695  /* We need a safe address that is cheap to find and that is already
23696 -   in L1 during context switch. The best choices are unfortunately
23697 -   different for UP and SMP */
23698 -#ifdef CONFIG_SMP
23699 -#define safe_address (__per_cpu_offset[0])
23700 -#else
23701 -#define safe_address (kstat_cpu(0).cpustat.user)
23702 -#endif
23703 +   in L1 during context switch. */
23704 +#define safe_address (init_tss[smp_processor_id()].esp0)
23705  
23706  /*
23707   * These must be called with preempt disabled
23708 diff -urNp linux-2.6.20.3/include/asm-i386/irqflags.h linux-2.6.20.3/include/asm-i386/irqflags.h
23709 --- linux-2.6.20.3/include/asm-i386/irqflags.h  2007-03-13 14:27:08.000000000 -0400
23710 +++ linux-2.6.20.3/include/asm-i386/irqflags.h  2007-03-23 08:10:06.000000000 -0400
23711 @@ -84,6 +84,8 @@ static inline unsigned long __raw_local_
23712  #define ENABLE_INTERRUPTS_SYSEXIT      sti; sysexit
23713  #define INTERRUPT_RETURN               iret
23714  #define GET_CR0_INTO_EAX               movl %cr0, %eax
23715 +#define GET_CR0_INTO_EDX               movl %cr0, %edx
23716 +#define SET_CR0_FROM_EDX               movl %edx, %cr0
23717  #endif /* __ASSEMBLY__ */
23718  #endif /* CONFIG_PARAVIRT */
23719  
23720 diff -urNp linux-2.6.20.3/include/asm-i386/kmap_types.h linux-2.6.20.3/include/asm-i386/kmap_types.h
23721 --- linux-2.6.20.3/include/asm-i386/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
23722 +++ linux-2.6.20.3/include/asm-i386/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
23723 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
23724  D(10)  KM_IRQ1,
23725  D(11)  KM_SOFTIRQ0,
23726  D(12)  KM_SOFTIRQ1,
23727 -D(13)  KM_TYPE_NR
23728 +D(13)  KM_CLEARPAGE,
23729 +D(14)  KM_TYPE_NR
23730  };
23731  
23732  #undef D
23733 diff -urNp linux-2.6.20.3/include/asm-i386/mach-default/apm.h linux-2.6.20.3/include/asm-i386/mach-default/apm.h
23734 --- linux-2.6.20.3/include/asm-i386/mach-default/apm.h  2007-03-13 14:27:08.000000000 -0400
23735 +++ linux-2.6.20.3/include/asm-i386/mach-default/apm.h  2007-03-23 08:10:06.000000000 -0400
23736 @@ -36,7 +36,7 @@ static inline void apm_bios_call_asm(u32
23737         __asm__ __volatile__(APM_DO_ZERO_SEGS
23738                 "pushl %%edi\n\t"
23739                 "pushl %%ebp\n\t"
23740 -               "lcall *%%cs:apm_bios_entry\n\t"
23741 +               "lcall *%%ss:apm_bios_entry\n\t"
23742                 "setc %%al\n\t"
23743                 "popl %%ebp\n\t"
23744                 "popl %%edi\n\t"
23745 @@ -60,7 +60,7 @@ static inline u8 apm_bios_call_simple_as
23746         __asm__ __volatile__(APM_DO_ZERO_SEGS
23747                 "pushl %%edi\n\t"
23748                 "pushl %%ebp\n\t"
23749 -               "lcall *%%cs:apm_bios_entry\n\t"
23750 +               "lcall *%%ss:apm_bios_entry\n\t"
23751                 "setc %%bl\n\t"
23752                 "popl %%ebp\n\t"
23753                 "popl %%edi\n\t"
23754 diff -urNp linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h
23755 --- linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h     2007-03-13 14:27:08.000000000 -0400
23756 +++ linux-2.6.20.3/include/asm-i386/mach-default/do_timer.h     2007-03-23 08:10:06.000000000 -0400
23757 @@ -18,7 +18,7 @@ static inline void do_timer_interrupt_ho
23758  {
23759         do_timer(1);
23760  #ifndef CONFIG_SMP
23761 -       update_process_times(user_mode_vm(get_irq_regs()));
23762 +       update_process_times(user_mode(get_irq_regs()));
23763  #endif
23764  /*
23765   * In the SMP case we use the local APIC timer interrupt to do the
23766 diff -urNp linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h
23767 --- linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h     2007-03-13 14:27:08.000000000 -0400
23768 +++ linux-2.6.20.3/include/asm-i386/mach-voyager/do_timer.h     2007-03-23 08:10:06.000000000 -0400
23769 @@ -5,7 +5,7 @@ static inline void do_timer_interrupt_ho
23770  {
23771         do_timer(1);
23772  #ifndef CONFIG_SMP
23773 -       update_process_times(user_mode_vm(irq_regs));
23774 +       update_process_times(user_mode(irq_regs));
23775  #endif
23776  
23777         voyager_timer_interrupt();
23778 diff -urNp linux-2.6.20.3/include/asm-i386/mman.h linux-2.6.20.3/include/asm-i386/mman.h
23779 --- linux-2.6.20.3/include/asm-i386/mman.h      2007-03-13 14:27:08.000000000 -0400
23780 +++ linux-2.6.20.3/include/asm-i386/mman.h      2007-03-23 08:10:06.000000000 -0400
23781 @@ -11,6 +11,10 @@
23782  #define MAP_POPULATE   0x8000          /* populate (prefault) pagetables */
23783  #define MAP_NONBLOCK   0x10000         /* do not block on IO */
23784  
23785 +#ifdef CONFIG_PAX_SEGMEXEC
23786 +#define MAP_MIRROR     0x20000
23787 +#endif
23788 +
23789  #define MCL_CURRENT    1               /* lock all current mappings */
23790  #define MCL_FUTURE     2               /* lock all future mappings */
23791  
23792 diff -urNp linux-2.6.20.3/include/asm-i386/mmu_context.h linux-2.6.20.3/include/asm-i386/mmu_context.h
23793 --- linux-2.6.20.3/include/asm-i386/mmu_context.h       2007-03-13 14:27:08.000000000 -0400
23794 +++ linux-2.6.20.3/include/asm-i386/mmu_context.h       2007-03-23 09:11:44.000000000 -0400
23795 @@ -45,6 +45,20 @@ static inline void switch_mm(struct mm_s
23796                  */
23797                 if (unlikely(prev->context.ldt != next->context.ldt))
23798                         load_LDT_nolock(&next->context);
23799 +
23800 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
23801 +               smp_mb__before_clear_bit();
23802 +               cpu_clear(cpu, prev->context.cpu_user_cs_mask);
23803 +               smp_mb__after_clear_bit();
23804 +               cpu_set(cpu, next->context.cpu_user_cs_mask);
23805 +#endif
23806 +
23807 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23808 +               if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
23809 +                            prev->context.user_cs_limit != next->context.user_cs_limit))
23810 +                       set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
23811 +#endif
23812 +
23813         }
23814  #ifdef CONFIG_SMP
23815         else {
23816 @@ -57,6 +71,15 @@ static inline void switch_mm(struct mm_s
23817                          */
23818                         load_cr3(next->pgd);
23819                         load_LDT_nolock(&next->context);
23820 +
23821 +#ifdef CONFIG_PAX_PAGEEXEC
23822 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
23823 +#endif
23824 +
23825 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23826 +                       set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
23827 +#endif
23828 +
23829                 }
23830         }
23831  #endif
23832 diff -urNp linux-2.6.20.3/include/asm-i386/mmu.h linux-2.6.20.3/include/asm-i386/mmu.h
23833 --- linux-2.6.20.3/include/asm-i386/mmu.h       2007-03-13 14:27:08.000000000 -0400
23834 +++ linux-2.6.20.3/include/asm-i386/mmu.h       2007-03-23 09:12:24.000000000 -0400
23835 @@ -11,8 +11,16 @@
23836  typedef struct { 
23837         int size;
23838         struct semaphore sem;
23839 -       void *ldt;
23840 -       void *vdso;
23841 +       struct desc_struct *ldt;
23842 +       unsigned long vdso;
23843 +
23844 +       unsigned long user_cs_base;
23845 +       unsigned long user_cs_limit;
23846 +
23847 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
23848 +       cpumask_t cpu_user_cs_mask;
23849 +#endif
23850 +
23851  } mm_context_t;
23852  
23853  #endif
23854 diff -urNp linux-2.6.20.3/include/asm-i386/module.h linux-2.6.20.3/include/asm-i386/module.h
23855 --- linux-2.6.20.3/include/asm-i386/module.h    2007-03-13 14:27:08.000000000 -0400
23856 +++ linux-2.6.20.3/include/asm-i386/module.h    2007-03-23 08:11:31.000000000 -0400
23857 @@ -68,6 +68,12 @@ struct mod_arch_specific
23858  #define MODULE_STACKSIZE ""
23859  #endif
23860  
23861 -#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
23862 +#ifdef CONFIG_GRKERNSEC
23863 +#define MODULE_GRSEC "GRSECURTY "
23864 +#else
23865 +#define MODULE_GRSEC ""
23866 +#endif
23867 +
23868 +#define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
23869  
23870  #endif /* _ASM_I386_MODULE_H */
23871 diff -urNp linux-2.6.20.3/include/asm-i386/page.h linux-2.6.20.3/include/asm-i386/page.h
23872 --- linux-2.6.20.3/include/asm-i386/page.h      2007-03-13 14:27:08.000000000 -0400
23873 +++ linux-2.6.20.3/include/asm-i386/page.h      2007-03-23 08:10:06.000000000 -0400
23874 @@ -10,6 +10,7 @@
23875  #define LARGE_PAGE_SIZE (1UL << PMD_SHIFT)
23876  
23877  #ifdef __KERNEL__
23878 +#include <asm/boot.h>
23879  #ifndef __ASSEMBLY__
23880  
23881  
23882 @@ -51,14 +52,15 @@ typedef struct { unsigned long long pgpr
23883  #define pmd_val(x)     ((x).pmd)
23884  #define pte_val(x)     ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
23885  #define __pmd(x) ((pmd_t) { (x) } )
23886 +#define __pte(x) ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
23887  #define HPAGE_SHIFT    21
23888  #include <asm-generic/pgtable-nopud.h>
23889  #else
23890  typedef struct { unsigned long pte_low; } pte_t;
23891  typedef struct { unsigned long pgd; } pgd_t;
23892  typedef struct { unsigned long pgprot; } pgprot_t;
23893 -#define boot_pte_t pte_t /* or would you rather have a typedef */
23894  #define pte_val(x)     ((x).pte_low)
23895 +#define __pte(x) ((pte_t) { (x) } )
23896  #define HPAGE_SHIFT    22
23897  #include <asm-generic/pgtable-nopmd.h>
23898  #endif
23899 @@ -74,7 +76,6 @@ typedef struct { unsigned long pgprot; }
23900  #define pgd_val(x)     ((x).pgd)
23901  #define pgprot_val(x)  ((x).pgprot)
23902  
23903 -#define __pte(x) ((pte_t) { (x) } )
23904  #define __pgd(x) ((pgd_t) { (x) } )
23905  #define __pgprot(x)    ((pgprot_t) { (x) } )
23906  
23907 @@ -118,6 +119,15 @@ extern int page_is_ram(unsigned long pag
23908  #define __PAGE_OFFSET          ((unsigned long)CONFIG_PAGE_OFFSET)
23909  #endif
23910  
23911 +#ifdef CONFIG_PAX_KERNEXEC
23912 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + ((LOAD_PHYSICAL_ADDR + 4*1024*1024 - 1) & ~(4*1024*1024 - 1)))
23913 +#ifndef __ASSEMBLY__
23914 +extern unsigned char MODULES_VADDR[];
23915 +extern unsigned char MODULES_END[];
23916 +#endif
23917 +#else
23918 +#define __KERNEL_TEXT_OFFSET   (0)
23919 +#endif
23920  
23921  #define PAGE_OFFSET            ((unsigned long)__PAGE_OFFSET)
23922  #define VMALLOC_RESERVE                ((unsigned long)__VMALLOC_RESERVE)
23923 @@ -140,6 +150,19 @@ extern int page_is_ram(unsigned long pag
23924         ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
23925                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
23926  
23927 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
23928 +#ifdef CONFIG_PAX_MPROTECT
23929 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
23930 +                         ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
23931 +#else
23932 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & (MF_PAX_PAGEEXEC|MF_PAX_SEGMEXEC))?0:VM_EXEC))
23933 +#endif
23934 +#endif
23935 +
23936 +#ifdef CONFIG_PAX_PAGEEXEC
23937 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
23938 +#endif
23939 +
23940  #include <asm-generic/memory_model.h>
23941  #include <asm-generic/page.h>
23942  
23943 diff -urNp linux-2.6.20.3/include/asm-i386/paravirt.h linux-2.6.20.3/include/asm-i386/paravirt.h
23944 --- linux-2.6.20.3/include/asm-i386/paravirt.h  2007-03-13 14:27:08.000000000 -0400
23945 +++ linux-2.6.20.3/include/asm-i386/paravirt.h  2007-03-23 08:10:06.000000000 -0400
23946 @@ -150,7 +150,7 @@ struct paravirt_ops
23947   static asmlinkage void (*__paravirtprobe_##fn)(void) __attribute_used__ \
23948                 __attribute__((__section__(".paravirtprobe"))) = fn
23949  
23950 -extern struct paravirt_ops paravirt_ops;
23951 +extern const struct paravirt_ops paravirt_ops;
23952  
23953  #define paravirt_enabled() (paravirt_ops.paravirt_enabled)
23954  
23955 @@ -479,7 +479,7 @@ static inline unsigned long __raw_local_
23956  
23957  #define INTERRUPT_RETURN                               \
23958         PARA_PATCH(PARAVIRT_INTERRUPT_RETURN, CLBR_ANY, \
23959 -       jmp *%cs:paravirt_ops+PARAVIRT_iret)
23960 +       jmp *%ss:paravirt_ops+PARAVIRT_iret)
23961  
23962  #define DISABLE_INTERRUPTS(clobbers)                   \
23963         PARA_PATCH(PARAVIRT_IRQ_DISABLE, clobbers,      \
23964 @@ -490,16 +490,26 @@ static inline unsigned long __raw_local_
23965  #define ENABLE_INTERRUPTS(clobbers)                    \
23966         PARA_PATCH(PARAVIRT_IRQ_ENABLE, clobbers,       \
23967         pushl %ecx; pushl %edx;                         \
23968 -       call *%cs:paravirt_ops+PARAVIRT_irq_enable;     \
23969 +       call *%ss:paravirt_ops+PARAVIRT_irq_enable;     \
23970         popl %edx; popl %ecx)
23971  
23972  #define ENABLE_INTERRUPTS_SYSEXIT                      \
23973         PARA_PATCH(PARAVIRT_STI_SYSEXIT, CLBR_ANY,      \
23974 -       jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
23975 +       jmp *%ss:paravirt_ops+PARAVIRT_irq_enable_sysexit)
23976  
23977 -#define GET_CR0_INTO_EAX                       \
23978 +#define GET_CR0_INTO_EAX                               \
23979         call *paravirt_ops+PARAVIRT_read_cr0
23980  
23981 +#define GET_CR0_INTO_EDX                               \
23982 +       movl %eax, %edx;                                \
23983 +       call *%ss:paravirt_ops+PARAVIRT_read_cr0;       \
23984 +       xchgl %eax, %edx;                               \
23985 +
23986 +#define SET_CR0_FROM_EDX                               \
23987 +       xchgl %edx, %eax;                               \
23988 +       call *%ss:paravirt_ops+PARAVIRT_write_cr0;      \
23989 +       movl %edx, %eax
23990 +
23991  #endif /* __ASSEMBLY__ */
23992  #endif /* CONFIG_PARAVIRT */
23993  #endif /* __ASM_PARAVIRT_H */
23994 diff -urNp linux-2.6.20.3/include/asm-i386/pda.h linux-2.6.20.3/include/asm-i386/pda.h
23995 --- linux-2.6.20.3/include/asm-i386/pda.h       2007-03-13 14:27:08.000000000 -0400
23996 +++ linux-2.6.20.3/include/asm-i386/pda.h       2007-03-23 08:35:45.000000000 -0400
23997 @@ -11,14 +11,15 @@
23998  
23999  struct i386_pda
24000  {
24001 -       struct i386_pda *_pda;          /* pointer to self */
24002 +       struct i386_pda * const _pda;   /* pointer to self */
24003  
24004         int cpu_number;
24005         struct task_struct *pcurrent;   /* current process */
24006         struct pt_regs *irq_regs;
24007  };
24008  
24009 -extern struct i386_pda *_cpu_pda[];
24010 +extern struct i386_pda * const _cpu_pda[];
24011 +extern struct i386_pda __cpu_pda[];
24012  
24013  #define cpu_pda(i)     (_cpu_pda[i])
24014  
24015 @@ -33,10 +34,13 @@ extern void __bad_pda_field(void);
24016     clobbers, so gcc can readily analyse them. */
24017  extern struct i386_pda _proxy_pda;
24018  
24019 +#ifdef CONFIG_PAX_KERNEXEC
24020  #define pda_to_op(op,field,val)                                                \
24021         do {                                                            \
24022 +               unsigned long cr0;                                      \
24023                 typedef typeof(_proxy_pda.field) T__;                   \
24024                 if (0) { T__ tmp__; tmp__ = (val); }                    \
24025 +               pax_open_kernel(cr0);                                   \
24026                 switch (sizeof(_proxy_pda.field)) {                     \
24027                 case 1:                                                 \
24028                         asm(op "b %1,%%gs:%c2"                          \
24029 @@ -58,7 +62,36 @@ extern struct i386_pda _proxy_pda;
24030                         break;                                          \
24031                 default: __bad_pda_field();                             \
24032                 }                                                       \
24033 +               pax_close_kernel(cr0);                                  \
24034         } while (0)
24035 +#else
24036 +#define pda_to_op(op,field,val)                                                \
24037 +       do {                                                            \
24038 +               typedef typeof(_proxy_pda.field) T__;                   \
24039 +               if (0) { T__ tmp__; tmp__ = (val); }                    \
24040 +               switch (sizeof(_proxy_pda.field)) {                     \
24041 +               case 1:                                                 \
24042 +                       asm(op "b %1,%%gs:%c2"                          \
24043 +                           : "+m" (_proxy_pda.field)                   \
24044 +                           :"ri" ((T__)val),                           \
24045 +                            "i"(pda_offset(field)));                   \
24046 +                       break;                                          \
24047 +               case 2:                                                 \
24048 +                       asm(op "w %1,%%gs:%c2"                          \
24049 +                           : "+m" (_proxy_pda.field)                   \
24050 +                           :"ri" ((T__)val),                           \
24051 +                            "i"(pda_offset(field)));                   \
24052 +                       break;                                          \
24053 +               case 4:                                                 \
24054 +                       asm(op "l %1,%%gs:%c2"                          \
24055 +                           : "+m" (_proxy_pda.field)                   \
24056 +                           :"ri" ((T__)val),                           \
24057 +                            "i"(pda_offset(field)));                   \
24058 +                       break;                                          \
24059 +               default: __bad_pda_field();                             \
24060 +               }                                                       \
24061 +       } while (0)
24062 +#endif
24063  
24064  #define pda_from_op(op,field)                                          \
24065         ({                                                              \
24066 diff -urNp linux-2.6.20.3/include/asm-i386/pgalloc.h linux-2.6.20.3/include/asm-i386/pgalloc.h
24067 --- linux-2.6.20.3/include/asm-i386/pgalloc.h   2007-03-13 14:27:08.000000000 -0400
24068 +++ linux-2.6.20.3/include/asm-i386/pgalloc.h   2007-03-23 08:10:06.000000000 -0400
24069 @@ -5,8 +5,13 @@
24070  #include <linux/threads.h>
24071  #include <linux/mm.h>          /* for struct page */
24072  
24073 +#ifdef CONFIG_COMPAT_VDSO
24074  #define pmd_populate_kernel(mm, pmd, pte) \
24075                 set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)))
24076 +#else
24077 +#define pmd_populate_kernel(mm, pmd, pte) \
24078 +               set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)))
24079 +#endif
24080  
24081  #define pmd_populate(mm, pmd, pte)                             \
24082         set_pmd(pmd, __pmd(_PAGE_TABLE +                        \
24083 diff -urNp linux-2.6.20.3/include/asm-i386/pgtable.h linux-2.6.20.3/include/asm-i386/pgtable.h
24084 --- linux-2.6.20.3/include/asm-i386/pgtable.h   2007-03-13 14:27:08.000000000 -0400
24085 +++ linux-2.6.20.3/include/asm-i386/pgtable.h   2007-03-23 08:10:06.000000000 -0400
24086 @@ -34,7 +34,6 @@ struct vm_area_struct;
24087   */
24088  #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
24089  extern unsigned long empty_zero_page[1024];
24090 -extern pgd_t swapper_pg_dir[1024];
24091  extern struct kmem_cache *pgd_cache;
24092  extern struct kmem_cache *pmd_cache;
24093  extern spinlock_t pgd_lock;
24094 @@ -59,6 +58,11 @@ void paging_init(void);
24095  # include <asm/pgtable-2level-defs.h>
24096  #endif
24097  
24098 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
24099 +#ifdef CONFIG_X86_PAE
24100 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
24101 +#endif
24102 +
24103  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
24104  #define PGDIR_MASK     (~(PGDIR_SIZE-1))
24105  
24106 @@ -68,9 +72,11 @@ void paging_init(void);
24107  #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
24108  #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
24109  
24110 +#ifndef CONFIG_X86_PAE
24111  #define TWOLEVEL_PGDIR_SHIFT   22
24112  #define BOOT_USER_PGD_PTRS (__PAGE_OFFSET >> TWOLEVEL_PGDIR_SHIFT)
24113  #define BOOT_KERNEL_PGD_PTRS (1024-BOOT_USER_PGD_PTRS)
24114 +#endif
24115  
24116  /* Just any arbitrary offset to the start of the vmalloc VM area: the
24117   * current 8MB value just means that there will be a 8MB "hole" after the
24118 @@ -137,21 +143,30 @@ void paging_init(void);
24119  #define PAGE_NONE \
24120         __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
24121  #define PAGE_SHARED \
24122 -       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
24123 +       __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24124  
24125  #define PAGE_SHARED_EXEC \
24126         __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
24127 -#define PAGE_COPY_NOEXEC \
24128 -       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24129  #define PAGE_COPY_EXEC \
24130         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
24131 -#define PAGE_COPY \
24132 -       PAGE_COPY_NOEXEC
24133  #define PAGE_READONLY \
24134         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24135  #define PAGE_READONLY_EXEC \
24136         __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
24137  
24138 +#ifdef CONFIG_PAX_PAGEEXEC
24139 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED)
24140 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
24141 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
24142 +#else
24143 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
24144 +# define PAGE_COPY_NOEXEC \
24145 +       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
24146 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
24147 +#endif
24148 +
24149 +#define PAGE_COPY \
24150 +       PAGE_COPY_NOEXEC
24151  #define _PAGE_KERNEL \
24152         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
24153  #define _PAGE_KERNEL_EXEC \
24154 @@ -176,18 +191,18 @@ extern unsigned long long __PAGE_KERNEL,
24155   * This is the closest we can get..
24156   */
24157  #define __P000 PAGE_NONE
24158 -#define __P001 PAGE_READONLY
24159 -#define __P010 PAGE_COPY
24160 -#define __P011 PAGE_COPY
24161 +#define __P001 PAGE_READONLY_NOEXEC
24162 +#define __P010 PAGE_COPY_NOEXEC
24163 +#define __P011 PAGE_COPY_NOEXEC
24164  #define __P100 PAGE_READONLY_EXEC
24165  #define __P101 PAGE_READONLY_EXEC
24166  #define __P110 PAGE_COPY_EXEC
24167  #define __P111 PAGE_COPY_EXEC
24168  
24169  #define __S000 PAGE_NONE
24170 -#define __S001 PAGE_READONLY
24171 -#define __S010 PAGE_SHARED
24172 -#define __S011 PAGE_SHARED
24173 +#define __S001 PAGE_READONLY_NOEXEC
24174 +#define __S010 PAGE_SHARED_NOEXEC
24175 +#define __S011 PAGE_SHARED_NOEXEC
24176  #define __S100 PAGE_READONLY_EXEC
24177  #define __S101 PAGE_READONLY_EXEC
24178  #define __S110 PAGE_SHARED_EXEC
24179 @@ -497,6 +512,9 @@ do {                                                                        \
24180  #define update_mmu_cache(vma,address,pte) do { } while (0)
24181  #endif /* !__ASSEMBLY__ */
24182  
24183 +#define HAVE_ARCH_UNMAPPED_AREA
24184 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
24185 +
24186  #ifdef CONFIG_FLATMEM
24187  #define kern_addr_valid(addr)  (1)
24188  #endif /* CONFIG_FLATMEM */
24189 diff -urNp linux-2.6.20.3/include/asm-i386/processor.h linux-2.6.20.3/include/asm-i386/processor.h
24190 --- linux-2.6.20.3/include/asm-i386/processor.h 2007-03-13 14:27:08.000000000 -0400
24191 +++ linux-2.6.20.3/include/asm-i386/processor.h 2007-03-23 08:10:06.000000000 -0400
24192 @@ -18,7 +18,6 @@
24193  #include <asm/system.h>
24194  #include <linux/cache.h>
24195  #include <linux/threads.h>
24196 -#include <asm/percpu.h>
24197  #include <linux/cpumask.h>
24198  #include <linux/init.h>
24199  
24200 @@ -99,8 +98,6 @@ struct cpuinfo_x86 {
24201  
24202  extern struct cpuinfo_x86 boot_cpu_data;
24203  extern struct cpuinfo_x86 new_cpu_data;
24204 -extern struct tss_struct doublefault_tss;
24205 -DECLARE_PER_CPU(struct tss_struct, init_tss);
24206  
24207  #ifdef CONFIG_SMP
24208  extern struct cpuinfo_x86 cpu_data[];
24209 @@ -274,10 +271,19 @@ extern int bootloader_type;
24210   */
24211  #define TASK_SIZE      (PAGE_OFFSET)
24212  
24213 +#ifdef CONFIG_PAX_SEGMEXEC
24214 +#define SEGMEXEC_TASK_SIZE     ((PAGE_OFFSET) / 2)
24215 +#endif
24216 +
24217  /* This decides where the kernel will search for a free chunk of vm
24218   * space during mmap's.
24219   */
24220 +
24221 +#ifdef CONFIG_PAX_SEGMEXEC
24222 +#define TASK_UNMAPPED_BASE     (PAGE_ALIGN((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3 : TASK_SIZE/3))
24223 +#else
24224  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
24225 +#endif
24226  
24227  #define HAVE_ARCH_PICK_MMAP_LAYOUT
24228  
24229 @@ -393,6 +399,9 @@ struct tss_struct {
24230  
24231  #define ARCH_MIN_TASKALIGN     16
24232  
24233 +extern struct tss_struct doublefault_tss;
24234 +extern struct tss_struct init_tss[NR_CPUS];
24235 +
24236  struct thread_struct {
24237  /* cached TLS descriptors. */
24238         struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES];
24239 @@ -421,6 +430,7 @@ struct thread_struct {
24240  };
24241  
24242  #define INIT_THREAD  {                                                 \
24243 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
24244         .vm86_info = NULL,                                              \
24245         .sysenter_cs = __KERNEL_CS,                                     \
24246         .io_bitmap_ptr = NULL,                                          \
24247 @@ -434,7 +444,7 @@ struct thread_struct {
24248   * be within the limit.
24249   */
24250  #define INIT_TSS  {                                                    \
24251 -       .esp0           = sizeof(init_stack) + (long)&init_stack,       \
24252 +       .esp0           = sizeof(init_stack) + (long)&init_stack - 8,   \
24253         .ss0            = __KERNEL_DS,                                  \
24254         .ss1            = __KERNEL_CS,                                  \
24255         .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,                     \
24256 @@ -474,11 +484,7 @@ void show_trace(struct task_struct *task
24257  unsigned long get_wchan(struct task_struct *p);
24258  
24259  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
24260 -#define KSTK_TOP(info)                                                 \
24261 -({                                                                     \
24262 -       unsigned long *__ptr = (unsigned long *)(info);                 \
24263 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
24264 -})
24265 +#define KSTK_TOP(info)         ((info)->task.thread.esp0)
24266  
24267  /*
24268   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
24269 @@ -493,7 +499,7 @@ unsigned long get_wchan(struct task_stru
24270  #define task_pt_regs(task)                                             \
24271  ({                                                                     \
24272         struct pt_regs *__regs__;                                       \
24273 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
24274 +       __regs__ = (struct pt_regs *)((task)->thread.esp0);             \
24275         __regs__ - 1;                                                   \
24276  })
24277  
24278 @@ -742,7 +748,7 @@ extern unsigned long boot_option_idle_ov
24279  extern void enable_sep_cpu(void);
24280  extern int sysenter_setup(void);
24281  
24282 -extern int init_gdt(int cpu, struct task_struct *idle);
24283 +extern void init_gdt(int cpu, struct task_struct *idle);
24284  extern void cpu_set_gdt(int);
24285  extern void secondary_cpu_init(void);
24286  
24287 diff -urNp linux-2.6.20.3/include/asm-i386/ptrace.h linux-2.6.20.3/include/asm-i386/ptrace.h
24288 --- linux-2.6.20.3/include/asm-i386/ptrace.h    2007-03-13 14:27:08.000000000 -0400
24289 +++ linux-2.6.20.3/include/asm-i386/ptrace.h    2007-03-23 08:10:06.000000000 -0400
24290 @@ -35,17 +35,18 @@ struct task_struct;
24291  extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
24292  
24293  /*
24294 - * user_mode_vm(regs) determines whether a register set came from user mode.
24295 + * user_mode(regs) determines whether a register set came from user mode.
24296   * This is true if V8086 mode was enabled OR if the register set was from
24297   * protected mode with RPL-3 CS value.  This tricky test checks that with
24298   * one comparison.  Many places in the kernel can bypass this full check
24299 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
24300 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
24301 + * be used.
24302   */
24303 -static inline int user_mode(struct pt_regs *regs)
24304 +static inline int user_mode_novm(struct pt_regs *regs)
24305  {
24306         return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
24307  }
24308 -static inline int user_mode_vm(struct pt_regs *regs)
24309 +static inline int user_mode(struct pt_regs *regs)
24310  {
24311         return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
24312  }
24313 diff -urNp linux-2.6.20.3/include/asm-i386/segment.h linux-2.6.20.3/include/asm-i386/segment.h
24314 --- linux-2.6.20.3/include/asm-i386/segment.h   2007-03-13 14:27:08.000000000 -0400
24315 +++ linux-2.6.20.3/include/asm-i386/segment.h   2007-03-23 08:10:06.000000000 -0400
24316 @@ -87,9 +87,9 @@
24317  #define GDT_SIZE (GDT_ENTRIES * 8)
24318  
24319  /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
24320 -#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
24321 +#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
24322  /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
24323 -#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
24324 +#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
24325  
24326  /* Simple and small GDT entries for booting only */
24327  
24328 diff -urNp linux-2.6.20.3/include/asm-i386/serial.h linux-2.6.20.3/include/asm-i386/serial.h
24329 --- linux-2.6.20.3/include/asm-i386/serial.h    2007-03-13 14:27:08.000000000 -0400
24330 +++ linux-2.6.20.3/include/asm-i386/serial.h    2007-03-23 08:10:06.000000000 -0400
24331 @@ -23,7 +23,7 @@
24332  
24333  #define SERIAL_PORT_DFNS                       \
24334         /* UART CLK   PORT IRQ     FLAGS        */                      \
24335 -       { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS },      /* ttyS0 */     \
24336 -       { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS },      /* ttyS1 */     \
24337 -       { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS },      /* ttyS2 */     \
24338 -       { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS },     /* ttyS3 */
24339 +       { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS, 0 ,0, NULL, 0 },       /* ttyS0 */     \
24340 +       { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS, 0 ,0, NULL, 0 },       /* ttyS1 */     \
24341 +       { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS, 0 ,0, NULL, 0 },       /* ttyS2 */     \
24342 +       { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS, 0 ,0, NULL, 0 },      /* ttyS3 */
24343 diff -urNp linux-2.6.20.3/include/asm-i386/system.h linux-2.6.20.3/include/asm-i386/system.h
24344 --- linux-2.6.20.3/include/asm-i386/system.h    2007-03-13 14:27:08.000000000 -0400
24345 +++ linux-2.6.20.3/include/asm-i386/system.h    2007-03-23 08:10:06.000000000 -0400
24346 @@ -152,6 +152,21 @@ __asm__ __volatile__ ("movw %%dx,%1\n\t"
24347  /* Set the 'TS' bit */
24348  #define stts() write_cr0(8 | read_cr0())
24349  
24350 +#define pax_open_kernel(cr0)           \
24351 +do {                                   \
24352 +       typecheck(unsigned long,cr0);   \
24353 +       preempt_disable();              \
24354 +       cr0 = read_cr0();               \
24355 +       write_cr0(cr0 & ~0x10000UL);    \
24356 +} while(0)
24357 +
24358 +#define pax_close_kernel(cr0)          \
24359 +do {                                   \
24360 +       typecheck(unsigned long,cr0);   \
24361 +       write_cr0(cr0);                 \
24362 +       preempt_enable_no_resched();    \
24363 +} while(0)
24364 +
24365  #endif /* __KERNEL__ */
24366  
24367  static inline unsigned long get_limit(unsigned long segment)
24368 @@ -159,7 +174,7 @@ static inline unsigned long get_limit(un
24369         unsigned long __limit;
24370         __asm__("lsll %1,%0"
24371                 :"=r" (__limit):"r" (segment));
24372 -       return __limit+1;
24373 +       return __limit;
24374  }
24375  
24376  #define nop() __asm__ __volatile__ ("nop")
24377 @@ -520,7 +535,7 @@ static inline void sched_cacheflush(void
24378         wbinvd();
24379  }
24380  
24381 -extern unsigned long arch_align_stack(unsigned long sp);
24382 +#define arch_align_stack(x) (x)
24383  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
24384  
24385  void default_idle(void);
24386 diff -urNp linux-2.6.20.3/include/asm-i386/uaccess.h linux-2.6.20.3/include/asm-i386/uaccess.h
24387 --- linux-2.6.20.3/include/asm-i386/uaccess.h   2007-03-13 14:27:08.000000000 -0400
24388 +++ linux-2.6.20.3/include/asm-i386/uaccess.h   2007-03-23 08:10:06.000000000 -0400
24389 @@ -9,6 +9,7 @@
24390  #include <linux/prefetch.h>
24391  #include <linux/string.h>
24392  #include <asm/page.h>
24393 +#include <asm/segment.h>
24394  
24395  #define VERIFY_READ 0
24396  #define VERIFY_WRITE 1
24397 @@ -29,7 +30,8 @@
24398  
24399  #define get_ds()       (KERNEL_DS)
24400  #define get_fs()       (current_thread_info()->addr_limit)
24401 -#define set_fs(x)      (current_thread_info()->addr_limit = (x))
24402 +void __set_fs(mm_segment_t x, int cpu);
24403 +void set_fs(mm_segment_t x);
24404  
24405  #define segment_eq(a,b)        ((a).seg == (b).seg)
24406  
24407 @@ -280,9 +282,12 @@ extern void __put_user_8(void);
24408  
24409  #define __put_user_u64(x, addr, err)                           \
24410         __asm__ __volatile__(                                   \
24411 -               "1:     movl %%eax,0(%2)\n"                     \
24412 -               "2:     movl %%edx,4(%2)\n"                     \
24413 +               "       movw %w5,%%ds\n"                        \
24414 +               "1:     movl %%eax,%%ds:0(%2)\n"                \
24415 +               "2:     movl %%edx,%%ds:4(%2)\n"                \
24416                 "3:\n"                                          \
24417 +               "       pushl %%ss\n"                           \
24418 +               "       popl %%ds\n"                            \
24419                 ".section .fixup,\"ax\"\n"                      \
24420                 "4:     movl %3,%0\n"                           \
24421                 "       jmp 3b\n"                               \
24422 @@ -293,7 +298,8 @@ extern void __put_user_8(void);
24423                 "       .long 2b,4b\n"                          \
24424                 ".previous"                                     \
24425                 : "=r"(err)                                     \
24426 -               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err))
24427 +               : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err),  \
24428 +                 "r"(__USER_DS))
24429  
24430  #ifdef CONFIG_X86_WP_WORKS_OK
24431  
24432 @@ -332,8 +338,11 @@ struct __large_struct { unsigned long bu
24433   */
24434  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
24435         __asm__ __volatile__(                                           \
24436 -               "1:     mov"itype" %"rtype"1,%2\n"                      \
24437 +               "       movw %w5,%%ds\n"                                \
24438 +               "1:     mov"itype" %"rtype"1,%%ds:%2\n"                 \
24439                 "2:\n"                                                  \
24440 +               "       pushl %%ss\n"                                   \
24441 +               "       popl %%ds\n"                                    \
24442                 ".section .fixup,\"ax\"\n"                              \
24443                 "3:     movl %3,%0\n"                                   \
24444                 "       jmp 2b\n"                                       \
24445 @@ -343,7 +352,8 @@ struct __large_struct { unsigned long bu
24446                 "       .long 1b,3b\n"                                  \
24447                 ".previous"                                             \
24448                 : "=r"(err)                                             \
24449 -               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err))
24450 +               : ltype (x), "m"(__m(addr)), "i"(errret), "0"(err),     \
24451 +                 "r"(__USER_DS))
24452  
24453  
24454  #define __get_user_nocheck(x,ptr,size)                         \
24455 @@ -371,8 +381,11 @@ do {                                                                       \
24456  
24457  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
24458         __asm__ __volatile__(                                           \
24459 -               "1:     mov"itype" %2,%"rtype"1\n"                      \
24460 +               "       movw %w5,%%ds\n"                                \
24461 +               "1:     mov"itype" %%ds:%2,%"rtype"1\n"                 \
24462                 "2:\n"                                                  \
24463 +               "       pushl %%ss\n"                                   \
24464 +               "       popl %%ds\n"                                    \
24465                 ".section .fixup,\"ax\"\n"                              \
24466                 "3:     movl %3,%0\n"                                   \
24467                 "       xor"itype" %"rtype"1,%"rtype"1\n"               \
24468 @@ -383,7 +396,7 @@ do {                                                                        \
24469                 "       .long 1b,3b\n"                                  \
24470                 ".previous"                                             \
24471                 : "=r"(err), ltype (x)                                  \
24472 -               : "m"(__m(addr)), "i"(errret), "0"(err))
24473 +               : "m"(__m(addr)), "i"(errret), "0"(err), "r"(__USER_DS))
24474  
24475  
24476  unsigned long __must_check __copy_to_user_ll(void __user *to,
24477 diff -urNp linux-2.6.20.3/include/asm-ia64/elf.h linux-2.6.20.3/include/asm-ia64/elf.h
24478 --- linux-2.6.20.3/include/asm-ia64/elf.h       2007-03-13 14:27:08.000000000 -0400
24479 +++ linux-2.6.20.3/include/asm-ia64/elf.h       2007-03-23 08:10:06.000000000 -0400
24480 @@ -162,6 +162,16 @@ typedef elf_greg_t elf_gregset_t[ELF_NGR
24481  typedef struct ia64_fpreg elf_fpreg_t;
24482  typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
24483  
24484 +#ifdef CONFIG_PAX_ASLR
24485 +#define PAX_ELF_ET_DYN_BASE(tsk)       ((tsk)->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
24486 +
24487 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
24488 +#define PAX_DELTA_MMAP_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
24489 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
24490 +#define PAX_DELTA_EXEC_LEN(tsk)                ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
24491 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
24492 +#define PAX_DELTA_STACK_LEN(tsk)       ((tsk)->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
24493 +#endif
24494  
24495  
24496  struct pt_regs;        /* forward declaration... */
24497 diff -urNp linux-2.6.20.3/include/asm-ia64/kmap_types.h linux-2.6.20.3/include/asm-ia64/kmap_types.h
24498 --- linux-2.6.20.3/include/asm-ia64/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
24499 +++ linux-2.6.20.3/include/asm-ia64/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
24500 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
24501  D(10)  KM_IRQ1,
24502  D(11)  KM_SOFTIRQ0,
24503  D(12)  KM_SOFTIRQ1,
24504 -D(13)  KM_TYPE_NR
24505 +D(13)  KM_CLEARPAGE,
24506 +D(14)  KM_TYPE_NR
24507  };
24508  
24509  #undef D
24510 diff -urNp linux-2.6.20.3/include/asm-ia64/page.h linux-2.6.20.3/include/asm-ia64/page.h
24511 --- linux-2.6.20.3/include/asm-ia64/page.h      2007-03-13 14:27:08.000000000 -0400
24512 +++ linux-2.6.20.3/include/asm-ia64/page.h      2007-03-23 08:10:06.000000000 -0400
24513 @@ -226,5 +226,14 @@ get_order (unsigned long size)
24514                                          (((current->personality & READ_IMPLIES_EXEC) != 0)     \
24515                                           ? VM_EXEC : 0))
24516  
24517 +#ifdef CONFIG_PAX_PAGEEXEC
24518 +#ifdef CONFIG_PAX_MPROTECT
24519 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24520 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24521 +#else
24522 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24523 +#endif
24524 +#endif
24525 +
24526  # endif /* __KERNEL__ */
24527  #endif /* _ASM_IA64_PAGE_H */
24528 diff -urNp linux-2.6.20.3/include/asm-ia64/pgtable.h linux-2.6.20.3/include/asm-ia64/pgtable.h
24529 --- linux-2.6.20.3/include/asm-ia64/pgtable.h   2007-03-13 14:27:08.000000000 -0400
24530 +++ linux-2.6.20.3/include/asm-ia64/pgtable.h   2007-03-23 08:10:06.000000000 -0400
24531 @@ -143,6 +143,17 @@
24532  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24533  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24534  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
24535 +
24536 +#ifdef CONFIG_PAX_PAGEEXEC
24537 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
24538 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24539 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
24540 +#else
24541 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
24542 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
24543 +# define PAGE_COPY_NOEXEC      PAGE_COPY
24544 +#endif
24545 +
24546  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
24547  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
24548  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
24549 diff -urNp linux-2.6.20.3/include/asm-ia64/processor.h linux-2.6.20.3/include/asm-ia64/processor.h
24550 --- linux-2.6.20.3/include/asm-ia64/processor.h 2007-03-13 14:27:08.000000000 -0400
24551 +++ linux-2.6.20.3/include/asm-ia64/processor.h 2007-03-23 08:10:06.000000000 -0400
24552 @@ -274,7 +274,7 @@ struct thread_struct {
24553         .on_ustack =    0,                                      \
24554         .ksp =          0,                                      \
24555         .map_base =     DEFAULT_MAP_BASE,                       \
24556 -       .rbs_bot =      STACK_TOP - DEFAULT_USER_STACK_SIZE,    \
24557 +       .rbs_bot =      __STACK_TOP - DEFAULT_USER_STACK_SIZE,  \
24558         .task_size =    DEFAULT_TASK_SIZE,                      \
24559         .last_fph_cpu =  -1,                                    \
24560         INIT_THREAD_IA32                                        \
24561 diff -urNp linux-2.6.20.3/include/asm-ia64/ustack.h linux-2.6.20.3/include/asm-ia64/ustack.h
24562 --- linux-2.6.20.3/include/asm-ia64/ustack.h    2007-03-13 14:27:08.000000000 -0400
24563 +++ linux-2.6.20.3/include/asm-ia64/ustack.h    2007-03-23 08:10:06.000000000 -0400
24564 @@ -10,10 +10,10 @@
24565  
24566  /* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
24567  #define MAX_USER_STACK_SIZE    (RGN_MAP_LIMIT/2)
24568 -#define STACK_TOP              (0x6000000000000000UL + RGN_MAP_LIMIT)
24569 +#define __STACK_TOP            (0x6000000000000000UL + RGN_MAP_LIMIT)
24570  #endif
24571  
24572 -/* Make a default stack size of 2GiB */
24573 +/* Make a default stack size of 2GB */
24574  #define DEFAULT_USER_STACK_SIZE        (1UL << 31)
24575  
24576  #endif /* _ASM_IA64_USTACK_H */
24577 diff -urNp linux-2.6.20.3/include/asm-m32r/kmap_types.h linux-2.6.20.3/include/asm-m32r/kmap_types.h
24578 --- linux-2.6.20.3/include/asm-m32r/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
24579 +++ linux-2.6.20.3/include/asm-m32r/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
24580 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
24581  D(10)  KM_IRQ1,
24582  D(11)  KM_SOFTIRQ0,
24583  D(12)  KM_SOFTIRQ1,
24584 -D(13)  KM_TYPE_NR
24585 +D(13)  KM_CLEARPAGE,
24586 +D(14)  KM_TYPE_NR
24587  };
24588  
24589  #undef D
24590 diff -urNp linux-2.6.20.3/include/asm-m68k/kmap_types.h linux-2.6.20.3/include/asm-m68k/kmap_types.h
24591 --- linux-2.6.20.3/include/asm-m68k/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
24592 +++ linux-2.6.20.3/include/asm-m68k/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
24593 @@ -15,6 +15,7 @@ enum km_type {
24594         KM_IRQ1,
24595         KM_SOFTIRQ0,
24596         KM_SOFTIRQ1,
24597 +       KM_CLEARPAGE,
24598         KM_TYPE_NR
24599  };
24600  
24601 diff -urNp linux-2.6.20.3/include/asm-m68knommu/kmap_types.h linux-2.6.20.3/include/asm-m68knommu/kmap_types.h
24602 --- linux-2.6.20.3/include/asm-m68knommu/kmap_types.h   2007-03-13 14:27:08.000000000 -0400
24603 +++ linux-2.6.20.3/include/asm-m68knommu/kmap_types.h   2007-03-23 08:10:06.000000000 -0400
24604 @@ -15,6 +15,7 @@ enum km_type {
24605         KM_IRQ1,
24606         KM_SOFTIRQ0,
24607         KM_SOFTIRQ1,
24608 +       KM_CLEARPAGE,
24609         KM_TYPE_NR
24610  };
24611  
24612 diff -urNp linux-2.6.20.3/include/asm-mips/a.out.h linux-2.6.20.3/include/asm-mips/a.out.h
24613 --- linux-2.6.20.3/include/asm-mips/a.out.h     2007-03-13 14:27:08.000000000 -0400
24614 +++ linux-2.6.20.3/include/asm-mips/a.out.h     2007-03-23 08:10:06.000000000 -0400
24615 @@ -35,10 +35,10 @@ struct exec
24616  #ifdef __KERNEL__
24617  
24618  #ifdef CONFIG_32BIT
24619 -#define STACK_TOP      TASK_SIZE
24620 +#define __STACK_TOP    TASK_SIZE
24621  #endif
24622  #ifdef CONFIG_64BIT
24623 -#define STACK_TOP      (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
24624 +#define __STACK_TOP    (current->thread.mflags & MF_32BIT_ADDR ? TASK_SIZE32 : TASK_SIZE)
24625  #endif
24626  
24627  #endif
24628 diff -urNp linux-2.6.20.3/include/asm-mips/elf.h linux-2.6.20.3/include/asm-mips/elf.h
24629 --- linux-2.6.20.3/include/asm-mips/elf.h       2007-03-13 14:27:08.000000000 -0400
24630 +++ linux-2.6.20.3/include/asm-mips/elf.h       2007-03-23 08:10:06.000000000 -0400
24631 @@ -371,4 +371,15 @@ extern int dump_task_fpu(struct task_str
24632  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
24633  #endif
24634  
24635 +#ifdef CONFIG_PAX_ASLR
24636 +#define PAX_ELF_ET_DYN_BASE(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
24637 +
24638 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
24639 +#define PAX_DELTA_MMAP_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
24640 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
24641 +#define PAX_DELTA_EXEC_LEN(tsk)                (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
24642 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
24643 +#define PAX_DELTA_STACK_LEN(tsk)       (((tsk)->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
24644 +#endif
24645 +
24646  #endif /* _ASM_ELF_H */
24647 diff -urNp linux-2.6.20.3/include/asm-mips/kmap_types.h linux-2.6.20.3/include/asm-mips/kmap_types.h
24648 --- linux-2.6.20.3/include/asm-mips/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
24649 +++ linux-2.6.20.3/include/asm-mips/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
24650 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
24651  D(10)  KM_IRQ1,
24652  D(11)  KM_SOFTIRQ0,
24653  D(12)  KM_SOFTIRQ1,
24654 -D(13)  KM_TYPE_NR
24655 +D(13)  KM_CLEARPAGE,
24656 +D(14)  KM_TYPE_NR
24657  };
24658  
24659  #undef D
24660 diff -urNp linux-2.6.20.3/include/asm-mips/page.h linux-2.6.20.3/include/asm-mips/page.h
24661 --- linux-2.6.20.3/include/asm-mips/page.h      2007-03-13 14:27:08.000000000 -0400
24662 +++ linux-2.6.20.3/include/asm-mips/page.h      2007-03-23 08:10:06.000000000 -0400
24663 @@ -75,7 +75,7 @@ extern void copy_user_highpage(struct pa
24664    #ifdef CONFIG_CPU_MIPS32
24665      typedef struct { unsigned long pte_low, pte_high; } pte_t;
24666      #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
24667 -    #define __pte(x)      ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
24668 +    #define __pte(x)      ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
24669    #else
24670       typedef struct { unsigned long long pte; } pte_t;
24671       #define pte_val(x)        ((x).pte)
24672 @@ -170,6 +170,15 @@ typedef struct { unsigned long pgprot; }
24673  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
24674                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24675  
24676 +#ifdef CONFIG_PAX_PAGEEXEC
24677 +#ifdef CONFIG_PAX_MPROTECT
24678 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24679 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24680 +#else
24681 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24682 +#endif
24683 +#endif
24684 +
24685  #define UNCAC_ADDR(addr)       ((addr) - PAGE_OFFSET + UNCAC_BASE)
24686  #define CAC_ADDR(addr)         ((addr) - UNCAC_BASE + PAGE_OFFSET)
24687  
24688 diff -urNp linux-2.6.20.3/include/asm-parisc/a.out.h linux-2.6.20.3/include/asm-parisc/a.out.h
24689 --- linux-2.6.20.3/include/asm-parisc/a.out.h   2007-03-13 14:27:08.000000000 -0400
24690 +++ linux-2.6.20.3/include/asm-parisc/a.out.h   2007-03-23 08:10:06.000000000 -0400
24691 @@ -22,7 +22,7 @@ struct exec
24692  /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
24693   * prumpf */
24694  
24695 -#define STACK_TOP      TASK_SIZE
24696 +#define __STACK_TOP    TASK_SIZE
24697  
24698  #endif
24699  
24700 diff -urNp linux-2.6.20.3/include/asm-parisc/elf.h linux-2.6.20.3/include/asm-parisc/elf.h
24701 --- linux-2.6.20.3/include/asm-parisc/elf.h     2007-03-13 14:27:08.000000000 -0400
24702 +++ linux-2.6.20.3/include/asm-parisc/elf.h     2007-03-23 08:10:06.000000000 -0400
24703 @@ -337,6 +337,17 @@ struct pt_regs;    /* forward declaration..
24704  
24705  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
24706  
24707 +#ifdef CONFIG_PAX_ASLR
24708 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
24709 +
24710 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
24711 +#define PAX_DELTA_MMAP_LEN(tsk)                16
24712 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
24713 +#define PAX_DELTA_EXEC_LEN(tsk)                16
24714 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
24715 +#define PAX_DELTA_STACK_LEN(tsk)       16
24716 +#endif
24717 +
24718  /* This yields a mask that user programs can use to figure out what
24719     instruction set this CPU supports.  This could be done in user space,
24720     but it's not easy, and we've already done it here.  */
24721 diff -urNp linux-2.6.20.3/include/asm-parisc/kmap_types.h linux-2.6.20.3/include/asm-parisc/kmap_types.h
24722 --- linux-2.6.20.3/include/asm-parisc/kmap_types.h      2007-03-13 14:27:08.000000000 -0400
24723 +++ linux-2.6.20.3/include/asm-parisc/kmap_types.h      2007-03-23 08:10:06.000000000 -0400
24724 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
24725  D(10)  KM_IRQ1,
24726  D(11)  KM_SOFTIRQ0,
24727  D(12)  KM_SOFTIRQ1,
24728 -D(13)  KM_TYPE_NR
24729 +D(13)  KM_CLEARPAGE,
24730 +D(14)  KM_TYPE_NR
24731  };
24732  
24733  #undef D
24734 diff -urNp linux-2.6.20.3/include/asm-parisc/page.h linux-2.6.20.3/include/asm-parisc/page.h
24735 --- linux-2.6.20.3/include/asm-parisc/page.h    2007-03-13 14:27:08.000000000 -0400
24736 +++ linux-2.6.20.3/include/asm-parisc/page.h    2007-03-23 08:10:06.000000000 -0400
24737 @@ -166,6 +166,15 @@ extern int npmem_ranges;
24738  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
24739                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24740  
24741 +#ifdef CONFIG_PAX_PAGEEXEC
24742 +#ifdef CONFIG_PAX_MPROTECT
24743 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24744 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24745 +#else
24746 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24747 +#endif
24748 +#endif
24749 +
24750  #include <asm-generic/memory_model.h>
24751  #include <asm-generic/page.h>
24752  
24753 diff -urNp linux-2.6.20.3/include/asm-parisc/pgtable.h linux-2.6.20.3/include/asm-parisc/pgtable.h
24754 --- linux-2.6.20.3/include/asm-parisc/pgtable.h 2007-03-13 14:27:08.000000000 -0400
24755 +++ linux-2.6.20.3/include/asm-parisc/pgtable.h 2007-03-23 08:10:06.000000000 -0400
24756 @@ -219,6 +219,17 @@ extern  void *vmalloc_start;
24757  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
24758  #define PAGE_COPY       PAGE_EXECREAD
24759  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
24760 +
24761 +#ifdef CONFIG_PAX_PAGEEXEC
24762 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
24763 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
24764 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
24765 +#else
24766 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
24767 +# define PAGE_COPY_NOEXEC      PAGE_COPY
24768 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
24769 +#endif
24770 +
24771  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
24772  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
24773  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
24774 diff -urNp linux-2.6.20.3/include/asm-powerpc/a.out.h linux-2.6.20.3/include/asm-powerpc/a.out.h
24775 --- linux-2.6.20.3/include/asm-powerpc/a.out.h  2007-03-13 14:27:08.000000000 -0400
24776 +++ linux-2.6.20.3/include/asm-powerpc/a.out.h  2007-03-23 08:10:06.000000000 -0400
24777 @@ -23,12 +23,12 @@ struct exec
24778  #define STACK_TOP_USER64 TASK_SIZE_USER64
24779  #define STACK_TOP_USER32 TASK_SIZE_USER32
24780  
24781 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
24782 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
24783                    STACK_TOP_USER32 : STACK_TOP_USER64)
24784  
24785  #else /* __powerpc64__ */
24786  
24787 -#define STACK_TOP TASK_SIZE
24788 +#define __STACK_TOP TASK_SIZE
24789  
24790  #endif /* __powerpc64__ */
24791  #endif /* __KERNEL__ */
24792 diff -urNp linux-2.6.20.3/include/asm-powerpc/elf.h linux-2.6.20.3/include/asm-powerpc/elf.h
24793 --- linux-2.6.20.3/include/asm-powerpc/elf.h    2007-03-13 14:27:08.000000000 -0400
24794 +++ linux-2.6.20.3/include/asm-powerpc/elf.h    2007-03-23 08:10:06.000000000 -0400
24795 @@ -159,6 +159,26 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_N
24796  typedef elf_vrreg_t elf_vrregset_t32[ELF_NVRREG32];
24797  #endif
24798  
24799 +#ifdef CONFIG_PAX_ASLR
24800 +#define PAX_ELF_ET_DYN_BASE(tsk)       (0x10000000UL)
24801 +
24802 +#ifdef __powerpc64__
24803 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
24804 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
24805 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
24806 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 16 : 28)
24807 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
24808 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 16 : 28)
24809 +#else
24810 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
24811 +#define PAX_DELTA_MMAP_LEN(tsk)                15
24812 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
24813 +#define PAX_DELTA_EXEC_LEN(tsk)                15
24814 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
24815 +#define PAX_DELTA_STACK_LEN(tsk)       15
24816 +#endif
24817 +#endif
24818 +
24819  #ifdef __KERNEL__
24820  /*
24821   * This is used to ensure we don't load something for the wrong architecture.
24822 diff -urNp linux-2.6.20.3/include/asm-powerpc/kmap_types.h linux-2.6.20.3/include/asm-powerpc/kmap_types.h
24823 --- linux-2.6.20.3/include/asm-powerpc/kmap_types.h     2007-03-13 14:27:08.000000000 -0400
24824 +++ linux-2.6.20.3/include/asm-powerpc/kmap_types.h     2007-03-23 08:10:06.000000000 -0400
24825 @@ -26,6 +26,7 @@ enum km_type {
24826         KM_SOFTIRQ1,
24827         KM_PPC_SYNC_PAGE,
24828         KM_PPC_SYNC_ICACHE,
24829 +       KM_CLEARPAGE,
24830         KM_TYPE_NR
24831  };
24832  
24833 diff -urNp linux-2.6.20.3/include/asm-powerpc/page_64.h linux-2.6.20.3/include/asm-powerpc/page_64.h
24834 --- linux-2.6.20.3/include/asm-powerpc/page_64.h        2007-03-13 14:27:08.000000000 -0400
24835 +++ linux-2.6.20.3/include/asm-powerpc/page_64.h        2007-03-23 08:10:06.000000000 -0400
24836 @@ -160,15 +160,18 @@ extern unsigned int HPAGE_SHIFT;
24837   * stack by default, so in the absense of a PT_GNU_STACK program header
24838   * we turn execute permission off.
24839   */
24840 -#define VM_STACK_DEFAULT_FLAGS32       (VM_READ | VM_WRITE | VM_EXEC | \
24841 -                                        VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24842 +#define VM_STACK_DEFAULT_FLAGS32 \
24843 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
24844 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24845  
24846  #define VM_STACK_DEFAULT_FLAGS64       (VM_READ | VM_WRITE | \
24847                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24848  
24849 +#ifndef CONFIG_PAX_PAGEEXEC
24850  #define VM_STACK_DEFAULT_FLAGS \
24851         (test_thread_flag(TIF_32BIT) ? \
24852          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
24853 +#endif
24854  
24855  #include <asm-generic/page.h>
24856  
24857 diff -urNp linux-2.6.20.3/include/asm-powerpc/page.h linux-2.6.20.3/include/asm-powerpc/page.h
24858 --- linux-2.6.20.3/include/asm-powerpc/page.h   2007-03-13 14:27:08.000000000 -0400
24859 +++ linux-2.6.20.3/include/asm-powerpc/page.h   2007-03-23 08:10:06.000000000 -0400
24860 @@ -71,8 +71,9 @@
24861   * and needs to be executable.  This means the whole heap ends
24862   * up being executable.
24863   */
24864 -#define VM_DATA_DEFAULT_FLAGS32        (VM_READ | VM_WRITE | VM_EXEC | \
24865 -                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24866 +#define VM_DATA_DEFAULT_FLAGS32 \
24867 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
24868 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24869  
24870  #define VM_DATA_DEFAULT_FLAGS64        (VM_READ | VM_WRITE | \
24871                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
24872 @@ -83,6 +84,15 @@
24873  #include <asm/page_32.h>
24874  #endif
24875  
24876 +#ifdef CONFIG_PAX_PAGEEXEC
24877 +#ifdef CONFIG_PAX_MPROTECT
24878 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24879 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24880 +#else
24881 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24882 +#endif
24883 +#endif
24884 +
24885  /* align addr on a size boundary - adjust address up/down if needed */
24886  #define _ALIGN_UP(addr,size)   (((addr)+((size)-1))&(~((size)-1)))
24887  #define _ALIGN_DOWN(addr,size) ((addr)&(~((size)-1)))
24888 diff -urNp linux-2.6.20.3/include/asm-ppc/mmu_context.h linux-2.6.20.3/include/asm-ppc/mmu_context.h
24889 --- linux-2.6.20.3/include/asm-ppc/mmu_context.h        2007-03-13 14:27:08.000000000 -0400
24890 +++ linux-2.6.20.3/include/asm-ppc/mmu_context.h        2007-03-23 08:10:06.000000000 -0400
24891 @@ -144,7 +144,8 @@ static inline void get_mmu_context(struc
24892  static inline int init_new_context(struct task_struct *t, struct mm_struct *mm)
24893  {
24894         mm->context.id = NO_CONTEXT;
24895 -       mm->context.vdso_base = 0;
24896 +       if (t == current)
24897 +               mm->context.vdso_base = ~0UL;
24898         return 0;
24899  }
24900  
24901 diff -urNp linux-2.6.20.3/include/asm-ppc/page.h linux-2.6.20.3/include/asm-ppc/page.h
24902 --- linux-2.6.20.3/include/asm-ppc/page.h       2007-03-13 14:27:08.000000000 -0400
24903 +++ linux-2.6.20.3/include/asm-ppc/page.h       2007-03-23 08:10:06.000000000 -0400
24904 @@ -173,6 +173,15 @@ extern __inline__ int get_order(unsigned
24905  /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
24906  #define __HAVE_ARCH_GATE_AREA          1
24907  
24908 +#ifdef CONFIG_PAX_PAGEEXEC
24909 +#ifdef CONFIG_PAX_MPROTECT
24910 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
24911 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24912 +#else
24913 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
24914 +#endif
24915 +#endif
24916 +
24917  #include <asm-generic/memory_model.h>
24918  #endif /* __KERNEL__ */
24919  #endif /* _PPC_PAGE_H */
24920 diff -urNp linux-2.6.20.3/include/asm-ppc/pgtable.h linux-2.6.20.3/include/asm-ppc/pgtable.h
24921 --- linux-2.6.20.3/include/asm-ppc/pgtable.h    2007-03-13 14:27:08.000000000 -0400
24922 +++ linux-2.6.20.3/include/asm-ppc/pgtable.h    2007-03-23 08:10:06.000000000 -0400
24923 @@ -440,11 +440,21 @@ extern unsigned long ioremap_bot, iorema
24924  
24925  #define PAGE_NONE      __pgprot(_PAGE_BASE)
24926  #define PAGE_READONLY  __pgprot(_PAGE_BASE | _PAGE_USER)
24927 -#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
24928 +#define PAGE_READONLY_X        __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
24929  #define PAGE_SHARED    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW)
24930 -#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC)
24931 +#define PAGE_SHARED_X  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_EXEC | _PAGE_HWEXEC)
24932  #define PAGE_COPY      __pgprot(_PAGE_BASE | _PAGE_USER)
24933 -#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC)
24934 +#define PAGE_COPY_X    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_EXEC | _PAGE_HWEXEC)
24935 +
24936 +#if defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_40x) && !defined(CONFIG_44x)
24937 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_RW | _PAGE_GUARDED)
24938 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
24939 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_BASE | _PAGE_USER | _PAGE_GUARDED)
24940 +#else
24941 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
24942 +# define PAGE_COPY_NOEXEC      PAGE_COPY
24943 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
24944 +#endif
24945  
24946  #define PAGE_KERNEL            __pgprot(_PAGE_RAM)
24947  #define PAGE_KERNEL_NOCACHE    __pgprot(_PAGE_IO)
24948 @@ -456,21 +466,21 @@ extern unsigned long ioremap_bot, iorema
24949   * This is the closest we can get..
24950   */
24951  #define __P000 PAGE_NONE
24952 -#define __P001 PAGE_READONLY_X
24953 -#define __P010 PAGE_COPY
24954 -#define __P011 PAGE_COPY_X
24955 -#define __P100 PAGE_READONLY
24956 +#define __P001 PAGE_READONLY_NOEXEC
24957 +#define __P010 PAGE_COPY_NOEXEC
24958 +#define __P011 PAGE_COPY_NOEXEC
24959 +#define __P100 PAGE_READONLY_X
24960  #define __P101 PAGE_READONLY_X
24961 -#define __P110 PAGE_COPY
24962 +#define __P110 PAGE_COPY_X
24963  #define __P111 PAGE_COPY_X
24964  
24965  #define __S000 PAGE_NONE
24966 -#define __S001 PAGE_READONLY_X
24967 -#define __S010 PAGE_SHARED
24968 -#define __S011 PAGE_SHARED_X
24969 -#define __S100 PAGE_READONLY
24970 +#define __S001 PAGE_READONLY_NOEXEC
24971 +#define __S010 PAGE_SHARED_NOEXEC
24972 +#define __S011 PAGE_SHARED_NOEXEC
24973 +#define __S100 PAGE_READONLY_X
24974  #define __S101 PAGE_READONLY_X
24975 -#define __S110 PAGE_SHARED
24976 +#define __S110 PAGE_SHARED_X
24977  #define __S111 PAGE_SHARED_X
24978  
24979  #ifndef __ASSEMBLY__
24980 diff -urNp linux-2.6.20.3/include/asm-s390/kmap_types.h linux-2.6.20.3/include/asm-s390/kmap_types.h
24981 --- linux-2.6.20.3/include/asm-s390/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
24982 +++ linux-2.6.20.3/include/asm-s390/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
24983 @@ -16,6 +16,7 @@ enum km_type {
24984         KM_IRQ1,
24985         KM_SOFTIRQ0,
24986         KM_SOFTIRQ1,    
24987 +       KM_CLEARPAGE,
24988         KM_TYPE_NR
24989  };
24990  
24991 diff -urNp linux-2.6.20.3/include/asm-sh/kmap_types.h linux-2.6.20.3/include/asm-sh/kmap_types.h
24992 --- linux-2.6.20.3/include/asm-sh/kmap_types.h  2007-03-13 14:27:08.000000000 -0400
24993 +++ linux-2.6.20.3/include/asm-sh/kmap_types.h  2007-03-23 08:10:06.000000000 -0400
24994 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
24995  D(10)  KM_IRQ1,
24996  D(11)  KM_SOFTIRQ0,
24997  D(12)  KM_SOFTIRQ1,
24998 -D(13)  KM_TYPE_NR
24999 +D(13)  KM_CLEARPAGE,
25000 +D(14)  KM_TYPE_NR
25001  };
25002  
25003  #undef D
25004 diff -urNp linux-2.6.20.3/include/asm-sparc/a.out.h linux-2.6.20.3/include/asm-sparc/a.out.h
25005 --- linux-2.6.20.3/include/asm-sparc/a.out.h    2007-03-13 14:27:08.000000000 -0400
25006 +++ linux-2.6.20.3/include/asm-sparc/a.out.h    2007-03-23 08:10:06.000000000 -0400
25007 @@ -91,7 +91,7 @@ struct relocation_info /* used when head
25008  
25009  #include <asm/page.h>
25010  
25011 -#define STACK_TOP      (PAGE_OFFSET - PAGE_SIZE)
25012 +#define __STACK_TOP    (PAGE_OFFSET - PAGE_SIZE)
25013  
25014  #endif /* __KERNEL__ */
25015  
25016 diff -urNp linux-2.6.20.3/include/asm-sparc/elf.h linux-2.6.20.3/include/asm-sparc/elf.h
25017 --- linux-2.6.20.3/include/asm-sparc/elf.h      2007-03-13 14:27:08.000000000 -0400
25018 +++ linux-2.6.20.3/include/asm-sparc/elf.h      2007-03-23 08:10:06.000000000 -0400
25019 @@ -143,6 +143,17 @@ do {       unsigned long *dest = &(__elf_regs[
25020  
25021  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
25022  
25023 +#ifdef CONFIG_PAX_ASLR
25024 +#define PAX_ELF_ET_DYN_BASE(tsk)       0x10000UL
25025 +
25026 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
25027 +#define PAX_DELTA_MMAP_LEN(tsk)                16
25028 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
25029 +#define PAX_DELTA_EXEC_LEN(tsk)                16
25030 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
25031 +#define PAX_DELTA_STACK_LEN(tsk)       16
25032 +#endif
25033 +
25034  /* This yields a mask that user programs can use to figure out what
25035     instruction set this cpu supports.  This can NOT be done in userspace
25036     on Sparc.  */
25037 diff -urNp linux-2.6.20.3/include/asm-sparc/kmap_types.h linux-2.6.20.3/include/asm-sparc/kmap_types.h
25038 --- linux-2.6.20.3/include/asm-sparc/kmap_types.h       2007-03-13 14:27:08.000000000 -0400
25039 +++ linux-2.6.20.3/include/asm-sparc/kmap_types.h       2007-03-23 08:10:06.000000000 -0400
25040 @@ -15,6 +15,7 @@ enum km_type {
25041         KM_IRQ1,
25042         KM_SOFTIRQ0,
25043         KM_SOFTIRQ1,
25044 +       KM_CLEARPAGE,
25045         KM_TYPE_NR
25046  };
25047  
25048 diff -urNp linux-2.6.20.3/include/asm-sparc/page.h linux-2.6.20.3/include/asm-sparc/page.h
25049 --- linux-2.6.20.3/include/asm-sparc/page.h     2007-03-13 14:27:08.000000000 -0400
25050 +++ linux-2.6.20.3/include/asm-sparc/page.h     2007-03-23 08:10:06.000000000 -0400
25051 @@ -160,6 +160,15 @@ extern unsigned long pfn_base;
25052  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
25053                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25054  
25055 +#ifdef CONFIG_PAX_PAGEEXEC
25056 +#ifdef CONFIG_PAX_MPROTECT
25057 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
25058 +                        ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25059 +#else
25060 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25061 +#endif
25062 +#endif
25063 +
25064  #include <asm-generic/memory_model.h>
25065  #include <asm-generic/page.h>
25066  
25067 diff -urNp linux-2.6.20.3/include/asm-sparc/pgtable.h linux-2.6.20.3/include/asm-sparc/pgtable.h
25068 --- linux-2.6.20.3/include/asm-sparc/pgtable.h  2007-03-13 14:27:08.000000000 -0400
25069 +++ linux-2.6.20.3/include/asm-sparc/pgtable.h  2007-03-23 08:10:06.000000000 -0400
25070 @@ -49,6 +49,13 @@ BTFIXUPDEF_INT(page_none)
25071  BTFIXUPDEF_INT(page_shared)
25072  BTFIXUPDEF_INT(page_copy)
25073  BTFIXUPDEF_INT(page_readonly)
25074 +
25075 +#ifdef CONFIG_PAX_PAGEEXEC
25076 +BTFIXUPDEF_INT(page_shared_noexec)
25077 +BTFIXUPDEF_INT(page_copy_noexec)
25078 +BTFIXUPDEF_INT(page_readonly_noexec)
25079 +#endif
25080 +
25081  BTFIXUPDEF_INT(page_kernel)
25082  
25083  #define PMD_SHIFT              SUN4C_PMD_SHIFT
25084 @@ -70,6 +77,16 @@ BTFIXUPDEF_INT(page_kernel)
25085  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
25086  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
25087  
25088 +#ifdef CONFIG_PAX_PAGEEXEC
25089 +# define PAGE_SHARED_NOEXEC    __pgprot(BTFIXUP_INT(page_shared_noexec))
25090 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
25091 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
25092 +#else
25093 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
25094 +# define PAGE_COPY_NOEXEC      PAGE_COPY
25095 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
25096 +#endif
25097 +
25098  extern unsigned long page_kernel;
25099  
25100  #ifdef MODULE
25101 diff -urNp linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h
25102 --- linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h 2007-03-13 14:27:08.000000000 -0400
25103 +++ linux-2.6.20.3/include/asm-sparc/pgtsrmmu.h 2007-03-23 08:10:06.000000000 -0400
25104 @@ -115,6 +115,16 @@
25105                                     SRMMU_EXEC | SRMMU_REF)
25106  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25107                                     SRMMU_EXEC | SRMMU_REF)
25108 +
25109 +#ifdef CONFIG_PAX_PAGEEXEC
25110 +#define SRMMU_PAGE_SHARED_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25111 +                                          SRMMU_WRITE | SRMMU_REF)
25112 +#define SRMMU_PAGE_COPY_NOEXEC    __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25113 +                                          SRMMU_REF)
25114 +#define SRMMU_PAGE_RDONLY_NOEXEC  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
25115 +                                          SRMMU_REF)
25116 +#endif
25117 +
25118  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
25119                                     SRMMU_DIRTY | SRMMU_REF)
25120  
25121 diff -urNp linux-2.6.20.3/include/asm-sparc/uaccess.h linux-2.6.20.3/include/asm-sparc/uaccess.h
25122 --- linux-2.6.20.3/include/asm-sparc/uaccess.h  2007-03-13 14:27:08.000000000 -0400
25123 +++ linux-2.6.20.3/include/asm-sparc/uaccess.h  2007-03-23 08:10:06.000000000 -0400
25124 @@ -41,7 +41,7 @@
25125   * No one can read/write anything from userland in the kernel space by setting
25126   * large size and address near to PAGE_OFFSET - a fault will break his intentions.
25127   */
25128 -#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; })
25129 +#define __user_ok(addr, size) ({ (void)(size); (addr) < __STACK_TOP; })
25130  #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS))
25131  #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size)))
25132  #define access_ok(type, addr, size)                                    \
25133 diff -urNp linux-2.6.20.3/include/asm-sparc64/a.out.h linux-2.6.20.3/include/asm-sparc64/a.out.h
25134 --- linux-2.6.20.3/include/asm-sparc64/a.out.h  2007-03-13 14:27:08.000000000 -0400
25135 +++ linux-2.6.20.3/include/asm-sparc64/a.out.h  2007-03-23 08:10:06.000000000 -0400
25136 @@ -98,7 +98,7 @@ struct relocation_info /* used when head
25137  #define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
25138  #define STACK_TOP64    (0x0000080000000000UL - (1UL << 32UL))
25139  
25140 -#define STACK_TOP (test_thread_flag(TIF_32BIT) ? \
25141 +#define __STACK_TOP (test_thread_flag(TIF_32BIT) ? \
25142                    STACK_TOP32 : STACK_TOP64)
25143  
25144  #endif
25145 diff -urNp linux-2.6.20.3/include/asm-sparc64/elf.h linux-2.6.20.3/include/asm-sparc64/elf.h
25146 --- linux-2.6.20.3/include/asm-sparc64/elf.h    2007-03-13 14:27:08.000000000 -0400
25147 +++ linux-2.6.20.3/include/asm-sparc64/elf.h    2007-03-23 08:10:06.000000000 -0400
25148 @@ -142,6 +142,16 @@ typedef struct {
25149  #define ELF_ET_DYN_BASE         0x0000010000000000UL
25150  #endif
25151  
25152 +#ifdef CONFIG_PAX_ASLR
25153 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
25154 +
25155 +#define PAX_DELTA_MMAP_LSB(tsk)                (PAGE_SHIFT + 1)
25156 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
25157 +#define PAX_DELTA_EXEC_LSB(tsk)                (PAGE_SHIFT + 1)
25158 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_32BIT) ? 14 : 28 )
25159 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
25160 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_32BIT) ? 15 : 29 )
25161 +#endif
25162  
25163  /* This yields a mask that user programs can use to figure out what
25164     instruction set this cpu supports.  */
25165 diff -urNp linux-2.6.20.3/include/asm-sparc64/kmap_types.h linux-2.6.20.3/include/asm-sparc64/kmap_types.h
25166 --- linux-2.6.20.3/include/asm-sparc64/kmap_types.h     2007-03-13 14:27:08.000000000 -0400
25167 +++ linux-2.6.20.3/include/asm-sparc64/kmap_types.h     2007-03-23 08:10:06.000000000 -0400
25168 @@ -19,6 +19,7 @@ enum km_type {
25169         KM_IRQ1,
25170         KM_SOFTIRQ0,
25171         KM_SOFTIRQ1,
25172 +       KM_CLEARPAGE,
25173         KM_TYPE_NR
25174  };
25175  
25176 diff -urNp linux-2.6.20.3/include/asm-sparc64/page.h linux-2.6.20.3/include/asm-sparc64/page.h
25177 --- linux-2.6.20.3/include/asm-sparc64/page.h   2007-03-13 14:27:08.000000000 -0400
25178 +++ linux-2.6.20.3/include/asm-sparc64/page.h   2007-03-23 08:10:06.000000000 -0400
25179 @@ -141,6 +141,15 @@ typedef unsigned long pgprot_t;
25180  #define VM_DATA_DEFAULT_FLAGS  (VM_READ | VM_WRITE | VM_EXEC | \
25181                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25182  
25183 +#ifdef CONFIG_PAX_PAGEEXEC
25184 +#ifdef CONFIG_PAX_MPROTECT
25185 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
25186 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25187 +#else
25188 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25189 +#endif
25190 +#endif
25191 +
25192  #include <asm-generic/page.h>
25193  
25194  #endif /* __KERNEL__ */
25195 diff -urNp linux-2.6.20.3/include/asm-v850/kmap_types.h linux-2.6.20.3/include/asm-v850/kmap_types.h
25196 --- linux-2.6.20.3/include/asm-v850/kmap_types.h        2007-03-13 14:27:08.000000000 -0400
25197 +++ linux-2.6.20.3/include/asm-v850/kmap_types.h        2007-03-23 08:10:06.000000000 -0400
25198 @@ -13,6 +13,7 @@ enum km_type {
25199         KM_PTE1,
25200         KM_IRQ0,
25201         KM_IRQ1,
25202 +       KM_CLEARPAGE,
25203         KM_TYPE_NR
25204  };
25205  
25206 diff -urNp linux-2.6.20.3/include/asm-x86_64/a.out.h linux-2.6.20.3/include/asm-x86_64/a.out.h
25207 --- linux-2.6.20.3/include/asm-x86_64/a.out.h   2007-03-13 14:27:08.000000000 -0400
25208 +++ linux-2.6.20.3/include/asm-x86_64/a.out.h   2007-03-23 08:10:06.000000000 -0400
25209 @@ -21,7 +21,7 @@ struct exec
25210  
25211  #ifdef __KERNEL__
25212  #include <linux/thread_info.h>
25213 -#define STACK_TOP TASK_SIZE
25214 +#define __STACK_TOP TASK_SIZE
25215  #endif
25216  
25217  #endif /* __A_OUT_GNU_H__ */
25218 diff -urNp linux-2.6.20.3/include/asm-x86_64/elf.h linux-2.6.20.3/include/asm-x86_64/elf.h
25219 --- linux-2.6.20.3/include/asm-x86_64/elf.h     2007-03-13 14:27:08.000000000 -0400
25220 +++ linux-2.6.20.3/include/asm-x86_64/elf.h     2007-03-23 08:10:06.000000000 -0400
25221 @@ -92,6 +92,17 @@ typedef struct user_i387_struct elf_fpre
25222  
25223  #define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
25224  
25225 +#ifdef CONFIG_PAX_ASLR
25226 +#define PAX_ELF_ET_DYN_BASE(tsk)       (test_thread_flag(TIF_IA32) ? 0x08048000UL : 0x400000UL)
25227 +
25228 +#define PAX_DELTA_MMAP_LSB(tsk)                PAGE_SHIFT
25229 +#define PAX_DELTA_MMAP_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
25230 +#define PAX_DELTA_EXEC_LSB(tsk)                PAGE_SHIFT
25231 +#define PAX_DELTA_EXEC_LEN(tsk)                (test_thread_flag(TIF_IA32) ? 16 : 32)
25232 +#define PAX_DELTA_STACK_LSB(tsk)       PAGE_SHIFT
25233 +#define PAX_DELTA_STACK_LEN(tsk)       (test_thread_flag(TIF_IA32) ? 16 : 32)
25234 +#endif
25235 +
25236  /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
25237     now struct_user_regs, they are different). Assumes current is the process
25238     getting dumped. */
25239 diff -urNp linux-2.6.20.3/include/asm-x86_64/ia32.h linux-2.6.20.3/include/asm-x86_64/ia32.h
25240 --- linux-2.6.20.3/include/asm-x86_64/ia32.h    2007-03-13 14:27:08.000000000 -0400
25241 +++ linux-2.6.20.3/include/asm-x86_64/ia32.h    2007-03-23 08:10:06.000000000 -0400
25242 @@ -156,7 +156,13 @@ struct ustat32 {
25243         char                    f_fpack[6];
25244  };
25245  
25246 -#define IA32_STACK_TOP IA32_PAGE_OFFSET
25247 +#ifdef CONFIG_PAX_RANDUSTACK
25248 +#define IA32_DELTA_STACK (current->mm->delta_stack)
25249 +#else
25250 +#define IA32_DELTA_STACK 0UL
25251 +#endif
25252 +
25253 +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - IA32_DELTA_STACK)
25254  
25255  #ifdef __KERNEL__
25256  struct user_desc;
25257 diff -urNp linux-2.6.20.3/include/asm-x86_64/kmap_types.h linux-2.6.20.3/include/asm-x86_64/kmap_types.h
25258 --- linux-2.6.20.3/include/asm-x86_64/kmap_types.h      2007-03-13 14:27:08.000000000 -0400
25259 +++ linux-2.6.20.3/include/asm-x86_64/kmap_types.h      2007-03-23 08:10:06.000000000 -0400
25260 @@ -13,6 +13,7 @@ enum km_type {
25261         KM_IRQ1,
25262         KM_SOFTIRQ0,
25263         KM_SOFTIRQ1,
25264 +       KM_CLEARPAGE,
25265         KM_TYPE_NR
25266  };
25267  
25268 diff -urNp linux-2.6.20.3/include/asm-x86_64/page.h linux-2.6.20.3/include/asm-x86_64/page.h
25269 --- linux-2.6.20.3/include/asm-x86_64/page.h    2007-03-13 14:27:08.000000000 -0400
25270 +++ linux-2.6.20.3/include/asm-x86_64/page.h    2007-03-23 08:10:06.000000000 -0400
25271 @@ -88,6 +88,8 @@ typedef struct { unsigned long pgprot; }
25272  #define __PAGE_OFFSET           0xffff810000000000
25273  #endif /* !__ASSEMBLY__ */
25274  
25275 +#define __KERNEL_TEXT_OFFSET   (0)
25276 +
25277  /* to align the pointer to the (next) page boundary */
25278  #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
25279  
25280 @@ -133,6 +135,15 @@ typedef struct { unsigned long pgprot; }
25281         (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0 ) | \
25282          VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
25283  
25284 +#ifdef CONFIG_PAX_PAGEEXEC
25285 +#ifdef CONFIG_PAX_MPROTECT
25286 +#define __VM_STACK_FLAGS (((current->mm->pax_flags & MF_PAX_MPROTECT)?0:VM_MAYEXEC) | \
25287 +                         ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25288 +#else
25289 +#define __VM_STACK_FLAGS (VM_MAYEXEC | ((current->mm->pax_flags & MF_PAX_PAGEEXEC)?0:VM_EXEC))
25290 +#endif
25291 +#endif
25292 +
25293  #define __HAVE_ARCH_GATE_AREA 1        
25294  
25295  #include <asm-generic/memory_model.h>
25296 diff -urNp linux-2.6.20.3/include/asm-x86_64/pgalloc.h linux-2.6.20.3/include/asm-x86_64/pgalloc.h
25297 --- linux-2.6.20.3/include/asm-x86_64/pgalloc.h 2007-03-13 14:27:08.000000000 -0400
25298 +++ linux-2.6.20.3/include/asm-x86_64/pgalloc.h 2007-03-23 08:10:06.000000000 -0400
25299 @@ -7,7 +7,7 @@
25300  #include <linux/mm.h>
25301  
25302  #define pmd_populate_kernel(mm, pmd, pte) \
25303 -               set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)))
25304 +               set_pmd(pmd, __pmd(_KERNPG_TABLE | __pa(pte)))
25305  #define pud_populate(mm, pud, pmd) \
25306                 set_pud(pud, __pud(_PAGE_TABLE | __pa(pmd)))
25307  #define pgd_populate(mm, pgd, pud) \
25308 diff -urNp linux-2.6.20.3/include/asm-x86_64/pgtable.h linux-2.6.20.3/include/asm-x86_64/pgtable.h
25309 --- linux-2.6.20.3/include/asm-x86_64/pgtable.h 2007-03-13 14:27:08.000000000 -0400
25310 +++ linux-2.6.20.3/include/asm-x86_64/pgtable.h 2007-03-23 08:10:06.000000000 -0400
25311 @@ -174,6 +174,10 @@ static inline pte_t ptep_get_and_clear_f
25312  #define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
25313  #define PAGE_READONLY  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_NX)
25314  #define PAGE_READONLY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
25315 +
25316 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
25317 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
25318 +
25319  #define __PAGE_KERNEL \
25320         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_NX)
25321  #define __PAGE_KERNEL_EXEC \
25322 @@ -261,7 +265,15 @@ static inline pte_t pfn_pte(unsigned lon
25323  #define __LARGE_PTE (_PAGE_PSE|_PAGE_PRESENT)
25324  static inline int pte_user(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
25325  static inline int pte_read(pte_t pte)          { return pte_val(pte) & _PAGE_USER; }
25326 -static inline int pte_exec(pte_t pte)          { return !(pte_val(pte) & _PAGE_NX); }
25327 +
25328 +static inline int pte_exec(pte_t pte)
25329 +{
25330 +       if (__supported_pte_mask & _PAGE_NX)
25331 +               return pte_val(pte) & _PAGE_NX;
25332 +       else
25333 +               return pte_val(pte) & _PAGE_USER;
25334 +}
25335 +
25336  static inline int pte_dirty(pte_t pte)         { return pte_val(pte) & _PAGE_DIRTY; }
25337  static inline int pte_young(pte_t pte)         { return pte_val(pte) & _PAGE_ACCESSED; }
25338  static inline int pte_write(pte_t pte)         { return pte_val(pte) & _PAGE_RW; }
25339 @@ -269,12 +281,30 @@ static inline int pte_file(pte_t pte)             {
25340  static inline int pte_huge(pte_t pte)          { return pte_val(pte) & _PAGE_PSE; }
25341  
25342  static inline pte_t pte_rdprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
25343 -static inline pte_t pte_exprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER)); return pte; }
25344 +
25345 +static inline pte_t pte_exprotect(pte_t pte)
25346 +{
25347 +       if (__supported_pte_mask & _PAGE_NX)
25348 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX));
25349 +       else
25350 +               set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_USER));
25351 +       return pte;
25352 +}
25353 +
25354  static inline pte_t pte_mkclean(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_DIRTY)); return pte; }
25355  static inline pte_t pte_mkold(pte_t pte)       { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_ACCESSED)); return pte; }
25356  static inline pte_t pte_wrprotect(pte_t pte)   { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_RW)); return pte; }
25357  static inline pte_t pte_mkread(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER)); return pte; }
25358 -static inline pte_t pte_mkexec(pte_t pte)      { set_pte(&pte, __pte(pte_val(pte) & ~_PAGE_NX)); return pte; }
25359 +
25360 +extern inline pte_t pte_mkexec(pte_t pte)
25361 +{
25362 +       if (__supported_pte_mask & _PAGE_NX)
25363 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_NX));
25364 +       else
25365 +               set_pte(&pte, __pte(pte_val(pte) | _PAGE_USER));
25366 +       return pte;
25367 +}
25368 +
25369  static inline pte_t pte_mkdirty(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_DIRTY)); return pte; }
25370  static inline pte_t pte_mkyoung(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_ACCESSED)); return pte; }
25371  static inline pte_t pte_mkwrite(pte_t pte)     { set_pte(&pte, __pte(pte_val(pte) | _PAGE_RW)); return pte; }
25372 diff -urNp linux-2.6.20.3/include/asm-x86_64/system.h linux-2.6.20.3/include/asm-x86_64/system.h
25373 --- linux-2.6.20.3/include/asm-x86_64/system.h  2007-03-13 14:27:08.000000000 -0400
25374 +++ linux-2.6.20.3/include/asm-x86_64/system.h  2007-03-23 08:10:06.000000000 -0400
25375 @@ -248,7 +248,7 @@ static inline unsigned long __cmpxchg(vo
25376  
25377  void cpu_idle_wait(void);
25378  
25379 -extern unsigned long arch_align_stack(unsigned long sp);
25380 +#define arch_align_stack(x) (x)
25381  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
25382  
25383  #endif
25384 diff -urNp linux-2.6.20.3/include/asm-xtensa/kmap_types.h linux-2.6.20.3/include/asm-xtensa/kmap_types.h
25385 --- linux-2.6.20.3/include/asm-xtensa/kmap_types.h      2007-03-13 14:27:08.000000000 -0400
25386 +++ linux-2.6.20.3/include/asm-xtensa/kmap_types.h      2007-03-23 08:10:06.000000000 -0400
25387 @@ -25,6 +25,7 @@ enum km_type {
25388    KM_IRQ1,
25389    KM_SOFTIRQ0,
25390    KM_SOFTIRQ1,
25391 +  KM_CLEARPAGE,
25392    KM_TYPE_NR
25393  };
25394  
25395 diff -urNp linux-2.6.20.3/include/linux/a.out.h linux-2.6.20.3/include/linux/a.out.h
25396 --- linux-2.6.20.3/include/linux/a.out.h        2007-03-13 14:27:08.000000000 -0400
25397 +++ linux-2.6.20.3/include/linux/a.out.h        2007-03-23 08:10:06.000000000 -0400
25398 @@ -7,6 +7,16 @@
25399  
25400  #include <asm/a.out.h>
25401  
25402 +#ifdef CONFIG_PAX_RANDUSTACK
25403 +#define __DELTA_STACK (current->mm->delta_stack)
25404 +#else
25405 +#define __DELTA_STACK 0UL
25406 +#endif
25407 +
25408 +#ifndef STACK_TOP
25409 +#define STACK_TOP      (__STACK_TOP - __DELTA_STACK)
25410 +#endif
25411 +
25412  #endif /* __STRUCT_EXEC_OVERRIDE__ */
25413  
25414  /* these go in the N_MACHTYPE field */
25415 @@ -37,6 +47,14 @@ enum machine_type {
25416    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
25417  };
25418  
25419 +/* Constants for the N_FLAGS field */
25420 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
25421 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
25422 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
25423 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
25424 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
25425 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
25426 +
25427  #if !defined (N_MAGIC)
25428  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
25429  #endif
25430 diff -urNp linux-2.6.20.3/include/linux/binfmts.h linux-2.6.20.3/include/linux/binfmts.h
25431 --- linux-2.6.20.3/include/linux/binfmts.h      2007-03-13 14:27:08.000000000 -0400
25432 +++ linux-2.6.20.3/include/linux/binfmts.h      2007-03-23 08:10:06.000000000 -0400
25433 @@ -7,10 +7,10 @@ struct pt_regs;
25434  
25435  /*
25436   * MAX_ARG_PAGES defines the number of pages allocated for arguments
25437 - * and envelope for the new program. 32 should suffice, this gives
25438 - * a maximum env+arg of 128kB w/4KB pages!
25439 + * and envelope for the new program. 33 should suffice, this gives
25440 + * a maximum env+arg of 132kB w/4KB pages!
25441   */
25442 -#define MAX_ARG_PAGES 32
25443 +#define MAX_ARG_PAGES 33
25444  
25445  /* sizeof(linux_binprm->buf) */
25446  #define BINPRM_BUF_SIZE 128
25447 @@ -38,6 +38,7 @@ struct linux_binprm{
25448         unsigned interp_flags;
25449         unsigned interp_data;
25450         unsigned long loader, exec;
25451 +       int misc;
25452  };
25453  
25454  #define BINPRM_FLAGS_ENFORCE_NONDUMP_BIT 0
25455 @@ -88,5 +89,8 @@ extern void compute_creds(struct linux_b
25456  extern int do_coredump(long signr, int exit_code, struct pt_regs * regs);
25457  extern int set_binfmt(struct linux_binfmt *new);
25458  
25459 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
25460 +void pax_report_insns(void *pc, void *sp);
25461 +
25462  #endif /* __KERNEL__ */
25463  #endif /* _LINUX_BINFMTS_H */
25464 diff -urNp linux-2.6.20.3/include/linux/capability.h linux-2.6.20.3/include/linux/capability.h
25465 --- linux-2.6.20.3/include/linux/capability.h   2007-03-13 14:27:08.000000000 -0400
25466 +++ linux-2.6.20.3/include/linux/capability.h   2007-03-23 08:11:31.000000000 -0400
25467 @@ -358,6 +358,7 @@ static inline kernel_cap_t cap_invert(ke
25468  #define cap_is_fs_cap(c)     (CAP_TO_MASK(c) & CAP_FS_MASK)
25469  
25470  int capable(int cap);
25471 +int capable_nolog(int cap);
25472  int __capable(struct task_struct *t, int cap);
25473  
25474  #endif /* __KERNEL__ */
25475 diff -urNp linux-2.6.20.3/include/linux/elf.h linux-2.6.20.3/include/linux/elf.h
25476 --- linux-2.6.20.3/include/linux/elf.h  2007-03-13 14:27:08.000000000 -0400
25477 +++ linux-2.6.20.3/include/linux/elf.h  2007-03-23 08:10:06.000000000 -0400
25478 @@ -8,6 +8,10 @@
25479  
25480  struct file;
25481  
25482 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
25483 +#undef elf_read_implies_exec
25484 +#endif
25485 +
25486  #ifndef elf_read_implies_exec
25487    /* Executables for which elf_read_implies_exec() returns TRUE will
25488       have the READ_IMPLIES_EXEC personality flag set automatically.
25489 @@ -49,6 +53,16 @@ typedef __s64        Elf64_Sxword;
25490  
25491  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
25492  
25493 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
25494 +
25495 +/* Constants for the e_flags field */
25496 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
25497 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
25498 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
25499 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
25500 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
25501 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
25502 +
25503  /* These constants define the different elf file types */
25504  #define ET_NONE   0
25505  #define ET_REL    1
25506 @@ -83,6 +97,8 @@ typedef __s64 Elf64_Sxword;
25507  #define DT_DEBUG       21
25508  #define DT_TEXTREL     22
25509  #define DT_JMPREL      23
25510 +#define DT_FLAGS       30
25511 +  #define DF_TEXTREL   0x00000004
25512  #define DT_LOPROC      0x70000000
25513  #define DT_HIPROC      0x7fffffff
25514  
25515 @@ -212,6 +228,19 @@ typedef struct elf64_hdr {
25516  #define PF_W           0x2
25517  #define PF_X           0x1
25518  
25519 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
25520 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
25521 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
25522 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
25523 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
25524 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
25525 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
25526 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
25527 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
25528 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
25529 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
25530 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
25531 +
25532  typedef struct elf32_phdr{
25533    Elf32_Word   p_type;
25534    Elf32_Off    p_offset;
25535 @@ -304,6 +333,8 @@ typedef struct elf64_shdr {
25536  #define        EI_OSABI        7
25537  #define        EI_PAD          8
25538  
25539 +#define        EI_PAX          14
25540 +
25541  #define        ELFMAG0         0x7f            /* EI_MAG */
25542  #define        ELFMAG1         'E'
25543  #define        ELFMAG2         'L'
25544 @@ -361,6 +392,7 @@ extern Elf32_Dyn _DYNAMIC [];
25545  #define elf_phdr       elf32_phdr
25546  #define elf_note       elf32_note
25547  #define elf_addr_t     Elf32_Off
25548 +#define elf_dyn                Elf32_Dyn
25549  
25550  #else
25551  
25552 @@ -369,6 +401,7 @@ extern Elf64_Dyn _DYNAMIC [];
25553  #define elf_phdr       elf64_phdr
25554  #define elf_note       elf64_note
25555  #define elf_addr_t     Elf64_Off
25556 +#define elf_dyn                Elf64_Dyn
25557  
25558  #endif
25559  
25560 diff -urNp linux-2.6.20.3/include/linux/ext4_fs_extents.h linux-2.6.20.3/include/linux/ext4_fs_extents.h
25561 --- linux-2.6.20.3/include/linux/ext4_fs_extents.h      2007-03-13 14:27:08.000000000 -0400
25562 +++ linux-2.6.20.3/include/linux/ext4_fs_extents.h      2007-03-23 08:10:06.000000000 -0400
25563 @@ -50,7 +50,7 @@
25564  #ifdef EXT_DEBUG
25565  #define ext_debug(a...)                printk(a)
25566  #else
25567 -#define ext_debug(a...)
25568 +#define ext_debug(a...)                do {} while (0)
25569  #endif
25570  
25571  /*
25572 diff -urNp linux-2.6.20.3/include/linux/gracl.h linux-2.6.20.3/include/linux/gracl.h
25573 --- linux-2.6.20.3/include/linux/gracl.h        1969-12-31 19:00:00.000000000 -0500
25574 +++ linux-2.6.20.3/include/linux/gracl.h        2007-03-23 08:11:31.000000000 -0400
25575 @@ -0,0 +1,316 @@
25576 +#ifndef GR_ACL_H
25577 +#define GR_ACL_H
25578 +
25579 +#include <linux/grdefs.h>
25580 +#include <linux/resource.h>
25581 +#include <linux/dcache.h>
25582 +#include <asm/resource.h>
25583 +
25584 +/* Major status information */
25585 +
25586 +#define GR_VERSION  "grsecurity 2.1.10"
25587 +#define GRSECURITY_VERSION 0x2110
25588 +
25589 +enum {
25590 +
25591 +       SHUTDOWN = 0,
25592 +       ENABLE = 1,
25593 +       SPROLE = 2,
25594 +       RELOAD = 3,
25595 +       SEGVMOD = 4,
25596 +       STATUS = 5,
25597 +       UNSPROLE = 6,
25598 +       PASSSET = 7,
25599 +       SPROLEPAM = 8
25600 +};
25601 +
25602 +/* Password setup definitions
25603 + * kernel/grhash.c */
25604 +enum {
25605 +       GR_PW_LEN = 128,
25606 +       GR_SALT_LEN = 16,
25607 +       GR_SHA_LEN = 32,
25608 +};
25609 +
25610 +enum {
25611 +       GR_SPROLE_LEN = 64,
25612 +};
25613 +
25614 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
25615 +
25616 +/* Begin Data Structures */
25617 +
25618 +struct sprole_pw {
25619 +       unsigned char *rolename;
25620 +       unsigned char salt[GR_SALT_LEN];
25621 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
25622 +};
25623 +
25624 +struct name_entry {
25625 +       __u32 key;
25626 +       ino_t inode;
25627 +       dev_t device;
25628 +       char *name;
25629 +       __u16 len;
25630 +       struct name_entry *prev;
25631 +       struct name_entry *next;
25632 +};
25633 +
25634 +struct inodev_entry {
25635 +       struct name_entry *nentry;
25636 +       struct inodev_entry *prev;
25637 +       struct inodev_entry *next;
25638 +};
25639 +
25640 +struct acl_role_db {
25641 +       struct acl_role_label **r_hash;
25642 +       __u32 r_size;
25643 +};
25644 +
25645 +struct inodev_db {
25646 +       struct inodev_entry **i_hash;
25647 +       __u32 i_size;
25648 +};
25649 +
25650 +struct name_db {
25651 +       struct name_entry **n_hash;
25652 +       __u32 n_size;
25653 +};
25654 +
25655 +struct crash_uid {
25656 +       uid_t uid;
25657 +       unsigned long expires;
25658 +};
25659 +
25660 +struct gr_hash_struct {
25661 +       void **table;
25662 +       void **nametable;
25663 +       void *first;
25664 +       __u32 table_size;
25665 +       __u32 used_size;
25666 +       int type;
25667 +};
25668 +
25669 +/* Userspace Grsecurity ACL data structures */
25670 +
25671 +struct acl_subject_label {
25672 +       char *filename;
25673 +       ino_t inode;
25674 +       dev_t device;
25675 +       __u32 mode;
25676 +       __u32 cap_mask;
25677 +       __u32 cap_lower;
25678 +
25679 +       struct rlimit res[GR_NLIMITS];
25680 +       __u16 resmask;
25681 +
25682 +       __u8 user_trans_type;
25683 +       __u8 group_trans_type;
25684 +       uid_t *user_transitions;
25685 +       gid_t *group_transitions;
25686 +       __u16 user_trans_num;
25687 +       __u16 group_trans_num;
25688 +
25689 +       __u32 ip_proto[8];
25690 +       __u32 ip_type;
25691 +       struct acl_ip_label **ips;
25692 +       __u32 ip_num;
25693 +
25694 +       __u32 crashes;
25695 +       unsigned long expires;
25696 +
25697 +       struct acl_subject_label *parent_subject;
25698 +       struct gr_hash_struct *hash;
25699 +       struct acl_subject_label *prev;
25700 +       struct acl_subject_label *next;
25701 +
25702 +       struct acl_object_label **obj_hash;
25703 +       __u32 obj_hash_size;
25704 +       __u16 pax_flags;
25705 +};
25706 +
25707 +struct role_allowed_ip {
25708 +       __u32 addr;
25709 +       __u32 netmask;
25710 +
25711 +       struct role_allowed_ip *prev;
25712 +       struct role_allowed_ip *next;
25713 +};
25714 +
25715 +struct role_transition {
25716 +       char *rolename;
25717 +
25718 +       struct role_transition *prev;
25719 +       struct role_transition *next;
25720 +};
25721 +
25722 +struct acl_role_label {
25723 +       char *rolename;
25724 +       uid_t uidgid;
25725 +       __u16 roletype;
25726 +
25727 +       __u16 auth_attempts;
25728 +       unsigned long expires;
25729 +
25730 +       struct acl_subject_label *root_label;
25731 +       struct gr_hash_struct *hash;
25732 +
25733 +       struct acl_role_label *prev;
25734 +       struct acl_role_label *next;
25735 +
25736 +       struct role_transition *transitions;
25737 +       struct role_allowed_ip *allowed_ips;
25738 +       uid_t *domain_children;
25739 +       __u16 domain_child_num;
25740 +
25741 +       struct acl_subject_label **subj_hash;
25742 +       __u32 subj_hash_size;
25743 +};
25744 +
25745 +struct user_acl_role_db {
25746 +       struct acl_role_label **r_table;
25747 +       __u32 num_pointers;             /* Number of allocations to track */
25748 +       __u32 num_roles;                /* Number of roles */
25749 +       __u32 num_domain_children;      /* Number of domain children */
25750 +       __u32 num_subjects;             /* Number of subjects */
25751 +       __u32 num_objects;              /* Number of objects */
25752 +};
25753 +
25754 +struct acl_object_label {
25755 +       char *filename;
25756 +       ino_t inode;
25757 +       dev_t device;
25758 +       __u32 mode;
25759 +
25760 +       struct acl_subject_label *nested;
25761 +       struct acl_object_label *globbed;
25762 +
25763 +       /* next two structures not used */
25764 +
25765 +       struct acl_object_label *prev;
25766 +       struct acl_object_label *next;
25767 +};
25768 +
25769 +struct acl_ip_label {
25770 +       char *iface;
25771 +       __u32 addr;
25772 +       __u32 netmask;
25773 +       __u16 low, high;
25774 +       __u8 mode;
25775 +       __u32 type;
25776 +       __u32 proto[8];
25777 +
25778 +       /* next two structures not used */
25779 +
25780 +       struct acl_ip_label *prev;
25781 +       struct acl_ip_label *next;
25782 +};
25783 +
25784 +struct gr_arg {
25785 +       struct user_acl_role_db role_db;
25786 +       unsigned char pw[GR_PW_LEN];
25787 +       unsigned char salt[GR_SALT_LEN];
25788 +       unsigned char sum[GR_SHA_LEN];
25789 +       unsigned char sp_role[GR_SPROLE_LEN];
25790 +       struct sprole_pw *sprole_pws;
25791 +       dev_t segv_device;
25792 +       ino_t segv_inode;
25793 +       uid_t segv_uid;
25794 +       __u16 num_sprole_pws;
25795 +       __u16 mode;
25796 +};
25797 +
25798 +struct gr_arg_wrapper {
25799 +       struct gr_arg *arg;
25800 +       __u32 version;
25801 +       __u32 size;
25802 +};
25803 +
25804 +struct subject_map {
25805 +       struct acl_subject_label *user;
25806 +       struct acl_subject_label *kernel;
25807 +       struct subject_map *prev;
25808 +       struct subject_map *next;
25809 +};
25810 +
25811 +struct acl_subj_map_db {
25812 +       struct subject_map **s_hash;
25813 +       __u32 s_size;
25814 +};
25815 +
25816 +/* End Data Structures Section */
25817 +
25818 +/* Hash functions generated by empirical testing by Brad Spengler
25819 +   Makes good use of the low bits of the inode.  Generally 0-1 times
25820 +   in loop for successful match.  0-3 for unsuccessful match.
25821 +   Shift/add algorithm with modulus of table size and an XOR*/
25822 +
25823 +static __inline__ unsigned int
25824 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
25825 +{
25826 +       return (((uid << type) + (uid ^ type)) % sz);
25827 +}
25828 +
25829 + static __inline__ unsigned int
25830 +shash(const struct acl_subject_label *userp, const unsigned int sz)
25831 +{
25832 +       return ((const unsigned long)userp % sz);
25833 +}
25834 +
25835 +static __inline__ unsigned int
25836 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
25837 +{
25838 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
25839 +}
25840 +
25841 +static __inline__ unsigned int
25842 +nhash(const char *name, const __u16 len, const unsigned int sz)
25843 +{
25844 +       return full_name_hash(name, len) % sz;
25845 +}
25846 +
25847 +#define FOR_EACH_ROLE_START(role,iter) \
25848 +       role = NULL; \
25849 +       iter = 0; \
25850 +       while (iter < acl_role_set.r_size) { \
25851 +               if (role == NULL) \
25852 +                       role = acl_role_set.r_hash[iter]; \
25853 +               if (role == NULL) { \
25854 +                       iter++; \
25855 +                       continue; \
25856 +               }
25857 +
25858 +#define FOR_EACH_ROLE_END(role,iter) \
25859 +               role = role->next; \
25860 +               if (role == NULL) \
25861 +                       iter++; \
25862 +       }
25863 +
25864 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
25865 +       subj = NULL; \
25866 +       iter = 0; \
25867 +       while (iter < role->subj_hash_size) { \
25868 +               if (subj == NULL) \
25869 +                       subj = role->subj_hash[iter]; \
25870 +               if (subj == NULL) { \
25871 +                       iter++; \
25872 +                       continue; \
25873 +               }
25874 +
25875 +#define FOR_EACH_SUBJECT_END(subj,iter) \
25876 +               subj = subj->next; \
25877 +               if (subj == NULL) \
25878 +                       iter++; \
25879 +       }
25880 +
25881 +
25882 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
25883 +       subj = role->hash->first; \
25884 +       while (subj != NULL) {
25885 +
25886 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
25887 +               subj = subj->next; \
25888 +       }
25889 +
25890 +#endif
25891 +
25892 diff -urNp linux-2.6.20.3/include/linux/gralloc.h linux-2.6.20.3/include/linux/gralloc.h
25893 --- linux-2.6.20.3/include/linux/gralloc.h      1969-12-31 19:00:00.000000000 -0500
25894 +++ linux-2.6.20.3/include/linux/gralloc.h      2007-03-23 08:11:31.000000000 -0400
25895 @@ -0,0 +1,8 @@
25896 +#ifndef __GRALLOC_H
25897 +#define __GRALLOC_H
25898 +
25899 +void acl_free_all(void);
25900 +int acl_alloc_stack_init(unsigned long size);
25901 +void *acl_alloc(unsigned long len);
25902 +
25903 +#endif
25904 diff -urNp linux-2.6.20.3/include/linux/grdefs.h linux-2.6.20.3/include/linux/grdefs.h
25905 --- linux-2.6.20.3/include/linux/grdefs.h       1969-12-31 19:00:00.000000000 -0500
25906 +++ linux-2.6.20.3/include/linux/grdefs.h       2007-03-23 08:11:31.000000000 -0400
25907 @@ -0,0 +1,131 @@
25908 +#ifndef GRDEFS_H
25909 +#define GRDEFS_H
25910 +
25911 +/* Begin grsecurity status declarations */
25912 +
25913 +enum {
25914 +       GR_READY = 0x01,
25915 +       GR_STATUS_INIT = 0x00   // disabled state
25916 +};
25917 +
25918 +/* Begin  ACL declarations */
25919 +
25920 +/* Role flags */
25921 +
25922 +enum {
25923 +       GR_ROLE_USER = 0x0001,
25924 +       GR_ROLE_GROUP = 0x0002,
25925 +       GR_ROLE_DEFAULT = 0x0004,
25926 +       GR_ROLE_SPECIAL = 0x0008,
25927 +       GR_ROLE_AUTH = 0x0010,
25928 +       GR_ROLE_NOPW = 0x0020,
25929 +       GR_ROLE_GOD = 0x0040,
25930 +       GR_ROLE_LEARN = 0x0080,
25931 +       GR_ROLE_TPE = 0x0100,
25932 +       GR_ROLE_DOMAIN = 0x0200,
25933 +       GR_ROLE_PAM = 0x0400
25934 +};
25935 +
25936 +/* ACL Subject and Object mode flags */
25937 +enum {
25938 +       GR_DELETED = 0x80000000
25939 +};
25940 +
25941 +/* ACL Object-only mode flags */
25942 +enum {
25943 +       GR_READ         = 0x00000001,
25944 +       GR_APPEND       = 0x00000002,
25945 +       GR_WRITE        = 0x00000004,
25946 +       GR_EXEC         = 0x00000008,
25947 +       GR_FIND         = 0x00000010,
25948 +       GR_INHERIT      = 0x00000020,
25949 +       GR_SETID        = 0x00000040,
25950 +       GR_CREATE       = 0x00000080,
25951 +       GR_DELETE       = 0x00000100,
25952 +       GR_LINK         = 0x00000200,
25953 +       GR_AUDIT_READ   = 0x00000400,
25954 +       GR_AUDIT_APPEND = 0x00000800,
25955 +       GR_AUDIT_WRITE  = 0x00001000,
25956 +       GR_AUDIT_EXEC   = 0x00002000,
25957 +       GR_AUDIT_FIND   = 0x00004000,
25958 +       GR_AUDIT_INHERIT= 0x00008000,
25959 +       GR_AUDIT_SETID  = 0x00010000,
25960 +       GR_AUDIT_CREATE = 0x00020000,
25961 +       GR_AUDIT_DELETE = 0x00040000,
25962 +       GR_AUDIT_LINK   = 0x00080000,
25963 +       GR_PTRACERD     = 0x00100000,
25964 +       GR_NOPTRACE     = 0x00200000,
25965 +       GR_SUPPRESS     = 0x00400000,
25966 +       GR_NOLEARN      = 0x00800000
25967 +};
25968 +
25969 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
25970 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
25971 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
25972 +
25973 +/* ACL subject-only mode flags */
25974 +enum {
25975 +       GR_KILL         = 0x00000001,
25976 +       GR_VIEW         = 0x00000002,
25977 +       GR_PROTECTED    = 0x00000004,
25978 +       GR_LEARN        = 0x00000008,
25979 +       GR_OVERRIDE     = 0x00000010,
25980 +       /* just a placeholder, this mode is only used in userspace */
25981 +       GR_DUMMY        = 0x00000020,
25982 +       GR_PROTSHM      = 0x00000040,
25983 +       GR_KILLPROC     = 0x00000080,
25984 +       GR_KILLIPPROC   = 0x00000100,
25985 +       /* just a placeholder, this mode is only used in userspace */
25986 +       GR_NOTROJAN     = 0x00000200,
25987 +       GR_PROTPROCFD   = 0x00000400,
25988 +       GR_PROCACCT     = 0x00000800,
25989 +       GR_RELAXPTRACE  = 0x00001000,
25990 +       GR_NESTED       = 0x00002000,
25991 +       GR_INHERITLEARN = 0x00004000,
25992 +       GR_PROCFIND     = 0x00008000,
25993 +       GR_POVERRIDE    = 0x00010000,
25994 +       GR_KERNELAUTH   = 0x00020000,
25995 +};
25996 +
25997 +enum {
25998 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
25999 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
26000 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
26001 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
26002 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
26003 +       GR_PAX_DISABLE_SEGMEXEC = 0x0100,
26004 +       GR_PAX_DISABLE_PAGEEXEC = 0x0200,
26005 +       GR_PAX_DISABLE_MPROTECT = 0x0400,
26006 +       GR_PAX_DISABLE_RANDMMAP = 0x0800,
26007 +       GR_PAX_DISABLE_EMUTRAMP = 0x1000,
26008 +};
26009 +
26010 +enum {
26011 +       GR_ID_USER      = 0x01,
26012 +       GR_ID_GROUP     = 0x02,
26013 +};
26014 +
26015 +enum {
26016 +       GR_ID_ALLOW     = 0x01,
26017 +       GR_ID_DENY      = 0x02,
26018 +};
26019 +
26020 +#define GR_CRASH_RES   11
26021 +#define GR_UIDTABLE_MAX 500
26022 +
26023 +/* begin resource learning section */
26024 +enum {
26025 +       GR_RLIM_CPU_BUMP = 60,
26026 +       GR_RLIM_FSIZE_BUMP = 50000,
26027 +       GR_RLIM_DATA_BUMP = 10000,
26028 +       GR_RLIM_STACK_BUMP = 1000,
26029 +       GR_RLIM_CORE_BUMP = 10000,
26030 +       GR_RLIM_RSS_BUMP = 500000,
26031 +       GR_RLIM_NPROC_BUMP = 1,
26032 +       GR_RLIM_NOFILE_BUMP = 5,
26033 +       GR_RLIM_MEMLOCK_BUMP = 50000,
26034 +       GR_RLIM_AS_BUMP = 500000,
26035 +       GR_RLIM_LOCKS_BUMP = 2
26036 +};
26037 +
26038 +#endif
26039 diff -urNp linux-2.6.20.3/include/linux/grinternal.h linux-2.6.20.3/include/linux/grinternal.h
26040 --- linux-2.6.20.3/include/linux/grinternal.h   1969-12-31 19:00:00.000000000 -0500
26041 +++ linux-2.6.20.3/include/linux/grinternal.h   2007-03-23 08:11:31.000000000 -0400
26042 @@ -0,0 +1,208 @@
26043 +#ifndef __GRINTERNAL_H
26044 +#define __GRINTERNAL_H
26045 +
26046 +#ifdef CONFIG_GRKERNSEC
26047 +
26048 +#include <linux/fs.h>
26049 +#include <linux/gracl.h>
26050 +#include <linux/grdefs.h>
26051 +#include <linux/grmsg.h>
26052 +
26053 +void gr_add_learn_entry(const char *fmt, ...);
26054 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
26055 +                           const struct vfsmount *mnt);
26056 +__u32 gr_check_create(const struct dentry *new_dentry,
26057 +                            const struct dentry *parent,
26058 +                            const struct vfsmount *mnt, const __u32 mode);
26059 +int gr_check_protected_task(const struct task_struct *task);
26060 +__u32 to_gr_audit(const __u32 reqmode);
26061 +int gr_set_acls(const int type);
26062 +
26063 +int gr_acl_is_enabled(void);
26064 +char gr_roletype_to_char(void);
26065 +
26066 +void gr_handle_alertkill(struct task_struct *task);
26067 +char *gr_to_filename(const struct dentry *dentry,
26068 +                           const struct vfsmount *mnt);
26069 +char *gr_to_filename1(const struct dentry *dentry,
26070 +                           const struct vfsmount *mnt);
26071 +char *gr_to_filename2(const struct dentry *dentry,
26072 +                           const struct vfsmount *mnt);
26073 +char *gr_to_filename3(const struct dentry *dentry,
26074 +                           const struct vfsmount *mnt);
26075 +
26076 +extern int grsec_enable_link;
26077 +extern int grsec_enable_fifo;
26078 +extern int grsec_enable_execve;
26079 +extern int grsec_enable_shm;
26080 +extern int grsec_enable_execlog;
26081 +extern int grsec_enable_signal;
26082 +extern int grsec_enable_forkfail;
26083 +extern int grsec_enable_time;
26084 +extern int grsec_enable_chroot_shmat;
26085 +extern int grsec_enable_chroot_findtask;
26086 +extern int grsec_enable_chroot_mount;
26087 +extern int grsec_enable_chroot_double;
26088 +extern int grsec_enable_chroot_pivot;
26089 +extern int grsec_enable_chroot_chdir;
26090 +extern int grsec_enable_chroot_chmod;
26091 +extern int grsec_enable_chroot_mknod;
26092 +extern int grsec_enable_chroot_fchdir;
26093 +extern int grsec_enable_chroot_nice;
26094 +extern int grsec_enable_chroot_execlog;
26095 +extern int grsec_enable_chroot_caps;
26096 +extern int grsec_enable_chroot_sysctl;
26097 +extern int grsec_enable_chroot_unix;
26098 +extern int grsec_enable_tpe;
26099 +extern int grsec_tpe_gid;
26100 +extern int grsec_enable_tpe_all;
26101 +extern int grsec_enable_sidcaps;
26102 +extern int grsec_enable_socket_all;
26103 +extern int grsec_socket_all_gid;
26104 +extern int grsec_enable_socket_client;
26105 +extern int grsec_socket_client_gid;
26106 +extern int grsec_enable_socket_server;
26107 +extern int grsec_socket_server_gid;
26108 +extern int grsec_audit_gid;
26109 +extern int grsec_enable_group;
26110 +extern int grsec_enable_audit_ipc;
26111 +extern int grsec_enable_audit_textrel;
26112 +extern int grsec_enable_mount;
26113 +extern int grsec_enable_chdir;
26114 +extern int grsec_resource_logging;
26115 +extern int grsec_lock;
26116 +
26117 +extern spinlock_t grsec_alert_lock;
26118 +extern unsigned long grsec_alert_wtime;
26119 +extern unsigned long grsec_alert_fyet;
26120 +
26121 +extern spinlock_t grsec_audit_lock;
26122 +
26123 +extern rwlock_t grsec_exec_file_lock;
26124 +
26125 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
26126 +                       gr_to_filename2(tsk->exec_file->f_dentry, \
26127 +                       tsk->exec_file->f_vfsmnt) : "/")
26128 +
26129 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
26130 +                       gr_to_filename3(tsk->parent->exec_file->f_dentry, \
26131 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
26132 +
26133 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
26134 +                       gr_to_filename(tsk->exec_file->f_dentry, \
26135 +                       tsk->exec_file->f_vfsmnt) : "/")
26136 +
26137 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
26138 +                       gr_to_filename1(tsk->parent->exec_file->f_dentry, \
26139 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
26140 +
26141 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
26142 +                         ((tsk_a->fs->root->d_inode->i_sb->s_dev != \
26143 +                         child_reaper(tsk_a)->fs->root->d_inode->i_sb->s_dev) || \
26144 +                         (tsk_a->fs->root->d_inode->i_ino != \
26145 +                         child_reaper(tsk_a)->fs->root->d_inode->i_ino)))
26146 +
26147 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
26148 +                         (tsk_a->fs->root->d_inode->i_sb->s_dev == \
26149 +                         tsk_b->fs->root->d_inode->i_sb->s_dev) && \
26150 +                         (tsk_a->fs->root->d_inode->i_ino == \
26151 +                         tsk_b->fs->root->d_inode->i_ino))
26152 +
26153 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
26154 +                      task->pid, task->uid, \
26155 +                      task->euid, task->gid, task->egid, \
26156 +                      gr_parent_task_fullpath(task), \
26157 +                      task->parent->comm, task->parent->pid, \
26158 +                      task->parent->uid, task->parent->euid, \
26159 +                      task->parent->gid, task->parent->egid
26160 +
26161 +#define GR_CHROOT_CAPS ( \
26162 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
26163 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
26164 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
26165 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
26166 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
26167 +       CAP_TO_MASK(CAP_IPC_OWNER))
26168 +
26169 +#define security_learn(normal_msg,args...) \
26170 +({ \
26171 +       read_lock(&grsec_exec_file_lock); \
26172 +       gr_add_learn_entry(normal_msg "\n", ## args); \
26173 +       read_unlock(&grsec_exec_file_lock); \
26174 +})
26175 +
26176 +enum {
26177 +       GR_DO_AUDIT,
26178 +       GR_DONT_AUDIT,
26179 +       GR_DONT_AUDIT_GOOD
26180 +};
26181 +
26182 +enum {
26183 +       GR_TTYSNIFF,
26184 +       GR_RBAC,
26185 +       GR_RBAC_STR,
26186 +       GR_STR_RBAC,
26187 +       GR_RBAC_MODE2,
26188 +       GR_RBAC_MODE3,
26189 +       GR_FILENAME,
26190 +       GR_NOARGS,
26191 +       GR_ONE_INT,
26192 +       GR_ONE_INT_TWO_STR,
26193 +       GR_ONE_STR,
26194 +       GR_STR_INT,
26195 +       GR_TWO_INT,
26196 +       GR_THREE_INT,
26197 +       GR_FIVE_INT_TWO_STR,
26198 +       GR_TWO_STR,
26199 +       GR_THREE_STR,
26200 +       GR_FOUR_STR,
26201 +       GR_STR_FILENAME,
26202 +       GR_FILENAME_STR,
26203 +       GR_FILENAME_TWO_INT,
26204 +       GR_FILENAME_TWO_INT_STR,
26205 +       GR_TEXTREL,
26206 +       GR_PTRACE,
26207 +       GR_RESOURCE,
26208 +       GR_CAP,
26209 +       GR_SIG,
26210 +       GR_CRASH1,
26211 +       GR_CRASH2,
26212 +       GR_PSACCT
26213 +};
26214 +
26215 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
26216 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
26217 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
26218 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
26219 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
26220 +#define gr_log_fs_rbac_mode3(audit, msg, dentry, mnt, str1, str2, str3) gr_log_varargs(audit, msg, GR_RBAC_MODE3, dentry, mnt, str1, str2, str3)
26221 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
26222 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
26223 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
26224 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
26225 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
26226 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
26227 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
26228 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
26229 +#define gr_log_int5_str2(audit, msg, num1, num2, str1, str2) gr_log_varargs(audit, msg, GR_FIVE_INT_TWO_STR, num1, num2, str1, str2)
26230 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
26231 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
26232 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
26233 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
26234 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
26235 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
26236 +#define gr_log_fs_int2_str(audit, msg, dentry, mnt, num1, num2, str) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT_STR, dentry, mnt, num1, num2, str)
26237 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
26238 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
26239 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
26240 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
26241 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
26242 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
26243 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
26244 +#define gr_log_procacct(audit, msg, task, num1, num2, num3, num4, num5, num6, num7, num8, num9) gr_log_varargs(audit, msg, GR_PSACCT, task, num1, num2, num3, num4, num5, num6, num7, num8, num9)
26245 +
26246 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
26247 +
26248 +#endif
26249 +
26250 +#endif
26251 diff -urNp linux-2.6.20.3/include/linux/grmsg.h linux-2.6.20.3/include/linux/grmsg.h
26252 --- linux-2.6.20.3/include/linux/grmsg.h        1969-12-31 19:00:00.000000000 -0500
26253 +++ linux-2.6.20.3/include/linux/grmsg.h        2007-03-23 08:11:31.000000000 -0400
26254 @@ -0,0 +1,108 @@
26255 +#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
26256 +#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%u.%u.%u.%u TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
26257 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
26258 +#define GR_STOPMOD_MSG "denied modification of module state by "
26259 +#define GR_IOPERM_MSG "denied use of ioperm() by "
26260 +#define GR_IOPL_MSG "denied use of iopl() by "
26261 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
26262 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
26263 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
26264 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
26265 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
26266 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
26267 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
26268 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
26269 +#define GR_LEARN_AUDIT_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%lu\t%lu\t%.4095s\t%lu\t%u.%u.%u.%u"
26270 +#define GR_ID_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%c\t%d\t%d\t%d\t%u.%u.%u.%u"
26271 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
26272 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
26273 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
26274 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
26275 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
26276 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
26277 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
26278 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
26279 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
26280 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
26281 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
26282 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
26283 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
26284 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
26285 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
26286 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
26287 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
26288 +#define GR_NPROC_MSG "denied overstep of process limit by "
26289 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
26290 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
26291 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
26292 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
26293 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.30s as %.930s from chroot by "
26294 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
26295 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
26296 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
26297 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
26298 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
26299 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
26300 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
26301 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
26302 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
26303 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
26304 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
26305 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
26306 +#define GR_DISABLED_ACL_MSG "Error loading %s, trying to run kernel with acls disabled. To disable acls at startup use <kernel image name> gracl=off from your boot loader"
26307 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
26308 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
26309 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
26310 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
26311 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
26312 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
26313 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
26314 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
26315 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
26316 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
26317 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
26318 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
26319 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
26320 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
26321 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
26322 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
26323 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
26324 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
26325 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
26326 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
26327 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
26328 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
26329 +#define GR_NICE_CHROOT_MSG "denied priority change by "
26330 +#define GR_UNISIGLOG_MSG "signal %d sent to "
26331 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
26332 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
26333 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
26334 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
26335 +#define GR_TIME_MSG "time set by "
26336 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
26337 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
26338 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
26339 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
26340 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
26341 +#define GR_BIND_MSG "denied bind() by "
26342 +#define GR_CONNECT_MSG "denied connect() by "
26343 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
26344 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
26345 +#define GR_IP_LEARN_MSG "%s\t%u\t%u\t%u\t%.4095s\t%.4095s\t%u.%u.%u.%u\t%u\t%u\t%u\t%u\t%u.%u.%u.%u"
26346 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
26347 +#define GR_CAP_ACL_MSG "use of %s denied for "
26348 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
26349 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
26350 +#define GR_REMOUNT_AUDIT_MSG "remount of %.30s by "
26351 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.30s by "
26352 +#define GR_MOUNT_AUDIT_MSG "mount of %.30s to %.64s by "
26353 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
26354 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
26355 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
26356 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
26357 +#define GR_SEM_AUDIT_MSG "semaphore created by "
26358 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
26359 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
26360 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
26361 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
26362 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
26363 diff -urNp linux-2.6.20.3/include/linux/grsecurity.h linux-2.6.20.3/include/linux/grsecurity.h
26364 --- linux-2.6.20.3/include/linux/grsecurity.h   1969-12-31 19:00:00.000000000 -0500
26365 +++ linux-2.6.20.3/include/linux/grsecurity.h   2007-03-23 08:11:31.000000000 -0400
26366 @@ -0,0 +1,196 @@
26367 +#ifndef GR_SECURITY_H
26368 +#define GR_SECURITY_H
26369 +#include <linux/fs.h>
26370 +#include <linux/binfmts.h>
26371 +#include <linux/gracl.h>
26372 +
26373 +void gr_handle_brute_attach(struct task_struct *p);
26374 +void gr_handle_brute_check(void);
26375 +
26376 +char gr_roletype_to_char(void);
26377 +
26378 +int gr_check_user_change(int real, int effective, int fs);
26379 +int gr_check_group_change(int real, int effective, int fs);
26380 +
26381 +void gr_del_task_from_ip_table(struct task_struct *p);
26382 +
26383 +int gr_pid_is_chrooted(struct task_struct *p);
26384 +int gr_handle_chroot_nice(void);
26385 +int gr_handle_chroot_sysctl(const int op);
26386 +int gr_handle_chroot_setpriority(struct task_struct *p,
26387 +                                       const int niceval);
26388 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
26389 +int gr_handle_chroot_chroot(const struct dentry *dentry,
26390 +                                  const struct vfsmount *mnt);
26391 +void gr_handle_chroot_caps(struct task_struct *task);
26392 +void gr_handle_chroot_chdir(struct dentry *dentry, struct vfsmount *mnt);
26393 +int gr_handle_chroot_chmod(const struct dentry *dentry,
26394 +                                 const struct vfsmount *mnt, const int mode);
26395 +int gr_handle_chroot_mknod(const struct dentry *dentry,
26396 +                                 const struct vfsmount *mnt, const int mode);
26397 +int gr_handle_chroot_mount(const struct dentry *dentry,
26398 +                                 const struct vfsmount *mnt,
26399 +                                 const char *dev_name);
26400 +int gr_handle_chroot_pivot(void);
26401 +int gr_handle_chroot_unix(const pid_t pid);
26402 +
26403 +int gr_handle_rawio(const struct inode *inode);
26404 +int gr_handle_nproc(void);
26405 +
26406 +void gr_handle_ioperm(void);
26407 +void gr_handle_iopl(void);
26408 +
26409 +int gr_tpe_allow(const struct file *file);
26410 +
26411 +int gr_random_pid(void);
26412 +
26413 +void gr_log_forkfail(const int retval);
26414 +void gr_log_timechange(void);
26415 +void gr_log_signal(const int sig, const struct task_struct *t);
26416 +void gr_log_chdir(const struct dentry *dentry,
26417 +                        const struct vfsmount *mnt);
26418 +void gr_log_chroot_exec(const struct dentry *dentry,
26419 +                              const struct vfsmount *mnt);
26420 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
26421 +void gr_log_remount(const char *devname, const int retval);
26422 +void gr_log_unmount(const char *devname, const int retval);
26423 +void gr_log_mount(const char *from, const char *to, const int retval);
26424 +void gr_log_msgget(const int ret, const int msgflg);
26425 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
26426 +void gr_log_semget(const int err, const int semflg);
26427 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
26428 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
26429 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
26430 +void gr_log_textrel(struct vm_area_struct *vma);
26431 +
26432 +int gr_handle_follow_link(const struct inode *parent,
26433 +                                const struct inode *inode,
26434 +                                const struct dentry *dentry,
26435 +                                const struct vfsmount *mnt);
26436 +int gr_handle_fifo(const struct dentry *dentry,
26437 +                         const struct vfsmount *mnt,
26438 +                         const struct dentry *dir, const int flag,
26439 +                         const int acc_mode);
26440 +int gr_handle_hardlink(const struct dentry *dentry,
26441 +                             const struct vfsmount *mnt,
26442 +                             struct inode *inode,
26443 +                             const int mode, const char *to);
26444 +
26445 +int gr_task_is_capable(struct task_struct *task, const int cap);
26446 +int gr_is_capable_nolog(const int cap);
26447 +void gr_learn_resource(const struct task_struct *task, const int limit,
26448 +                             const unsigned long wanted, const int gt);
26449 +void gr_copy_label(struct task_struct *tsk);
26450 +void gr_handle_crash(struct task_struct *task, const int sig);
26451 +int gr_handle_signal(const struct task_struct *p, const int sig);
26452 +int gr_check_crash_uid(const uid_t uid);
26453 +int gr_check_protected_task(const struct task_struct *task);
26454 +int gr_acl_handle_mmap(const struct file *file,
26455 +                             const unsigned long prot);
26456 +int gr_acl_handle_mprotect(const struct file *file,
26457 +                                 const unsigned long prot);
26458 +int gr_check_hidden_task(const struct task_struct *tsk);
26459 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
26460 +                                   const struct vfsmount *mnt);
26461 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
26462 +                                const struct vfsmount *mnt);
26463 +__u32 gr_acl_handle_access(const struct dentry *dentry,
26464 +                                 const struct vfsmount *mnt, const int fmode);
26465 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
26466 +                                 const struct vfsmount *mnt, mode_t mode);
26467 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
26468 +                                const struct vfsmount *mnt, mode_t mode);
26469 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
26470 +                                const struct vfsmount *mnt);
26471 +int gr_handle_ptrace(struct task_struct *task, const long request);
26472 +int gr_handle_proc_ptrace(struct task_struct *task);
26473 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
26474 +                                 const struct vfsmount *mnt);
26475 +int gr_check_crash_exec(const struct file *filp);
26476 +int gr_acl_is_enabled(void);
26477 +void gr_set_kernel_label(struct task_struct *task);
26478 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
26479 +                             const gid_t gid);
26480 +int gr_set_proc_label(const struct dentry *dentry,
26481 +                             const struct vfsmount *mnt);
26482 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
26483 +                                      const struct vfsmount *mnt);
26484 +__u32 gr_acl_handle_open(const struct dentry *dentry,
26485 +                               const struct vfsmount *mnt, const int fmode);
26486 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
26487 +                                const struct dentry *p_dentry,
26488 +                                const struct vfsmount *p_mnt, const int fmode,
26489 +                                const int imode);
26490 +void gr_handle_create(const struct dentry *dentry,
26491 +                            const struct vfsmount *mnt);
26492 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
26493 +                                const struct dentry *parent_dentry,
26494 +                                const struct vfsmount *parent_mnt,
26495 +                                const int mode);
26496 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
26497 +                                const struct dentry *parent_dentry,
26498 +                                const struct vfsmount *parent_mnt);
26499 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
26500 +                                const struct vfsmount *mnt);
26501 +void gr_handle_delete(const ino_t ino, const dev_t dev);
26502 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
26503 +                                 const struct vfsmount *mnt);
26504 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
26505 +                                  const struct dentry *parent_dentry,
26506 +                                  const struct vfsmount *parent_mnt,
26507 +                                  const char *from);
26508 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
26509 +                               const struct dentry *parent_dentry,
26510 +                               const struct vfsmount *parent_mnt,
26511 +                               const struct dentry *old_dentry,
26512 +                               const struct vfsmount *old_mnt, const char *to);
26513 +int gr_acl_handle_rename(struct dentry *new_dentry,
26514 +                               struct dentry *parent_dentry,
26515 +                               const struct vfsmount *parent_mnt,
26516 +                               struct dentry *old_dentry,
26517 +                               struct inode *old_parent_inode,
26518 +                               struct vfsmount *old_mnt, const char *newname);
26519 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
26520 +                               struct dentry *old_dentry,
26521 +                               struct dentry *new_dentry,
26522 +                               struct vfsmount *mnt, const __u8 replace);
26523 +__u32 gr_check_link(const struct dentry *new_dentry,
26524 +                          const struct dentry *parent_dentry,
26525 +                          const struct vfsmount *parent_mnt,
26526 +                          const struct dentry *old_dentry,
26527 +                          const struct vfsmount *old_mnt);
26528 +int gr_acl_handle_filldir(const struct file *file, const char *name,
26529 +                                const unsigned int namelen, const ino_t ino);
26530 +
26531 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
26532 +                               const struct vfsmount *mnt);
26533 +void gr_acl_handle_exit(void);
26534 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
26535 +int gr_acl_handle_procpidmem(const struct task_struct *task);
26536 +__u32 gr_cap_rtnetlink(void);
26537 +
26538 +#ifdef CONFIG_SYSVIPC
26539 +void gr_shm_exit(struct task_struct *task);
26540 +#else
26541 +static inline void gr_shm_exit(struct task_struct *task)
26542 +{
26543 +       return;
26544 +}
26545 +#endif
26546 +
26547 +#ifdef CONFIG_GRKERNSEC
26548 +void gr_handle_mem_write(void);
26549 +void gr_handle_kmem_write(void);
26550 +void gr_handle_open_port(void);
26551 +int gr_handle_mem_mmap(const unsigned long offset,
26552 +                             struct vm_area_struct *vma);
26553 +
26554 +unsigned long pax_get_random_long(void);
26555 +#define get_random_long() pax_get_random_long()
26556 +
26557 +extern int grsec_enable_dmesg;
26558 +extern int grsec_enable_randsrc;
26559 +extern int grsec_enable_shm;
26560 +#endif
26561 +
26562 +#endif
26563 diff -urNp linux-2.6.20.3/include/linux/highmem.h linux-2.6.20.3/include/linux/highmem.h
26564 --- linux-2.6.20.3/include/linux/highmem.h      2007-03-13 14:27:08.000000000 -0400
26565 +++ linux-2.6.20.3/include/linux/highmem.h      2007-03-23 08:10:06.000000000 -0400
26566 @@ -81,6 +81,13 @@ static inline void clear_highpage(struct
26567         kunmap_atomic(kaddr, KM_USER0);
26568  }
26569  
26570 +static inline void sanitize_highpage(struct page *page)
26571 +{
26572 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
26573 +       clear_page(kaddr);
26574 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
26575 +}
26576 +
26577  /*
26578   * Same but also flushes aliased cache contents to RAM.
26579   */
26580 diff -urNp linux-2.6.20.3/include/linux/jbd2.h linux-2.6.20.3/include/linux/jbd2.h
26581 --- linux-2.6.20.3/include/linux/jbd2.h 2007-03-13 14:27:08.000000000 -0400
26582 +++ linux-2.6.20.3/include/linux/jbd2.h 2007-03-23 08:10:06.000000000 -0400
26583 @@ -68,7 +68,7 @@ extern int jbd2_journal_enable_debug;
26584                 }                                                       \
26585         } while (0)
26586  #else
26587 -#define jbd_debug(f, a...)     /**/
26588 +#define jbd_debug(f, a...)     do {} while (0)
26589  #endif
26590  
26591  extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
26592 diff -urNp linux-2.6.20.3/include/linux/jbd.h linux-2.6.20.3/include/linux/jbd.h
26593 --- linux-2.6.20.3/include/linux/jbd.h  2007-03-13 14:27:08.000000000 -0400
26594 +++ linux-2.6.20.3/include/linux/jbd.h  2007-03-23 08:10:06.000000000 -0400
26595 @@ -68,7 +68,7 @@ extern int journal_enable_debug;
26596                 }                                                       \
26597         } while (0)
26598  #else
26599 -#define jbd_debug(f, a...)     /**/
26600 +#define jbd_debug(f, a...)     do {} while (0)
26601  #endif
26602  
26603  extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry);
26604 diff -urNp linux-2.6.20.3/include/linux/mman.h linux-2.6.20.3/include/linux/mman.h
26605 --- linux-2.6.20.3/include/linux/mman.h 2007-03-13 14:27:08.000000000 -0400
26606 +++ linux-2.6.20.3/include/linux/mman.h 2007-03-23 08:10:06.000000000 -0400
26607 @@ -61,6 +61,11 @@ static inline unsigned long
26608  calc_vm_flag_bits(unsigned long flags)
26609  {
26610         return _calc_vm_trans(flags, MAP_GROWSDOWN,  VM_GROWSDOWN ) |
26611 +
26612 +#ifdef CONFIG_PAX_SEGMEXEC
26613 +              _calc_vm_trans(flags, MAP_MIRROR, VM_MIRROR) |
26614 +#endif
26615 +
26616                _calc_vm_trans(flags, MAP_DENYWRITE,  VM_DENYWRITE ) |
26617                _calc_vm_trans(flags, MAP_EXECUTABLE, VM_EXECUTABLE) |
26618                _calc_vm_trans(flags, MAP_LOCKED,     VM_LOCKED    );
26619 diff -urNp linux-2.6.20.3/include/linux/mm.h linux-2.6.20.3/include/linux/mm.h
26620 --- linux-2.6.20.3/include/linux/mm.h   2007-03-13 14:27:08.000000000 -0400
26621 +++ linux-2.6.20.3/include/linux/mm.h   2007-03-23 08:10:06.000000000 -0400
26622 @@ -39,6 +39,7 @@ extern int sysctl_legacy_va_layout;
26623  #include <asm/page.h>
26624  #include <asm/pgtable.h>
26625  #include <asm/processor.h>
26626 +#include <asm/mman.h>
26627  
26628  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
26629  
26630 @@ -112,8 +113,43 @@ struct vm_area_struct {
26631  #ifdef CONFIG_NUMA
26632         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
26633  #endif
26634 +
26635 +       unsigned long vm_mirror;        /* PaX: mirror distance */
26636  };
26637  
26638 +#ifdef CONFIG_PAX_SOFTMODE
26639 +extern unsigned int pax_softmode;
26640 +#endif
26641 +
26642 +extern int pax_check_flags(unsigned long *);
26643 +
26644 +/* if tsk != current then task_lock must be held on it */
26645 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
26646 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
26647 +{
26648 +       if (likely(tsk->mm))
26649 +               return tsk->mm->pax_flags;
26650 +       else
26651 +               return 0UL;
26652 +}
26653 +
26654 +/* if tsk != current then task_lock must be held on it */
26655 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
26656 +{
26657 +       if (likely(tsk->mm)) {
26658 +               tsk->mm->pax_flags = flags;
26659 +               return 0;
26660 +       }
26661 +       return -EINVAL;
26662 +}
26663 +#endif
26664 +
26665 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
26666 +extern void pax_set_initial_flags(struct linux_binprm * bprm);
26667 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
26668 +extern void (*pax_set_initial_flags_func)(struct linux_binprm * bprm);
26669 +#endif
26670 +
26671  extern struct kmem_cache *vm_area_cachep;
26672  
26673  /*
26674 @@ -170,6 +206,18 @@ extern unsigned int kobjsize(const void 
26675  #define VM_INSERTPAGE  0x02000000      /* The vma has had "vm_insert_page()" done on it */
26676  #define VM_ALWAYSDUMP  0x04000000      /* Always include in core dumps */
26677  
26678 +#ifdef CONFIG_PAX_SEGMEXEC
26679 +#define VM_MIRROR      0x08000000      /* vma is mirroring another */
26680 +#endif
26681 +
26682 +#ifdef CONFIG_PAX_MPROTECT
26683 +#define VM_MAYNOTWRITE 0x10000000      /* vma cannot be granted VM_WRITE any more */
26684 +#endif
26685 +
26686 +#ifdef __VM_STACK_FLAGS
26687 +#define VM_STACK_DEFAULT_FLAGS (0x00000033 | __VM_STACK_FLAGS)
26688 +#endif
26689 +
26690  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
26691  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
26692  #endif
26693 @@ -1115,7 +1163,6 @@ static inline unsigned long vma_pages(st
26694  }
26695  
26696  pgprot_t vm_get_page_prot(unsigned long vm_flags);
26697 -struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
26698  struct page *vmalloc_to_page(void *addr);
26699  unsigned long vmalloc_to_pfn(void *addr);
26700  int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
26701 @@ -1167,5 +1214,11 @@ extern int randomize_va_space;
26702  
26703  __attribute__((weak)) const char *arch_vma_name(struct vm_area_struct *vma);
26704  
26705 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
26706 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
26707 +#else
26708 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
26709 +#endif
26710 +
26711  #endif /* __KERNEL__ */
26712  #endif /* _LINUX_MM_H */
26713 diff -urNp linux-2.6.20.3/include/linux/module.h linux-2.6.20.3/include/linux/module.h
26714 --- linux-2.6.20.3/include/linux/module.h       2007-03-13 14:27:08.000000000 -0400
26715 +++ linux-2.6.20.3/include/linux/module.h       2007-03-23 08:10:06.000000000 -0400
26716 @@ -297,16 +297,16 @@ struct module
26717         int (*init)(void);
26718  
26719         /* If this is non-NULL, vfree after init() returns */
26720 -       void *module_init;
26721 +       void *module_init_rx, *module_init_rw;
26722  
26723         /* Here is the actual code + data, vfree'd on unload. */
26724 -       void *module_core;
26725 +       void *module_core_rx, *module_core_rw;
26726  
26727         /* Here are the sizes of the init and core sections */
26728 -       unsigned long init_size, core_size;
26729 +       unsigned long init_size_rw, core_size_rw;
26730  
26731         /* The size of the executable code in each section.  */
26732 -       unsigned long init_text_size, core_text_size;
26733 +       unsigned long init_size_rx, core_size_rx;
26734  
26735         /* The handle returned from unwind_add_table. */
26736         void *unwind_info;
26737 diff -urNp linux-2.6.20.3/include/linux/moduleloader.h linux-2.6.20.3/include/linux/moduleloader.h
26738 --- linux-2.6.20.3/include/linux/moduleloader.h 2007-03-13 14:27:08.000000000 -0400
26739 +++ linux-2.6.20.3/include/linux/moduleloader.h 2007-03-23 08:10:06.000000000 -0400
26740 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
26741     sections.  Returns NULL on failure. */
26742  void *module_alloc(unsigned long size);
26743  
26744 +#ifdef CONFIG_PAX_KERNEXEC
26745 +void *module_alloc_exec(unsigned long size);
26746 +#else
26747 +#define module_alloc_exec(x) module_alloc(x)
26748 +#endif
26749 +
26750  /* Free memory returned from module_alloc. */
26751  void module_free(struct module *mod, void *module_region);
26752  
26753 +#ifdef CONFIG_PAX_KERNEXEC
26754 +void module_free_exec(struct module *mod, void *module_region);
26755 +#else
26756 +#define module_free_exec(x, y) module_free(x, y)
26757 +#endif
26758 +
26759  /* Apply the given relocation to the (simplified) ELF.  Return -error
26760     or 0. */
26761  int apply_relocate(Elf_Shdr *sechdrs,
26762 diff -urNp linux-2.6.20.3/include/linux/random.h linux-2.6.20.3/include/linux/random.h
26763 --- linux-2.6.20.3/include/linux/random.h       2007-03-13 14:27:08.000000000 -0400
26764 +++ linux-2.6.20.3/include/linux/random.h       2007-03-23 08:10:06.000000000 -0400
26765 @@ -62,6 +62,8 @@ extern __u32 secure_tcpv6_sequence_numbe
26766  extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
26767                                        __be16 sport, __be16 dport);
26768  
26769 +extern unsigned long pax_get_random_long(void);
26770 +
26771  #ifndef MODULE
26772  extern struct file_operations random_fops, urandom_fops;
26773  #endif
26774 diff -urNp linux-2.6.20.3/include/linux/sched.h linux-2.6.20.3/include/linux/sched.h
26775 --- linux-2.6.20.3/include/linux/sched.h        2007-03-13 14:27:08.000000000 -0400
26776 +++ linux-2.6.20.3/include/linux/sched.h        2007-03-23 08:11:31.000000000 -0400
26777 @@ -88,6 +88,7 @@ struct sched_param {
26778  
26779  struct exec_domain;
26780  struct futex_pi_state;
26781 +struct linux_binprm;
26782  
26783  /*
26784   * List of flags we want to share for kernel threads,
26785 @@ -373,8 +374,34 @@ struct mm_struct {
26786         /* aio bits */
26787         rwlock_t                ioctx_list_lock;
26788         struct kioctx           *ioctx_list;
26789 +
26790 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
26791 +       unsigned long pax_flags;
26792 +#endif
26793 +
26794 +#ifdef CONFIG_PAX_DLRESOLVE
26795 +       unsigned long call_dl_resolve;
26796 +#endif
26797 +
26798 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
26799 +       unsigned long call_syscall;
26800 +#endif
26801 +
26802 +#ifdef CONFIG_PAX_ASLR
26803 +       unsigned long delta_mmap;               /* randomized offset */
26804 +       unsigned long delta_exec;               /* randomized offset */
26805 +       unsigned long delta_stack;              /* randomized offset */
26806 +#endif
26807 +
26808  };
26809  
26810 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
26811 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
26812 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
26813 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
26814 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
26815 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
26816 +
26817  struct sighand_struct {
26818         atomic_t                count;
26819         struct k_sigaction      action[_NSIG];
26820 @@ -491,6 +518,15 @@ struct signal_struct {
26821  #ifdef CONFIG_TASKSTATS
26822         struct taskstats *stats;
26823  #endif
26824 +
26825 +#ifdef CONFIG_GRKERNSEC
26826 +       u32 curr_ip;
26827 +       u32 gr_saddr;
26828 +       u32 gr_daddr;
26829 +       u16 gr_sport;
26830 +       u16 gr_dport;
26831 +       u8 used_accept:1;
26832 +#endif
26833  };
26834  
26835  /* Context switch must be unlocked if interrupts are to be enabled */
26836 @@ -1038,6 +1074,17 @@ struct task_struct {
26837         struct list_head pi_state_list;
26838         struct futex_pi_state *pi_state_cache;
26839  
26840 +#ifdef CONFIG_GRKERNSEC
26841 +       /* grsecurity */
26842 +       struct acl_subject_label *acl;
26843 +       struct acl_role_label *role;
26844 +       struct file *exec_file;
26845 +       u16 acl_role_id;
26846 +       u8 acl_sp_role:1;
26847 +       u8 is_writable:1;
26848 +       u8 brute:1;
26849 +#endif
26850 +
26851         atomic_t fs_excl;       /* holding fs exclusive resources */
26852         struct rcu_head rcu;
26853  
26854 @@ -1634,6 +1681,12 @@ extern void arch_pick_mmap_layout(struct
26855  static inline void arch_pick_mmap_layout(struct mm_struct *mm)
26856  {
26857         mm->mmap_base = TASK_UNMAPPED_BASE;
26858 +
26859 +#ifdef CONFIG_PAX_RANDMMAP
26860 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
26861 +               mm->mmap_base += mm->delta_mmap;
26862 +#endif
26863 +
26864         mm->get_unmapped_area = arch_get_unmapped_area;
26865         mm->unmap_area = arch_unmap_area;
26866  }
26867 diff -urNp linux-2.6.20.3/include/linux/shm.h linux-2.6.20.3/include/linux/shm.h
26868 --- linux-2.6.20.3/include/linux/shm.h  2007-03-13 14:27:08.000000000 -0400
26869 +++ linux-2.6.20.3/include/linux/shm.h  2007-03-23 08:11:31.000000000 -0400
26870 @@ -86,6 +86,10 @@ struct shmid_kernel /* private to the ke
26871         pid_t                   shm_cprid;
26872         pid_t                   shm_lprid;
26873         struct user_struct      *mlock_user;
26874 +#ifdef CONFIG_GRKERNSEC
26875 +       time_t                  shm_createtime;
26876 +       pid_t                   shm_lapid;
26877 +#endif
26878  };
26879  
26880  /* shm_mode upper byte flags */
26881 diff -urNp linux-2.6.20.3/include/linux/skbuff.h linux-2.6.20.3/include/linux/skbuff.h
26882 --- linux-2.6.20.3/include/linux/skbuff.h       2007-03-13 14:27:08.000000000 -0400
26883 +++ linux-2.6.20.3/include/linux/skbuff.h       2007-03-23 08:10:06.000000000 -0400
26884 @@ -373,7 +373,7 @@ extern void       skb_truesize_bug(struc
26885  
26886  static inline void skb_truesize_check(struct sk_buff *skb)
26887  {
26888 -       if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
26889 +       if (unlikely(skb->truesize < sizeof(struct sk_buff) + skb->len))
26890                 skb_truesize_bug(skb);
26891  }
26892  
26893 diff -urNp linux-2.6.20.3/include/linux/sysctl.h linux-2.6.20.3/include/linux/sysctl.h
26894 --- linux-2.6.20.3/include/linux/sysctl.h       2007-03-13 14:27:08.000000000 -0400
26895 +++ linux-2.6.20.3/include/linux/sysctl.h       2007-03-23 08:29:10.000000000 -0400
26896 @@ -160,9 +160,21 @@ enum
26897         KERN_MAX_LOCK_DEPTH=74,
26898         KERN_NMI_WATCHDOG=75, /* int: enable/disable nmi watchdog */
26899         KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
26900 -};
26901 +#ifdef CONFIG_GRKERNSEC
26902 +       KERN_GRSECURITY=98,     /* grsecurity */
26903 +#endif
26904 +
26905 +#ifdef CONFIG_PAX_SOFTMODE
26906 +       KERN_PAX=99,            /* PaX control */
26907 +#endif
26908  
26909 +};
26910  
26911 +#ifdef CONFIG_PAX_SOFTMODE
26912 +enum {
26913 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
26914 +};
26915 +#endif
26916  
26917  /* CTL_VM names: */
26918  enum
26919 diff -urNp linux-2.6.20.3/include/linux/uaccess.h linux-2.6.20.3/include/linux/uaccess.h
26920 --- linux-2.6.20.3/include/linux/uaccess.h      2007-03-13 14:27:08.000000000 -0400
26921 +++ linux-2.6.20.3/include/linux/uaccess.h      2007-03-23 08:10:06.000000000 -0400
26922 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
26923                 long ret;                               \
26924                 mm_segment_t old_fs = get_fs();         \
26925                                                         \
26926 -               set_fs(KERNEL_DS);                      \
26927                 pagefault_disable();                    \
26928 +               set_fs(KERNEL_DS);                      \
26929                 ret = __get_user(retval, (__force typeof(retval) __user *)(addr));              \
26930 -               pagefault_enable();                     \
26931                 set_fs(old_fs);                         \
26932 +               pagefault_enable();                     \
26933                 ret;                                    \
26934         })
26935  
26936 diff -urNp linux-2.6.20.3/include/linux/udf_fs.h linux-2.6.20.3/include/linux/udf_fs.h
26937 --- linux-2.6.20.3/include/linux/udf_fs.h       2007-03-13 14:27:08.000000000 -0400
26938 +++ linux-2.6.20.3/include/linux/udf_fs.h       2007-03-23 08:10:06.000000000 -0400
26939 @@ -45,7 +45,7 @@
26940                 printk (f, ##a); \
26941         }
26942  #else
26943 -#define udf_debug(f, a...) /**/
26944 +#define udf_debug(f, a...) do {} while (0)
26945  #endif
26946  
26947  #define udf_info(f, a...) \
26948 diff -urNp linux-2.6.20.3/include/net/sctp/sctp.h linux-2.6.20.3/include/net/sctp/sctp.h
26949 --- linux-2.6.20.3/include/net/sctp/sctp.h      2007-03-13 14:27:08.000000000 -0400
26950 +++ linux-2.6.20.3/include/net/sctp/sctp.h      2007-03-23 08:10:06.000000000 -0400
26951 @@ -306,8 +306,8 @@ extern int sctp_debug_flag;
26952  
26953  #else  /* SCTP_DEBUG */
26954  
26955 -#define SCTP_DEBUG_PRINTK(whatever...)
26956 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
26957 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
26958 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
26959  #define SCTP_ENABLE_DEBUG
26960  #define SCTP_DISABLE_DEBUG
26961  #define SCTP_ASSERT(expr, str, func)
26962 diff -urNp linux-2.6.20.3/include/sound/core.h linux-2.6.20.3/include/sound/core.h
26963 --- linux-2.6.20.3/include/sound/core.h 2007-03-13 14:27:08.000000000 -0400
26964 +++ linux-2.6.20.3/include/sound/core.h 2007-03-23 08:10:06.000000000 -0400
26965 @@ -365,9 +365,9 @@ void snd_verbose_printd(const char *file
26966  
26967  #else /* !CONFIG_SND_DEBUG */
26968  
26969 -#define snd_printd(fmt, args...)       /* nothing */
26970 +#define snd_printd(fmt, args...)       do {} while (0)
26971  #define snd_assert(expr, args...)      (void)(expr)
26972 -#define snd_BUG()                      /* nothing */
26973 +#define snd_BUG()                      do {} while (0)
26974  
26975  #endif /* CONFIG_SND_DEBUG */
26976  
26977 diff -urNp linux-2.6.20.3/init/do_mounts.c linux-2.6.20.3/init/do_mounts.c
26978 --- linux-2.6.20.3/init/do_mounts.c     2007-03-13 14:27:08.000000000 -0400
26979 +++ linux-2.6.20.3/init/do_mounts.c     2007-03-23 08:10:06.000000000 -0400
26980 @@ -65,11 +65,12 @@ static dev_t try_name(char *name, int pa
26981  
26982         /* read device number from .../dev */
26983  
26984 -       sprintf(path, "/sys/block/%s/dev", name);
26985 -       fd = sys_open(path, 0, 0);
26986 +       if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/dev", name))
26987 +               goto fail;
26988 +       fd = sys_open((char __user *)path, 0, 0);
26989         if (fd < 0)
26990                 goto fail;
26991 -       len = sys_read(fd, buf, 32);
26992 +       len = sys_read(fd, (char __user *)buf, 32);
26993         sys_close(fd);
26994         if (len <= 0 || len == 32 || buf[len - 1] != '\n')
26995                 goto fail;
26996 @@ -95,11 +96,12 @@ static dev_t try_name(char *name, int pa
26997                 return res;
26998  
26999         /* otherwise read range from .../range */
27000 -       sprintf(path, "/sys/block/%s/range", name);
27001 -       fd = sys_open(path, 0, 0);
27002 +       if (sizeof path <= snprintf(path, sizeof path, "/sys/block/%s/range", name))
27003 +               goto fail;
27004 +       fd = sys_open((char __user *)path, 0, 0);
27005         if (fd < 0)
27006                 goto fail;
27007 -       len = sys_read(fd, buf, 32);
27008 +       len = sys_read(fd, (char __user *)buf, 32);
27009         sys_close(fd);
27010         if (len <= 0 || len == 32 || buf[len - 1] != '\n')
27011                 goto fail;
27012 @@ -268,11 +270,11 @@ static void __init get_fs_names(char *pa
27013  
27014  static int __init do_mount_root(char *name, char *fs, int flags, void *data)
27015  {
27016 -       int err = sys_mount(name, "/root", fs, flags, data);
27017 +       int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
27018         if (err)
27019                 return err;
27020  
27021 -       sys_chdir("/root");
27022 +       sys_chdir((char __user *)"/root");
27023         ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
27024         printk("VFS: Mounted root (%s filesystem)%s.\n",
27025                current->fs->pwdmnt->mnt_sb->s_type->name,
27026 @@ -354,18 +356,18 @@ void __init change_floppy(char *fmt, ...
27027         va_start(args, fmt);
27028         vsprintf(buf, fmt, args);
27029         va_end(args);
27030 -       fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
27031 +       fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
27032         if (fd >= 0) {
27033                 sys_ioctl(fd, FDEJECT, 0);
27034                 sys_close(fd);
27035         }
27036         printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
27037 -       fd = sys_open("/dev/console", O_RDWR, 0);
27038 +       fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
27039         if (fd >= 0) {
27040                 sys_ioctl(fd, TCGETS, (long)&termios);
27041                 termios.c_lflag &= ~ICANON;
27042                 sys_ioctl(fd, TCSETSF, (long)&termios);
27043 -               sys_read(fd, &c, 1);
27044 +               sys_read(fd, (char __user *)&c, 1);
27045                 termios.c_lflag |= ICANON;
27046                 sys_ioctl(fd, TCSETSF, (long)&termios);
27047                 sys_close(fd);
27048 @@ -442,8 +444,8 @@ void __init prepare_namespace(void)
27049  
27050         mount_root();
27051  out:
27052 -       sys_mount(".", "/", NULL, MS_MOVE, NULL);
27053 -       sys_chroot(".");
27054 +       sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
27055 +       sys_chroot((char __user *)".");
27056         security_sb_post_mountroot();
27057  }
27058  
27059 diff -urNp linux-2.6.20.3/init/do_mounts.h linux-2.6.20.3/init/do_mounts.h
27060 --- linux-2.6.20.3/init/do_mounts.h     2007-03-13 14:27:08.000000000 -0400
27061 +++ linux-2.6.20.3/init/do_mounts.h     2007-03-23 08:10:06.000000000 -0400
27062 @@ -15,15 +15,15 @@ extern char *root_device_name;
27063  
27064  static inline int create_dev(char *name, dev_t dev)
27065  {
27066 -       sys_unlink(name);
27067 -       return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
27068 +       sys_unlink((char __user *)name);
27069 +       return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
27070  }
27071  
27072  #if BITS_PER_LONG == 32
27073  static inline u32 bstat(char *name)
27074  {
27075         struct stat64 stat;
27076 -       if (sys_stat64(name, &stat) != 0)
27077 +       if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
27078                 return 0;
27079         if (!S_ISBLK(stat.st_mode))
27080                 return 0;
27081 diff -urNp linux-2.6.20.3/init/do_mounts_md.c linux-2.6.20.3/init/do_mounts_md.c
27082 --- linux-2.6.20.3/init/do_mounts_md.c  2007-03-13 14:27:08.000000000 -0400
27083 +++ linux-2.6.20.3/init/do_mounts_md.c  2007-03-23 08:10:06.000000000 -0400
27084 @@ -167,7 +167,7 @@ static void __init md_setup_drive(void)
27085                         partitioned ? "_d" : "", minor,
27086                         md_setup_args[ent].device_names);
27087  
27088 -               fd = sys_open(name, 0, 0);
27089 +               fd = sys_open((char __user *)name, 0, 0);
27090                 if (fd < 0) {
27091                         printk(KERN_ERR "md: open failed - cannot start "
27092                                         "array %s\n", name);
27093 @@ -230,7 +230,7 @@ static void __init md_setup_drive(void)
27094                          * array without it
27095                          */
27096                         sys_close(fd);
27097 -                       fd = sys_open(name, 0, 0);
27098 +                       fd = sys_open((char __user *)name, 0, 0);
27099                         sys_ioctl(fd, BLKRRPART, 0);
27100                 }
27101                 sys_close(fd);
27102 @@ -271,7 +271,7 @@ void __init md_run_setup(void)
27103         if (raid_noautodetect)
27104                 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
27105         else {
27106 -               int fd = sys_open("/dev/md0", 0, 0);
27107 +               int fd = sys_open((char __user *)"/dev/md0", 0, 0);
27108                 if (fd >= 0) {
27109                         sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
27110                         sys_close(fd);
27111 diff -urNp linux-2.6.20.3/init/initramfs.c linux-2.6.20.3/init/initramfs.c
27112 --- linux-2.6.20.3/init/initramfs.c     2007-03-13 14:27:08.000000000 -0400
27113 +++ linux-2.6.20.3/init/initramfs.c     2007-03-23 08:10:06.000000000 -0400
27114 @@ -240,7 +240,7 @@ static int __init maybe_link(void)
27115         if (nlink >= 2) {
27116                 char *old = find_link(major, minor, ino, mode, collected);
27117                 if (old)
27118 -                       return (sys_link(old, collected) < 0) ? -1 : 1;
27119 +                       return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
27120         }
27121         return 0;
27122  }
27123 @@ -249,11 +249,11 @@ static void __init clean_path(char *path
27124  {
27125         struct stat st;
27126  
27127 -       if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
27128 +       if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
27129                 if (S_ISDIR(st.st_mode))
27130 -                       sys_rmdir(path);
27131 +                       sys_rmdir((char __user *)path);
27132                 else
27133 -                       sys_unlink(path);
27134 +                       sys_unlink((char __user *)path);
27135         }
27136  }
27137  
27138 @@ -276,7 +276,7 @@ static int __init do_name(void)
27139                         int openflags = O_WRONLY|O_CREAT;
27140                         if (ml != 1)
27141                                 openflags |= O_TRUNC;
27142 -                       wfd = sys_open(collected, openflags, mode);
27143 +                       wfd = sys_open((char __user *)collected, openflags, mode);
27144  
27145                         if (wfd >= 0) {
27146                                 sys_fchown(wfd, uid, gid);
27147 @@ -285,15 +285,15 @@ static int __init do_name(void)
27148                         }
27149                 }
27150         } else if (S_ISDIR(mode)) {
27151 -               sys_mkdir(collected, mode);
27152 -               sys_chown(collected, uid, gid);
27153 -               sys_chmod(collected, mode);
27154 +               sys_mkdir((char __user *)collected, mode);
27155 +               sys_chown((char __user *)collected, uid, gid);
27156 +               sys_chmod((char __user *)collected, mode);
27157         } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
27158                    S_ISFIFO(mode) || S_ISSOCK(mode)) {
27159                 if (maybe_link() == 0) {
27160 -                       sys_mknod(collected, mode, rdev);
27161 -                       sys_chown(collected, uid, gid);
27162 -                       sys_chmod(collected, mode);
27163 +                       sys_mknod((char __user *)collected, mode, rdev);
27164 +                       sys_chown((char __user *)collected, uid, gid);
27165 +                       sys_chmod((char __user *)collected, mode);
27166                 }
27167         }
27168         return 0;
27169 @@ -302,13 +302,13 @@ static int __init do_name(void)
27170  static int __init do_copy(void)
27171  {
27172         if (count >= body_len) {
27173 -               sys_write(wfd, victim, body_len);
27174 +               sys_write(wfd, (char __user *)victim, body_len);
27175                 sys_close(wfd);
27176                 eat(body_len);
27177                 state = SkipIt;
27178                 return 0;
27179         } else {
27180 -               sys_write(wfd, victim, count);
27181 +               sys_write(wfd, (char __user *)victim, count);
27182                 body_len -= count;
27183                 eat(count);
27184                 return 1;
27185 @@ -319,8 +319,8 @@ static int __init do_symlink(void)
27186  {
27187         collected[N_ALIGN(name_len) + body_len] = '\0';
27188         clean_path(collected, 0);
27189 -       sys_symlink(collected + N_ALIGN(name_len), collected);
27190 -       sys_lchown(collected, uid, gid);
27191 +       sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
27192 +       sys_lchown((char __user *)collected, uid, gid);
27193         state = SkipIt;
27194         next_state = Reset;
27195         return 0;
27196 diff -urNp linux-2.6.20.3/init/Kconfig linux-2.6.20.3/init/Kconfig
27197 --- linux-2.6.20.3/init/Kconfig 2007-03-13 14:27:08.000000000 -0400
27198 +++ linux-2.6.20.3/init/Kconfig 2007-03-23 08:11:31.000000000 -0400
27199 @@ -350,6 +350,7 @@ config SYSCTL_SYSCALL
27200  config KALLSYMS
27201          bool "Load all symbols for debugging/ksymoops" if EMBEDDED
27202          default y
27203 +        depends on !GRKERNSEC_HIDESYM
27204          help
27205            Say Y here to let the kernel print out symbolic crash information and
27206            symbolic stack backtraces. This increases the size of the kernel
27207 diff -urNp linux-2.6.20.3/init/main.c linux-2.6.20.3/init/main.c
27208 --- linux-2.6.20.3/init/main.c  2007-03-13 14:27:08.000000000 -0400
27209 +++ linux-2.6.20.3/init/main.c  2007-03-23 08:11:31.000000000 -0400
27210 @@ -106,6 +106,7 @@ static inline void mark_rodata_ro(void) 
27211  #ifdef CONFIG_TC
27212  extern void tc_init(void);
27213  #endif
27214 +extern void grsecurity_init(void);
27215  
27216  enum system_states system_state;
27217  EXPORT_SYMBOL(system_state);
27218 @@ -176,6 +177,15 @@ static int __init set_reset_devices(char
27219  
27220  __setup("reset_devices", set_reset_devices);
27221  
27222 +#ifdef CONFIG_PAX_SOFTMODE
27223 +static int __init setup_pax_softmode(char *str)
27224 +{
27225 +       get_option(&str, &pax_softmode);
27226 +       return 1;
27227 +}
27228 +__setup("pax_softmode=", setup_pax_softmode);
27229 +#endif
27230 +
27231  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
27232  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
27233  static const char *panic_later, *panic_param;
27234 @@ -756,6 +766,8 @@ static int init(void * unused)
27235                 prepare_namespace();
27236         }
27237  
27238 +       grsecurity_init();
27239 +
27240         /*
27241          * Ok, we have completed the initial bootup, and
27242          * we're essentially up and running. Get rid of the
27243 diff -urNp linux-2.6.20.3/ipc/msg.c linux-2.6.20.3/ipc/msg.c
27244 --- linux-2.6.20.3/ipc/msg.c    2007-03-13 14:27:08.000000000 -0400
27245 +++ linux-2.6.20.3/ipc/msg.c    2007-03-23 08:11:31.000000000 -0400
27246 @@ -37,6 +37,7 @@
27247  #include <linux/mutex.h>
27248  #include <linux/nsproxy.h>
27249  #include <linux/vs_base.h>
27250 +#include <linux/grsecurity.h>
27251  
27252  #include <asm/current.h>
27253  #include <asm/uaccess.h>
27254 @@ -288,6 +289,8 @@ asmlinkage long sys_msgget(key_t key, in
27255         }
27256         mutex_unlock(&msg_ids(ns).mutex);
27257  
27258 +       gr_log_msgget(ret, msgflg);
27259 +
27260         return ret;
27261  }
27262  
27263 @@ -554,6 +557,7 @@ asmlinkage long sys_msgctl(int msqid, in
27264                 break;
27265         }
27266         case IPC_RMID:
27267 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
27268                 freeque(ns, msq, msqid);
27269                 break;
27270         }
27271 diff -urNp linux-2.6.20.3/ipc/sem.c linux-2.6.20.3/ipc/sem.c
27272 --- linux-2.6.20.3/ipc/sem.c    2007-03-13 14:27:08.000000000 -0400
27273 +++ linux-2.6.20.3/ipc/sem.c    2007-03-23 08:11:31.000000000 -0400
27274 @@ -83,6 +83,7 @@
27275  #include <linux/nsproxy.h>
27276  #include <linux/vs_base.h>
27277  #include <linux/vs_limit.h>
27278 +#include <linux/grsecurity.h>
27279  
27280  #include <asm/uaccess.h>
27281  #include "util.h"
27282 @@ -296,6 +297,9 @@ asmlinkage long sys_semget (key_t key, i
27283         }
27284  
27285         mutex_unlock(&sem_ids(ns).mutex);
27286 +
27287 +       gr_log_semget(err, semflg);
27288 +
27289         return err;
27290  }
27291  
27292 @@ -897,6 +901,7 @@ static int semctl_down(struct ipc_namesp
27293  
27294         switch(cmd){
27295         case IPC_RMID:
27296 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
27297                 freeary(ns, sma, semid);
27298                 err = 0;
27299                 break;
27300 diff -urNp linux-2.6.20.3/ipc/shm.c linux-2.6.20.3/ipc/shm.c
27301 --- linux-2.6.20.3/ipc/shm.c    2007-03-13 14:27:08.000000000 -0400
27302 +++ linux-2.6.20.3/ipc/shm.c    2007-03-23 08:11:31.000000000 -0400
27303 @@ -39,6 +39,7 @@
27304  #include <linux/nsproxy.h>
27305  #include <linux/vs_context.h>
27306  #include <linux/vs_limit.h>
27307 +#include <linux/grsecurity.h>
27308  
27309  #include <asm/uaccess.h>
27310  
27311 @@ -67,6 +68,14 @@ static void shm_destroy (struct ipc_name
27312  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
27313  #endif
27314  
27315 +#ifdef CONFIG_GRKERNSEC
27316 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
27317 +                          const time_t shm_createtime, const uid_t cuid,
27318 +                          const int shmid);
27319 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
27320 +                          const time_t shm_createtime);
27321 +#endif
27322 +
27323  static void __ipc_init __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids)
27324  {
27325         ns->ids[IPC_SHM_IDS] = ids;
27326 @@ -79,6 +88,8 @@ static void __ipc_init __shm_init_ns(str
27327  
27328  static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp)
27329  {
27330 +       gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
27331 +
27332         if (shp->shm_nattch){
27333                 shp->shm_perm.mode |= SHM_DEST;
27334                 /* Do not find it any more */
27335 @@ -216,6 +227,17 @@ static void shm_close (struct vm_area_st
27336         shp->shm_lprid = current->tgid;
27337         shp->shm_dtim = get_seconds();
27338         shp->shm_nattch--;
27339 +#ifdef CONFIG_GRKERNSEC_SHM
27340 +       if (grsec_enable_shm) {
27341 +               if (shp->shm_nattch == 0) {
27342 +                       shp->shm_perm.mode |= SHM_DEST;
27343 +                       shm_destroy(ns, shp);
27344 +               } else
27345 +                       shm_unlock(shp);
27346 +               mutex_unlock(&shm_ids(ns).mutex);
27347 +               return;
27348 +       }
27349 +#endif
27350         if(shp->shm_nattch == 0 &&
27351            shp->shm_perm.mode & SHM_DEST)
27352                 shm_destroy(ns, shp);
27353 @@ -326,6 +348,9 @@ static int newseg (struct ipc_namespace 
27354         shp->shm_lprid = 0;
27355         shp->shm_atim = shp->shm_dtim = 0;
27356         shp->shm_ctim = get_seconds();
27357 +#ifdef CONFIG_GRKERNSEC
27358 +       shp->shm_createtime = get_seconds();
27359 +#endif
27360         shp->shm_segsz = size;
27361         shp->shm_nattch = 0;
27362         shp->id = shm_buildid(ns, id, shp->shm_perm.seq);
27363 @@ -385,6 +410,8 @@ asmlinkage long sys_shmget (key_t key, s
27364         }
27365         mutex_unlock(&shm_ids(ns).mutex);
27366  
27367 +       gr_log_shmget(err, shmflg, size);
27368 +
27369         return err;
27370  }
27371  
27372 @@ -842,9 +869,23 @@ long do_shmat(int shmid, char __user *sh
27373                 return err;
27374         }
27375                 
27376 +#ifdef CONFIG_GRKERNSEC
27377 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
27378 +                            shp->shm_perm.cuid, shmid) ||
27379 +           !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
27380 +               shm_unlock(shp);
27381 +               return -EACCES;
27382 +       }
27383 +#endif
27384 +
27385         file = shp->shm_file;
27386         size = i_size_read(file->f_path.dentry->d_inode);
27387         shp->shm_nattch++;
27388 +
27389 +#ifdef CONFIG_GRKERNSEC
27390 +       shp->shm_lapid = current->pid;
27391 +#endif
27392 +
27393         shm_unlock(shp);
27394  
27395         down_write(&current->mm->mmap_sem);
27396 @@ -1014,3 +1055,27 @@ static int sysvipc_shm_proc_show(struct 
27397                           shp->shm_ctim);
27398  }
27399  #endif
27400 +
27401 +void gr_shm_exit(struct task_struct *task)
27402 +{
27403 +#ifdef CONFIG_GRKERNSEC_SHM
27404 +       int i;
27405 +       struct shmid_kernel *shp;
27406 +       struct ipc_namespace *ns;
27407 +
27408 +       ns = current->nsproxy->ipc_ns;
27409 +
27410 +       if (!grsec_enable_shm)
27411 +               return;
27412 +
27413 +       for (i = 0; i <= shm_ids(ns).max_id; i++) {
27414 +               shp = shm_get(ns, i);
27415 +               if (shp && (shp->shm_cprid == task->pid) &&
27416 +                   (shp->shm_nattch <= 0)) {
27417 +                       shp->shm_perm.mode |= SHM_DEST;
27418 +                       shm_destroy(ns, shp);
27419 +               }
27420 +       }
27421 +#endif
27422 +       return;
27423 +}
27424 diff -urNp linux-2.6.20.3/kernel/acct.c linux-2.6.20.3/kernel/acct.c
27425 --- linux-2.6.20.3/kernel/acct.c        2007-03-13 14:27:08.000000000 -0400
27426 +++ linux-2.6.20.3/kernel/acct.c        2007-03-23 08:10:06.000000000 -0400
27427 @@ -511,7 +511,7 @@ static void do_acct_process(struct file 
27428          */
27429         flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
27430         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
27431 -       file->f_op->write(file, (char *)&ac,
27432 +       file->f_op->write(file, (char __user *)&ac,
27433                                sizeof(acct_t), &file->f_pos);
27434         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
27435         set_fs(fs);
27436 diff -urNp linux-2.6.20.3/kernel/capability.c linux-2.6.20.3/kernel/capability.c
27437 --- linux-2.6.20.3/kernel/capability.c  2007-03-13 14:27:08.000000000 -0400
27438 +++ linux-2.6.20.3/kernel/capability.c  2007-03-23 08:11:31.000000000 -0400
27439 @@ -13,6 +13,7 @@
27440  #include <linux/security.h>
27441  #include <linux/syscalls.h>
27442  #include <linux/vs_context.h>
27443 +#include <linux/grsecurity.h>
27444  #include <asm/uaccess.h>
27445  
27446  unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
27447 @@ -237,14 +238,25 @@ out:
27448       return ret;
27449  }
27450  
27451 +extern int gr_task_is_capable(struct task_struct *task, const int cap);
27452 +extern int gr_is_capable_nolog(const int cap);
27453 +
27454  int __capable(struct task_struct *t, int cap)
27455  {
27456 -       if (security_capable(t, cap) == 0) {
27457 +       if ((security_capable(t, cap) == 0) && gr_task_is_capable(t, cap)) {
27458                 t->flags |= PF_SUPERPRIV;
27459                 return 1;
27460         }
27461         return 0;
27462  }
27463 +int capable_nolog(int cap)
27464 +{
27465 +       if ((security_capable(current, cap) == 0) && gr_is_capable_nolog(cap)) {
27466 +               current->flags |= PF_SUPERPRIV;
27467 +               return 1;
27468 +       }
27469 +       return 0;
27470 +}
27471  EXPORT_SYMBOL(__capable);
27472  
27473  #include <linux/vserver/base.h>
27474 @@ -249,3 +261,4 @@ int capable(int cap)
27475         return __capable(current, cap);
27476  }
27477  EXPORT_SYMBOL(capable);
27478 +EXPORT_SYMBOL(capable_nolog);
27479 diff -urNp linux-2.6.20.3/kernel/configs.c linux-2.6.20.3/kernel/configs.c
27480 --- linux-2.6.20.3/kernel/configs.c     2007-03-13 14:27:08.000000000 -0400
27481 +++ linux-2.6.20.3/kernel/configs.c     2007-03-23 08:11:31.000000000 -0400
27482 @@ -88,8 +88,16 @@ static int __init ikconfig_init(void)
27483         struct proc_dir_entry *entry;
27484  
27485         /* create the current config file */
27486 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
27487 +#ifdef CONFIG_GRKERNSEC_PROC_USER
27488 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR, &proc_root);
27489 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
27490 +       entry = create_proc_entry("config.gz", S_IFREG | S_IRUSR | S_IRGRP, &proc_root);
27491 +#endif
27492 +#else
27493         entry = create_proc_entry("config.gz", S_IFREG | S_IRUGO,
27494                                   &proc_root);
27495 +#endif
27496         if (!entry)
27497                 return -ENOMEM;
27498  
27499 diff -urNp linux-2.6.20.3/kernel/exit.c linux-2.6.20.3/kernel/exit.c
27500 --- linux-2.6.20.3/kernel/exit.c        2007-03-13 14:27:08.000000000 -0400
27501 +++ linux-2.6.20.3/kernel/exit.c        2007-03-23 08:11:31.000000000 -0400
27502 @@ -47,6 +47,11 @@
27503  #include <linux/vs_network.h>
27504  #include <linux/vs_pid.h>
27505  #include <linux/vserver/global.h>
27506 +#include <linux/grsecurity.h>
27507 +
27508 +#ifdef CONFIG_GRKERNSEC
27509 +extern rwlock_t grsec_exec_file_lock;
27510 +#endif
27511  
27512  #include <asm/uaccess.h>
27513  #include <asm/unistd.h>
27514 @@ -118,6 +123,7 @@ static void __exit_signal(struct task_st
27515  
27516         __unhash_process(tsk);
27517  
27518 +       gr_del_task_from_ip_table(tsk);
27519         tsk->signal = NULL;
27520         tsk->sighand = NULL;
27521         spin_unlock(&sighand->siglock);
27522 @@ -273,6 +279,15 @@ static void reparent_to_init(void)
27523  {
27524         write_lock_irq(&tasklist_lock);
27525  
27526 +#ifdef CONFIG_GRKERNSEC
27527 +       write_lock(&grsec_exec_file_lock);
27528 +       if (current->exec_file) {
27529 +               fput(current->exec_file);
27530 +               current->exec_file = NULL;
27531 +       }
27532 +       write_unlock(&grsec_exec_file_lock);
27533 +#endif
27534 +
27535         ptrace_unlink(current);
27536         /* Reparent to init */
27537         remove_parent(current);
27538 @@ -280,6 +295,8 @@ static void reparent_to_init(void)
27539         current->real_parent = child_reaper(current);
27540         add_parent(current);
27541  
27542 +       gr_set_kernel_label(current);
27543 +
27544         /* Set the exit signal to SIGCHLD so we signal init on exit */
27545         current->exit_signal = SIGCHLD;
27546  
27547 @@ -374,6 +391,17 @@ void daemonize(const char *name, ...)
27548         vsnprintf(current->comm, sizeof(current->comm), name, args);
27549         va_end(args);
27550  
27551 +#ifdef CONFIG_GRKERNSEC
27552 +       write_lock(&grsec_exec_file_lock);
27553 +       if (current->exec_file) {
27554 +               fput(current->exec_file);
27555 +               current->exec_file = NULL;
27556 +       }
27557 +       write_unlock(&grsec_exec_file_lock);
27558 +#endif
27559 +
27560 +       gr_set_kernel_label(current);
27561 +
27562         /*
27563          * If we were started as result of loading a module, close all of the
27564          * user space pages.  We don't need them, and if we didn't close them
27565 @@ -918,11 +946,15 @@ fastcall NORET_TYPE void do_exit(long co
27566  
27567         taskstats_exit(tsk, group_dead);
27568  
27569 +       gr_acl_handle_psacct(tsk, code);
27570 +       gr_acl_handle_exit();
27571 +
27572         exit_mm(tsk);
27573  
27574         if (group_dead)
27575                 acct_process();
27576         exit_sem(tsk);
27577 +       gr_shm_exit(tsk);
27578         __exit_files(tsk);
27579         __exit_fs(tsk);
27580         exit_thread();
27581 diff -urNp linux-2.6.20.3/kernel/fork.c linux-2.6.20.3/kernel/fork.c
27582 --- linux-2.6.20.3/kernel/fork.c        2007-03-13 14:27:08.000000000 -0400
27583 +++ linux-2.6.20.3/kernel/fork.c        2007-03-23 08:11:31.000000000 -0400
27584 @@ -49,6 +49,7 @@
27585  #include <linux/vs_limit.h>
27586  #include <linux/vs_memory.h>
27587  #include <linux/vserver/global.h>
27588 +#include <linux/grsecurity.h>
27589  
27590  #include <asm/pgtable.h>
27591  #include <asm/pgalloc.h>
27592 @@ -180,7 +181,7 @@ static struct task_struct *dup_task_stru
27593         setup_thread_stack(tsk, orig);
27594  
27595  #ifdef CONFIG_CC_STACKPROTECTOR
27596 -       tsk->stack_canary = get_random_int();
27597 +       tsk->stack_canary = pax_get_random_long();
27598  #endif
27599  
27600         /* One for us, one for whoever does the "release_task()" (usually parent) */
27601 @@ -212,8 +213,8 @@ static inline int dup_mmap(struct mm_str
27602         mm->locked_vm = 0;
27603         mm->mmap = NULL;
27604         mm->mmap_cache = NULL;
27605 -       mm->free_area_cache = oldmm->mmap_base;
27606 -       mm->cached_hole_size = ~0UL;
27607 +       mm->free_area_cache = oldmm->free_area_cache;
27608 +       mm->cached_hole_size = oldmm->cached_hole_size;
27609         mm->map_count = 0;
27610         __set_mm_counter(mm, file_rss, 0);
27611         __set_mm_counter(mm, anon_rss, 0);
27612 @@ -338,7 +339,7 @@ static struct mm_struct * mm_init(struct
27613         spin_lock_init(&mm->page_table_lock);
27614         rwlock_init(&mm->ioctx_list_lock);
27615         mm->ioctx_list = NULL;
27616 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
27617 +       mm->free_area_cache = ~0UL;
27618         mm->cached_hole_size = ~0UL;
27619  
27620         if (likely(!mm_alloc_pgd(mm))) {
27621 @@ -993,6 +994,9 @@ static struct task_struct *copy_process(
27622         }
27623  
27624         retval = -EAGAIN;
27625 +
27626 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
27627 +
27628         if (!vx_nproc_avail(1))
27629                 goto bad_fork_cleanup_vm;
27630  
27631 @@ -1126,6 +1130,8 @@ static struct task_struct *copy_process(
27632         if (retval)
27633                 goto bad_fork_cleanup_namespaces;
27634  
27635 +       gr_copy_label(p);
27636 +
27637         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
27638         /*
27639          * Clear TID on mm_release()?
27640 @@ -1304,6 +1310,8 @@ bad_fork_cleanup_count:
27641  bad_fork_free:
27642         free_task(p);
27643  fork_out:
27644 +       gr_log_forkfail(retval);
27645 +
27646         return ERR_PTR(retval);
27647  }
27648  
27649 @@ -1376,6 +1384,8 @@ long do_fork(unsigned long clone_flags,
27650         if (!IS_ERR(p)) {
27651                 struct completion vfork;
27652  
27653 +               gr_handle_brute_check();
27654 +
27655                 if (clone_flags & CLONE_VFORK) {
27656                         p->vfork_done = &vfork;
27657                         init_completion(&vfork);
27658 diff -urNp linux-2.6.20.3/kernel/futex.c linux-2.6.20.3/kernel/futex.c
27659 --- linux-2.6.20.3/kernel/futex.c       2007-03-13 14:27:08.000000000 -0400
27660 +++ linux-2.6.20.3/kernel/futex.c       2007-03-23 08:10:06.000000000 -0400
27661 @@ -183,6 +183,11 @@ static int get_futex_key(u32 __user *uad
27662         struct page *page;
27663         int err;
27664  
27665 +#ifdef CONFIG_PAX_SEGMEXEC
27666 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((unsigned long)uaddr >= SEGMEXEC_TASK_SIZE))
27667 +               return -EFAULT;
27668 +#endif
27669 +
27670         /*
27671          * The futex address must be "naturally" aligned.
27672          */
27673 @@ -195,8 +200,8 @@ static int get_futex_key(u32 __user *uad
27674          * The futex is hashed differently depending on whether
27675          * it's in a shared or private mapping.  So check vma first.
27676          */
27677 -       vma = find_extend_vma(mm, address);
27678 -       if (unlikely(!vma))
27679 +       vma = find_vma(mm, address);
27680 +       if (unlikely(!vma || address < vma->vm_start))
27681                 return -EFAULT;
27682  
27683         /*
27684 diff -urNp linux-2.6.20.3/kernel/irq/handle.c linux-2.6.20.3/kernel/irq/handle.c
27685 --- linux-2.6.20.3/kernel/irq/handle.c  2007-03-13 14:27:08.000000000 -0400
27686 +++ linux-2.6.20.3/kernel/irq/handle.c  2007-03-23 08:10:06.000000000 -0400
27687 @@ -56,7 +56,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
27688                 .depth = 1,
27689                 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
27690  #ifdef CONFIG_SMP
27691 -               .affinity = CPU_MASK_ALL
27692 +               .affinity = CPU_MASK_ALL,
27693 +               .cpu = 0,
27694  #endif
27695         }
27696  };
27697 diff -urNp linux-2.6.20.3/kernel/kallsyms.c linux-2.6.20.3/kernel/kallsyms.c
27698 --- linux-2.6.20.3/kernel/kallsyms.c    2007-03-13 14:27:08.000000000 -0400
27699 +++ linux-2.6.20.3/kernel/kallsyms.c    2007-03-23 08:11:31.000000000 -0400
27700 @@ -72,8 +72,8 @@ static inline int is_kernel(unsigned lon
27701  
27702  static int is_ksym_addr(unsigned long addr)
27703  {
27704 -       if (all_var)
27705 -               return is_kernel(addr);
27706 +       if (all_var && is_kernel(addr))
27707 +               return 1;
27708  
27709         return is_kernel_text(addr) || is_kernel_inittext(addr) ||
27710                 is_kernel_extratext(addr);
27711 @@ -334,7 +334,6 @@ static unsigned long get_ksymbol_core(st
27712  
27713  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
27714  {
27715 -       iter->name[0] = '\0';
27716         iter->nameoff = get_symbol_offset(new_pos);
27717         iter->pos = new_pos;
27718  }
27719 @@ -413,7 +412,7 @@ static int kallsyms_open(struct inode *i
27720         struct kallsym_iter *iter;
27721         int ret;
27722  
27723 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
27724 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
27725         if (!iter)
27726                 return -ENOMEM;
27727         reset_iter(iter, 0);
27728 @@ -444,7 +443,15 @@ static int __init kallsyms_init(void)
27729  {
27730         struct proc_dir_entry *entry;
27731  
27732 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
27733 +#ifdef CONFIG_GRKERNSEC_PROC_USER
27734 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR, NULL);
27735 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
27736 +       entry = create_proc_entry("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL);
27737 +#endif
27738 +#else
27739         entry = create_proc_entry("kallsyms", 0444, NULL);
27740 +#endif
27741         if (entry)
27742                 entry->proc_fops = &kallsyms_operations;
27743         return 0;
27744 diff -urNp linux-2.6.20.3/kernel/kprobes.c linux-2.6.20.3/kernel/kprobes.c
27745 --- linux-2.6.20.3/kernel/kprobes.c     2007-03-13 14:27:08.000000000 -0400
27746 +++ linux-2.6.20.3/kernel/kprobes.c     2007-03-23 08:10:06.000000000 -0400
27747 @@ -162,7 +162,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
27748          * kernel image and loaded module images reside. This is required
27749          * so x86_64 can correctly handle the %rip-relative fixups.
27750          */
27751 -       kip->insns = module_alloc(PAGE_SIZE);
27752 +       kip->insns = module_alloc_exec(PAGE_SIZE);
27753         if (!kip->insns) {
27754                 kfree(kip);
27755                 return NULL;
27756 diff -urNp linux-2.6.20.3/kernel/module.c linux-2.6.20.3/kernel/module.c
27757 --- linux-2.6.20.3/kernel/module.c      2007-03-13 14:27:08.000000000 -0400
27758 +++ linux-2.6.20.3/kernel/module.c      2007-03-23 08:11:31.000000000 -0400
27759 @@ -43,6 +43,11 @@
27760  #include <asm/uaccess.h>
27761  #include <asm/semaphore.h>
27762  #include <asm/cacheflush.h>
27763 +
27764 +#ifdef CONFIG_PAX_KERNEXEC
27765 +#include <asm/desc.h>
27766 +#endif
27767 +
27768  #include <linux/license.h>
27769  
27770  #if 0
27771 @@ -67,6 +72,8 @@ static LIST_HEAD(modules);
27772  
27773  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
27774  
27775 +extern int gr_check_modstop(void);
27776 +
27777  int register_module_notifier(struct notifier_block * nb)
27778  {
27779         return blocking_notifier_chain_register(&module_notify_list, nb);
27780 @@ -656,6 +663,9 @@ sys_delete_module(const char __user *nam
27781         char name[MODULE_NAME_LEN];
27782         int ret, forced = 0;
27783  
27784 +       if (gr_check_modstop())
27785 +               return -EPERM;
27786 +
27787         if (!capable(CAP_SYS_MODULE))
27788                 return -EPERM;
27789  
27790 @@ -1196,16 +1206,19 @@ static void free_module(struct module *m
27791         module_unload_free(mod);
27792  
27793         /* This may be NULL, but that's OK */
27794 -       module_free(mod, mod->module_init);
27795 +       module_free(mod, mod->module_init_rw);
27796 +       module_free_exec(mod, mod->module_init_rx);
27797         kfree(mod->args);
27798         if (mod->percpu)
27799                 percpu_modfree(mod->percpu);
27800  
27801         /* Free lock-classes: */
27802 -       lockdep_free_key_range(mod->module_core, mod->core_size);
27803 +       lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
27804 +       lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
27805  
27806         /* Finally, free the core (containing the module structure) */
27807 -       module_free(mod, mod->module_core);
27808 +       module_free_exec(mod, mod->module_core_rx);
27809 +       module_free(mod, mod->module_core_rw);
27810  }
27811  
27812  void *__symbol_get(const char *symbol)
27813 @@ -1362,11 +1375,14 @@ static void layout_sections(struct modul
27814                             || strncmp(secstrings + s->sh_name,
27815                                        ".init", 5) == 0)
27816                                 continue;
27817 -                       s->sh_entsize = get_offset(&mod->core_size, s);
27818 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
27819 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
27820 +                       else
27821 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
27822                         DEBUGP("\t%s\n", secstrings + s->sh_name);
27823                 }
27824                 if (m == 0)
27825 -                       mod->core_text_size = mod->core_size;
27826 +                       mod->core_size_rx = mod->core_size_rx;
27827         }
27828  
27829         DEBUGP("Init section allocation order:\n");
27830 @@ -1380,12 +1396,15 @@ static void layout_sections(struct modul
27831                             || strncmp(secstrings + s->sh_name,
27832                                        ".init", 5) != 0)
27833                                 continue;
27834 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
27835 -                                        | INIT_OFFSET_MASK);
27836 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
27837 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
27838 +                       else
27839 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
27840 +                       s->sh_entsize |= INIT_OFFSET_MASK;
27841                         DEBUGP("\t%s\n", secstrings + s->sh_name);
27842                 }
27843                 if (m == 0)
27844 -                       mod->init_text_size = mod->init_size;
27845 +                       mod->init_size_rx = mod->init_size_rx;
27846         }
27847  }
27848  
27849 @@ -1567,6 +1586,10 @@ static struct module *load_module(void _
27850         struct exception_table_entry *extable;
27851         mm_segment_t old_fs;
27852  
27853 +#ifdef CONFIG_PAX_KERNEXEC
27854 +       unsigned long cr0;
27855 +#endif
27856 +
27857         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
27858                umod, len, uargs);
27859         if (len < sizeof(*hdr))
27860 @@ -1725,21 +1748,57 @@ static struct module *load_module(void _
27861         layout_sections(mod, hdr, sechdrs, secstrings);
27862  
27863         /* Do the allocs. */
27864 -       ptr = module_alloc(mod->core_size);
27865 +       ptr = module_alloc(mod->core_size_rw);
27866         if (!ptr) {
27867                 err = -ENOMEM;
27868                 goto free_percpu;
27869         }
27870 -       memset(ptr, 0, mod->core_size);
27871 -       mod->module_core = ptr;
27872 +       memset(ptr, 0, mod->core_size_rw);
27873 +       mod->module_core_rw = ptr;
27874 +
27875 +       ptr = module_alloc(mod->init_size_rw);
27876 +       if (!ptr && mod->init_size_rw) {
27877 +               err = -ENOMEM;
27878 +               goto free_core_rw;
27879 +       }
27880 +       memset(ptr, 0, mod->init_size_rw);
27881 +       mod->module_init_rw = ptr;
27882 +
27883 +       ptr = module_alloc_exec(mod->core_size_rx);
27884 +       if (!ptr) {
27885 +               err = -ENOMEM;
27886 +               goto free_init_rw;
27887 +       }
27888  
27889 -       ptr = module_alloc(mod->init_size);
27890 -       if (!ptr && mod->init_size) {
27891 +#ifdef CONFIG_PAX_KERNEXEC
27892 +       pax_open_kernel(cr0);
27893 +#endif
27894 +
27895 +       memset(ptr, 0, mod->core_size_rx);
27896 +
27897 +#ifdef CONFIG_PAX_KERNEXEC
27898 +       pax_close_kernel(cr0);
27899 +#endif
27900 +
27901 +       mod->module_core_rx = ptr;
27902 +
27903 +       ptr = module_alloc_exec(mod->init_size_rx);
27904 +       if (!ptr && mod->init_size_rx) {
27905                 err = -ENOMEM;
27906 -               goto free_core;
27907 +               goto free_core_rx;
27908         }
27909 -       memset(ptr, 0, mod->init_size);
27910 -       mod->module_init = ptr;
27911 +
27912 +#ifdef CONFIG_PAX_KERNEXEC
27913 +       pax_open_kernel(cr0);
27914 +#endif
27915 +
27916 +       memset(ptr, 0, mod->init_size_rx);
27917 +
27918 +#ifdef CONFIG_PAX_KERNEXEC
27919 +       pax_close_kernel(cr0);
27920 +#endif
27921 +
27922 +       mod->module_init_rx = ptr;
27923  
27924         /* Transfer each section which specifies SHF_ALLOC */
27925         DEBUGP("final section addresses:\n");
27926 @@ -1749,17 +1808,44 @@ static struct module *load_module(void _
27927                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
27928                         continue;
27929  
27930 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
27931 -                       dest = mod->module_init
27932 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
27933 -               else
27934 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
27935 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
27936 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
27937 +                               dest = mod->module_init_rw
27938 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
27939 +                       else
27940 +                               dest = mod->module_init_rx
27941 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
27942 +               } else {
27943 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
27944 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
27945 +                       else
27946 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
27947 +               }
27948 +
27949 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
27950  
27951 -               if (sechdrs[i].sh_type != SHT_NOBITS)
27952 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
27953 -                              sechdrs[i].sh_size);
27954 +#ifdef CONFIG_PAX_KERNEXEC
27955 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
27956 +                               pax_open_kernel(cr0);
27957 +#endif
27958 +
27959 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
27960 +
27961 +#ifdef CONFIG_PAX_KERNEXEC
27962 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC))
27963 +                               pax_close_kernel(cr0);
27964 +#endif
27965 +
27966 +               }
27967                 /* Update sh_addr to point to copy in image. */
27968 -               sechdrs[i].sh_addr = (unsigned long)dest;
27969 +
27970 +#ifdef CONFIG_PAX_KERNEXEC
27971 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
27972 +                       sechdrs[i].sh_addr = (unsigned long)dest - __KERNEL_TEXT_OFFSET;
27973 +               else
27974 +#endif
27975 +
27976 +                       sechdrs[i].sh_addr = (unsigned long)dest;
27977                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
27978         }
27979         /* Module has been moved. */
27980 @@ -1780,8 +1866,18 @@ static struct module *load_module(void _
27981         setup_modinfo(mod, sechdrs, infoindex);
27982  
27983         /* Fix up syms, so that st_value is a pointer to location. */
27984 +
27985 +#ifdef CONFIG_PAX_KERNEXEC
27986 +       pax_open_kernel(cr0);
27987 +#endif
27988 +
27989         err = simplify_symbols(sechdrs, symindex, strtab, versindex, pcpuindex,
27990                                mod);
27991 +
27992 +#ifdef CONFIG_PAX_KERNEXEC
27993 +       pax_close_kernel(cr0);
27994 +#endif
27995 +
27996         if (err < 0)
27997                 goto cleanup;
27998  
27999 @@ -1836,11 +1932,20 @@ static struct module *load_module(void _
28000                 if (!(sechdrs[info].sh_flags & SHF_ALLOC))
28001                         continue;
28002  
28003 +#ifdef CONFIG_PAX_KERNEXEC
28004 +       pax_open_kernel(cr0);
28005 +#endif
28006 +
28007                 if (sechdrs[i].sh_type == SHT_REL)
28008                         err = apply_relocate(sechdrs, strtab, symindex, i,mod);
28009                 else if (sechdrs[i].sh_type == SHT_RELA)
28010                         err = apply_relocate_add(sechdrs, strtab, symindex, i,
28011                                                  mod);
28012 +
28013 +#ifdef CONFIG_PAX_KERNEXEC
28014 +       pax_close_kernel(cr0);
28015 +#endif
28016 +
28017                 if (err < 0)
28018                         goto cleanup;
28019         }
28020 @@ -1854,14 +1959,31 @@ static struct module *load_module(void _
28021         /* Set up and sort exception table */
28022         mod->num_exentries = sechdrs[exindex].sh_size / sizeof(*mod->extable);
28023         mod->extable = extable = (void *)sechdrs[exindex].sh_addr;
28024 +
28025 +#ifdef CONFIG_PAX_KERNEXEC
28026 +       pax_open_kernel(cr0);
28027 +#endif
28028 +
28029         sort_extable(extable, extable + mod->num_exentries);
28030  
28031 +#ifdef CONFIG_PAX_KERNEXEC
28032 +       pax_close_kernel(cr0);
28033 +#endif
28034 +
28035         /* Finally, copy percpu area over. */
28036         percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
28037                        sechdrs[pcpuindex].sh_size);
28038  
28039 +#ifdef CONFIG_PAX_KERNEXEC
28040 +       pax_open_kernel(cr0);
28041 +#endif
28042 +
28043         add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
28044  
28045 +#ifdef CONFIG_PAX_KERNEXEC
28046 +       pax_close_kernel(cr0);
28047 +#endif
28048 +
28049         err = module_finalize(hdr, sechdrs, mod);
28050         if (err < 0)
28051                 goto cleanup;
28052 @@ -1875,12 +1997,12 @@ static struct module *load_module(void _
28053          * Do it before processing of module parameters, so the module
28054          * can provide parameter accessor functions of its own.
28055          */
28056 -       if (mod->module_init)
28057 -               flush_icache_range((unsigned long)mod->module_init,
28058 -                                  (unsigned long)mod->module_init
28059 -                                  + mod->init_size);
28060 -       flush_icache_range((unsigned long)mod->module_core,
28061 -                          (unsigned long)mod->module_core + mod->core_size);
28062 +       if (mod->module_init_rx)
28063 +               flush_icache_range((unsigned long)mod->module_init_rx,
28064 +                                  (unsigned long)mod->module_init_rx
28065 +                                  + mod->init_size_rx);
28066 +       flush_icache_range((unsigned long)mod->module_core_rx,
28067 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
28068  
28069         set_fs(old_fs);
28070  
28071 @@ -1923,9 +2045,13 @@ static struct module *load_module(void _
28072         module_arch_cleanup(mod);
28073   cleanup:
28074         module_unload_free(mod);
28075 -       module_free(mod, mod->module_init);
28076 - free_core:
28077 -       module_free(mod, mod->module_core);
28078 +       module_free_exec(mod, mod->module_init_rx);
28079 + free_core_rx:
28080 +       module_free_exec(mod, mod->module_core_rx);
28081 + free_init_rw:
28082 +       module_free(mod, mod->module_init_rw);
28083 + free_core_rw:
28084 +       module_free(mod, mod->module_core_rw);
28085   free_percpu:
28086         if (percpu)
28087                 percpu_modfree(percpu);
28088 @@ -1961,6 +2087,9 @@ sys_init_module(void __user *umod,
28089         struct module *mod;
28090         int ret = 0;
28091  
28092 +       if (gr_check_modstop())
28093 +               return -EPERM;
28094 +
28095         /* Must have permission */
28096         if (!capable(CAP_SYS_MODULE))
28097                 return -EPERM;
28098 @@ -2012,10 +2141,12 @@ sys_init_module(void __user *umod,
28099         /* Drop initial reference. */
28100         module_put(mod);
28101         unwind_remove_table(mod->unwind_info, 1);
28102 -       module_free(mod, mod->module_init);
28103 -       mod->module_init = NULL;
28104 -       mod->init_size = 0;
28105 -       mod->init_text_size = 0;
28106 +       module_free(mod, mod->module_init_rw);
28107 +       module_free_exec(mod, mod->module_init_rx);
28108 +       mod->module_init_rw = NULL;
28109 +       mod->module_init_rx = NULL;
28110 +       mod->init_size_rw = 0;
28111 +       mod->init_size_rx = 0;
28112         mutex_unlock(&module_mutex);
28113  
28114         return 0;
28115 @@ -2046,10 +2177,14 @@ static const char *get_ksymbol(struct mo
28116         unsigned long nextval;
28117  
28118         /* At worse, next value is at end of module */
28119 -       if (within(addr, mod->module_init, mod->init_size))
28120 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
28121 -       else 
28122 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
28123 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
28124 +               nextval = (unsigned long)mod->module_init_rw;
28125 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
28126 +               nextval = (unsigned long)mod->module_core_rx;
28127 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
28128 +               nextval = (unsigned long)mod->module_core_rw;
28129 +       else
28130 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
28131  
28132         /* Scan for closest preceeding symbol, and next symbol. (ELF
28133             starts real symbols at 1). */
28134 @@ -2090,8 +2225,10 @@ const char *module_address_lookup(unsign
28135         struct module *mod;
28136  
28137         list_for_each_entry(mod, &modules, list) {
28138 -               if (within(addr, mod->module_init, mod->init_size)
28139 -                   || within(addr, mod->module_core, mod->core_size)) {
28140 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
28141 +                   || within(addr, mod->module_init_rw, mod->init_size_rw)
28142 +                   || within(addr, mod->module_core_rx, mod->core_size_rx)
28143 +                   || within(addr, mod->module_core_rw, mod->core_size_rw)) {
28144                         if (modname)
28145                                 *modname = mod->name;
28146                         return get_ksymbol(mod, addr, size, offset);
28147 @@ -2212,7 +2349,7 @@ static int m_show(struct seq_file *m, vo
28148         char buf[8];
28149  
28150         seq_printf(m, "%s %lu",
28151 -                  mod->name, mod->init_size + mod->core_size);
28152 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
28153         print_unload_info(m, mod);
28154  
28155         /* Informative for users. */
28156 @@ -2221,7 +2358,7 @@ static int m_show(struct seq_file *m, vo
28157                    mod->state == MODULE_STATE_COMING ? "Loading":
28158                    "Live");
28159         /* Used by oprofile and other similar tools. */
28160 -       seq_printf(m, " 0x%p", mod->module_core);
28161 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
28162  
28163         /* Taints info */
28164         if (mod->taints)
28165 @@ -2279,7 +2416,8 @@ int is_module_address(unsigned long addr
28166         spin_lock_irqsave(&modlist_lock, flags);
28167  
28168         list_for_each_entry(mod, &modules, list) {
28169 -               if (within(addr, mod->module_core, mod->core_size)) {
28170 +               if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
28171 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
28172                         spin_unlock_irqrestore(&modlist_lock, flags);
28173                         return 1;
28174                 }
28175 @@ -2297,8 +2435,8 @@ struct module *__module_text_address(uns
28176         struct module *mod;
28177  
28178         list_for_each_entry(mod, &modules, list)
28179 -               if (within(addr, mod->module_init, mod->init_text_size)
28180 -                   || within(addr, mod->module_core, mod->core_text_size))
28181 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
28182 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
28183                         return mod;
28184         return NULL;
28185  }
28186 diff -urNp linux-2.6.20.3/kernel/mutex.c linux-2.6.20.3/kernel/mutex.c
28187 --- linux-2.6.20.3/kernel/mutex.c       2007-03-13 14:27:08.000000000 -0400
28188 +++ linux-2.6.20.3/kernel/mutex.c       2007-03-23 08:10:06.000000000 -0400
28189 @@ -81,7 +81,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
28190   *
28191   * This function is similar to (but not equivalent to) down().
28192   */
28193 -void inline fastcall __sched mutex_lock(struct mutex *lock)
28194 +inline void fastcall __sched mutex_lock(struct mutex *lock)
28195  {
28196         might_sleep();
28197         /*
28198 diff -urNp linux-2.6.20.3/kernel/pid.c linux-2.6.20.3/kernel/pid.c
28199 --- linux-2.6.20.3/kernel/pid.c 2007-03-13 14:27:08.000000000 -0400
28200 +++ linux-2.6.20.3/kernel/pid.c 2007-03-23 08:11:31.000000000 -0400
28201 @@ -28,6 +28,7 @@
28202  #include <linux/hash.h>
28203  #include <linux/pid_namespace.h>
28204  #include <linux/vs_pid.h>
28205 +#include <linux/grsecurity.h>
28206  
28207  #define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift)
28208  static struct hlist_head *pid_hash;
28209 @@ -36,7 +37,7 @@ static struct kmem_cache *pid_cachep;
28210  
28211  int pid_max = PID_MAX_DEFAULT;
28212  
28213 -#define RESERVED_PIDS          300
28214 +#define RESERVED_PIDS          500
28215  
28216  int pid_max_min = RESERVED_PIDS + 1;
28217  int pid_max_max = PID_MAX_LIMIT;
28218 @@ -318,6 +319,8 @@ struct task_struct *find_task_by_pid_typ
28219                 /* maybe VS_WATCH_P in the future? */
28220                 !vx_check(task->xid, VS_WATCH|VS_IDENT))
28221                 return NULL;
28222 +       if (gr_pid_is_chrooted(task))
28223 +               return NULL;
28224         return task;
28225  }
28226  
28227 diff -urNp linux-2.6.20.3/kernel/posix-cpu-timers.c linux-2.6.20.3/kernel/posix-cpu-timers.c
28228 --- linux-2.6.20.3/kernel/posix-cpu-timers.c    2007-03-13 14:27:08.000000000 -0400
28229 +++ linux-2.6.20.3/kernel/posix-cpu-timers.c    2007-03-23 08:11:31.000000000 -0400
28230 @@ -6,6 +6,7 @@
28231  #include <linux/posix-timers.h>
28232  #include <asm/uaccess.h>
28233  #include <linux/errno.h>
28234 +#include <linux/grsecurity.h>
28235  
28236  static int check_clock(const clockid_t which_clock)
28237  {
28238 @@ -1139,6 +1140,7 @@ static void check_process_timers(struct 
28239                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
28240                         return;
28241                 }
28242 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
28243                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
28244                         /*
28245                          * At the soft limit, send a SIGXCPU every second.
28246 diff -urNp linux-2.6.20.3/kernel/power/poweroff.c linux-2.6.20.3/kernel/power/poweroff.c
28247 --- linux-2.6.20.3/kernel/power/poweroff.c      2007-03-13 14:27:08.000000000 -0400
28248 +++ linux-2.6.20.3/kernel/power/poweroff.c      2007-03-23 08:10:06.000000000 -0400
28249 @@ -35,7 +35,7 @@ static struct sysrq_key_op    sysrq_powerof
28250         .enable_mask    = SYSRQ_ENABLE_BOOT,
28251  };
28252  
28253 -static int pm_sysrq_init(void)
28254 +static int __init pm_sysrq_init(void)
28255  {
28256         register_sysrq_key('o', &sysrq_poweroff_op);
28257         return 0;
28258 diff -urNp linux-2.6.20.3/kernel/printk.c linux-2.6.20.3/kernel/printk.c
28259 --- linux-2.6.20.3/kernel/printk.c      2007-03-13 14:27:08.000000000 -0400
28260 +++ linux-2.6.20.3/kernel/printk.c      2007-03-23 08:11:31.000000000 -0400
28261 @@ -32,6 +32,7 @@
28262  #include <linux/syscalls.h>
28263  #include <linux/jiffies.h>
28264  #include <linux/vs_cvirt.h>
28265 +#include <linux/grsecurity.h>
28266  
28267  #include <asm/uaccess.h>
28268  
28269 @@ -186,6 +187,11 @@ int do_syslog(int type, char __user *buf
28270         char c;
28271         int error;
28272  
28273 +#ifdef CONFIG_GRKERNSEC_DMESG
28274 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
28275 +               return -EPERM;
28276 +#endif
28277 +
28278         error = security_syslog(type);
28279         if (error)
28280                 return error;
28281 diff -urNp linux-2.6.20.3/kernel/ptrace.c linux-2.6.20.3/kernel/ptrace.c
28282 --- linux-2.6.20.3/kernel/ptrace.c      2007-03-13 14:27:08.000000000 -0400
28283 +++ linux-2.6.20.3/kernel/ptrace.c      2007-03-23 08:11:31.000000000 -0400
28284 @@ -19,6 +19,7 @@
28285  #include <linux/security.h>
28286  #include <linux/signal.h>
28287  #include <linux/vs_context.h>
28288 +#include <linux/grsecurity.h>
28289  
28290  #include <asm/pgtable.h>
28291  #include <asm/uaccess.h>
28292 @@ -138,12 +139,12 @@ static int may_attach(struct task_struct
28293              (current->uid != task->uid) ||
28294              (current->gid != task->egid) ||
28295              (current->gid != task->sgid) ||
28296 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
28297 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
28298                 return -EPERM;
28299         smp_rmb();
28300         if (task->mm)
28301                 dumpable = task->mm->dumpable;
28302 -       if (!dumpable && !capable(CAP_SYS_PTRACE))
28303 +       if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
28304                 return -EPERM;
28305         if (!vx_check(task->xid, VS_ADMIN_P|VS_IDENT))
28306                 return -EPERM;
28307 @@ -487,6 +488,11 @@ asmlinkage long sys_ptrace(long request,
28308         if (ret < 0)
28309                 goto out_put_task_struct;
28310  
28311 +       if (gr_handle_ptrace(child, request)) {
28312 +               ret = -EPERM;
28313 +               goto out_put_task_struct;
28314 +       }
28315 +
28316         ret = arch_ptrace(child, request, addr, data);
28317         if (ret < 0)
28318                 goto out_put_task_struct;
28319 diff -urNp linux-2.6.20.3/kernel/rcupdate.c linux-2.6.20.3/kernel/rcupdate.c
28320 --- linux-2.6.20.3/kernel/rcupdate.c    2007-03-13 14:27:08.000000000 -0400
28321 +++ linux-2.6.20.3/kernel/rcupdate.c    2007-03-23 08:10:06.000000000 -0400
28322 @@ -63,11 +63,11 @@ static struct rcu_ctrlblk rcu_bh_ctrlblk
28323         .cpumask = CPU_MASK_NONE,
28324  };
28325  
28326 -DEFINE_PER_CPU(struct rcu_data, rcu_data) = { 0L };
28327 -DEFINE_PER_CPU(struct rcu_data, rcu_bh_data) = { 0L };
28328 +DEFINE_PER_CPU(struct rcu_data, rcu_data);
28329 +DEFINE_PER_CPU(struct rcu_data, rcu_bh_data);
28330  
28331  /* Fake initialization required by compiler */
28332 -static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet) = {NULL};
28333 +static DEFINE_PER_CPU(struct tasklet_struct, rcu_tasklet);
28334  static int blimit = 10;
28335  static int qhimark = 10000;
28336  static int qlowmark = 100;
28337 diff -urNp linux-2.6.20.3/kernel/resource.c linux-2.6.20.3/kernel/resource.c
28338 --- linux-2.6.20.3/kernel/resource.c    2007-03-13 14:27:08.000000000 -0400
28339 +++ linux-2.6.20.3/kernel/resource.c    2007-03-23 08:11:31.000000000 -0400
28340 @@ -133,10 +133,27 @@ static int __init ioresources_init(void)
28341  {
28342         struct proc_dir_entry *entry;
28343  
28344 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
28345 +#ifdef CONFIG_GRKERNSEC_PROC_USER
28346 +       entry = create_proc_entry("ioports", S_IRUSR, NULL);
28347 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
28348 +       entry = create_proc_entry("ioports", S_IRUSR | S_IRGRP, NULL);
28349 +#endif
28350 +#else
28351         entry = create_proc_entry("ioports", 0, NULL);
28352 +#endif
28353         if (entry)
28354                 entry->proc_fops = &proc_ioports_operations;
28355 +
28356 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
28357 +#ifdef CONFIG_GRKERNSEC_PROC_USER
28358 +       entry = create_proc_entry("iomem", S_IRUSR, NULL);
28359 +#elif CONFIG_GRKERNSEC_PROC_USERGROUP
28360 +       entry = create_proc_entry("iomem", S_IRUSR | S_IRGRP, NULL);
28361 +#endif
28362 +#else
28363         entry = create_proc_entry("iomem", 0, NULL);
28364 +#endif
28365         if (entry)
28366                 entry->proc_fops = &proc_iomem_operations;
28367         return 0;
28368 diff -urNp linux-2.6.20.3/kernel/sched.c linux-2.6.20.3/kernel/sched.c
28369 --- linux-2.6.20.3/kernel/sched.c       2007-03-13 14:27:08.000000000 -0400
28370 +++ linux-2.6.20.3/kernel/sched.c       2007-03-23 08:11:31.000000000 -0400
28371 @@ -52,6 +52,7 @@
28372  #include <linux/tsacct_kern.h>
28373  #include <linux/kprobes.h>
28374  #include <linux/delayacct.h>
28375 +#include <linux/grsecurity.h>
28376  #include <asm/tlb.h>
28377  
28378  #include <asm/unistd.h>
28379 @@ -4111,7 +4112,8 @@ asmlinkage long sys_nice(int increment)
28380         if (nice > 19)
28381                 nice = 19;
28382  
28383 -       if (increment < 0 && !can_nice(current, nice))
28384 +       if (increment < 0 && (!can_nice(current, nice) ||
28385 +                             gr_handle_chroot_nice()))
28386                 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
28387  
28388         retval = security_task_setnice(current, nice);
28389 diff -urNp linux-2.6.20.3/kernel/signal.c linux-2.6.20.3/kernel/signal.c
28390 --- linux-2.6.20.3/kernel/signal.c      2007-03-13 14:27:08.000000000 -0400
28391 +++ linux-2.6.20.3/kernel/signal.c      2007-03-23 08:11:31.000000000 -0400
28392 @@ -25,6 +25,7 @@
28393  #include <linux/capability.h>
28394  #include <linux/freezer.h>
28395  #include <linux/pid_namespace.h>
28396 +#include <linux/grsecurity.h>
28397  #include <linux/nsproxy.h>
28398  #include <linux/vs_context.h>
28399  #include <linux/vs_pid.h>
28400 @@ -596,11 +597,11 @@ static int check_kill_permission(int sig
28401                 sig, info, t, vx_task_xid(t), t->pid);
28402  
28403         error = -EPERM;
28404 -       if (((sig != SIGCONT) ||
28405 +       if ((((sig != SIGCONT) ||
28406                 (process_session(current) != process_session(t)))
28407             && (current->euid ^ t->suid) && (current->euid ^ t->uid)
28408             && (current->uid ^ t->suid) && (current->uid ^ t->uid)
28409 -           && !capable(CAP_KILL))
28410 +           && !capable(CAP_KILL)) || gr_handle_signal(t, sig))
28411                 return error;
28412  
28413         error = -ESRCH;
28414 @@ -612,8 +613,10 @@ static int check_kill_permission(int sig
28415         }
28416  skip:
28417         error = security_task_kill(t, info, sig, 0);
28418 -       if (!error)
28419 +       if (!error) {
28420                 audit_signal_info(sig, t); /* Let audit system see the signal */
28421 +               gr_log_signal(sig, t);
28422 +       }
28423         return error;
28424  }
28425  
28426 @@ -791,7 +794,7 @@ out_set:
28427         (((sig) < SIGRTMIN) && sigismember(&(sigptr)->signal, (sig)))
28428  
28429  
28430 -static int
28431 +int
28432  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
28433  {
28434         int ret = 0;
28435 @@ -845,6 +848,10 @@ force_sig_info(int sig, struct siginfo *
28436                 }
28437         }
28438         ret = specific_send_sig_info(sig, info, t);
28439 +
28440 +       gr_log_signal(sig, t);
28441 +       gr_handle_crash(t, sig);
28442 +
28443         spin_unlock_irqrestore(&t->sighand->siglock, flags);
28444  
28445         return ret;
28446 diff -urNp linux-2.6.20.3/kernel/sys.c linux-2.6.20.3/kernel/sys.c
28447 --- linux-2.6.20.3/kernel/sys.c 2007-03-13 14:27:08.000000000 -0400
28448 +++ linux-2.6.20.3/kernel/sys.c 2007-03-23 08:11:31.000000000 -0400
28449 @@ -29,6 +29,7 @@
28450  #include <linux/signal.h>
28451  #include <linux/cn_proc.h>
28452  #include <linux/getcpu.h>
28453 +#include <linux/grsecurity.h>
28454  
28455  #include <linux/compat.h>
28456  #include <linux/syscalls.h>
28457 @@ -583,6 +584,12 @@ static int set_one_prio(struct task_stru
28458                         error = -EACCES;
28459                 goto out;
28460         }
28461 +
28462 +       if (gr_handle_chroot_setpriority(p, niceval)) {
28463 +               error = -EACCES;
28464 +               goto out;
28465 +       }
28466 +
28467         no_nice = security_task_setnice(p, niceval);
28468         if (no_nice) {
28469                 error = no_nice;
28470 @@ -961,6 +968,9 @@ asmlinkage long sys_setregid(gid_t rgid,
28471         if (rgid != (gid_t) -1 ||
28472             (egid != (gid_t) -1 && egid != old_rgid))
28473                 current->sgid = new_egid;
28474 +
28475 +       gr_set_role_label(current, current->uid, new_rgid);
28476 +
28477         current->fsgid = new_egid;
28478         current->egid = new_egid;
28479         current->gid = new_rgid;
28480 @@ -988,6 +998,9 @@ asmlinkage long sys_setgid(gid_t gid)
28481                         current->mm->dumpable = suid_dumpable;
28482                         smp_wmb();
28483                 }
28484 +
28485 +               gr_set_role_label(current, current->uid, gid);
28486 +
28487                 current->gid = current->egid = current->sgid = current->fsgid = gid;
28488         } else if ((gid == current->gid) || (gid == current->sgid)) {
28489                 if (old_egid != gid) {
28490 @@ -1025,6 +1038,9 @@ static int set_user(uid_t new_ruid, int 
28491                 current->mm->dumpable = suid_dumpable;
28492                 smp_wmb();
28493         }
28494 +
28495 +       gr_set_role_label(current, new_ruid, current->gid);
28496 +
28497         current->uid = new_ruid;
28498         return 0;
28499  }
28500 @@ -1127,6 +1143,9 @@ asmlinkage long sys_setuid(uid_t uid)
28501         } else if ((uid != current->uid) && (uid != new_suid))
28502                 return -EPERM;
28503  
28504 +       if (gr_check_crash_uid(uid))
28505 +               return -EPERM;
28506 +
28507         if (old_euid != uid) {
28508                 current->mm->dumpable = suid_dumpable;
28509                 smp_wmb();
28510 @@ -1229,8 +1248,10 @@ asmlinkage long sys_setresgid(gid_t rgid
28511                 current->egid = egid;
28512         }
28513         current->fsgid = current->egid;
28514 -       if (rgid != (gid_t) -1)
28515 +       if (rgid != (gid_t) -1) {
28516 +               gr_set_role_label(current, current->uid, rgid);
28517                 current->gid = rgid;
28518 +       }
28519         if (sgid != (gid_t) -1)
28520                 current->sgid = sgid;
28521  
28522 @@ -1378,7 +1399,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
28523         write_lock_irq(&tasklist_lock);
28524  
28525         err = -ESRCH;
28526 -       p = find_task_by_pid(pid);
28527 +       /* grsec: replaced find_task_by_pid with equivalent call
28528 +          which lacks the chroot restriction
28529 +       */
28530 +       p = pid_task(find_pid(pid), PIDTYPE_PID);
28531         if (!p)
28532                 goto out;
28533  
28534 @@ -2092,7 +2116,7 @@ asmlinkage long sys_prctl(int option, un
28535                         error = current->mm->dumpable;
28536                         break;
28537                 case PR_SET_DUMPABLE:
28538 -                       if (arg2 < 0 || arg2 > 1) {
28539 +                       if (arg2 > 1) {
28540                                 error = -EINVAL;
28541                                 break;
28542                         }
28543 diff -urNp linux-2.6.20.3/kernel/sysctl.c linux-2.6.20.3/kernel/sysctl.c
28544 --- linux-2.6.20.3/kernel/sysctl.c      2007-03-13 14:27:08.000000000 -0400
28545 +++ linux-2.6.20.3/kernel/sysctl.c      2007-03-23 08:11:31.000000000 -0400
28546 @@ -58,6 +58,14 @@ extern int proc_nr_files(ctl_table *tabl
28547  #endif
28548  
28549  #if defined(CONFIG_SYSCTL)
28550 +#include <linux/grsecurity.h>
28551 +#include <linux/grinternal.h>
28552 +
28553 +extern __u32 gr_handle_sysctl(const ctl_table *table, const void *oldval,
28554 +                             const void *newval);
28555 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
28556 +                               const int op);
28557 +extern int gr_handle_chroot_sysctl(const int op);
28558  
28559  /* External variables not in a header file. */
28560  extern int C_A_D;
28561 @@ -156,7 +164,7 @@ static int proc_do_cad_pid(ctl_table *ta
28562  
28563  static ctl_table root_table[];
28564  static struct ctl_table_header root_table_header =
28565 -       { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) };
28566 +       { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry), 0, NULL };
28567  
28568  static ctl_table kern_table[];
28569  static ctl_table vm_table[];
28570 @@ -170,6 +178,7 @@ extern ctl_table pty_table[];
28571  #ifdef CONFIG_INOTIFY_USER
28572  extern ctl_table inotify_table[];
28573  #endif
28574 +extern ctl_table grsecurity_table[];
28575  
28576  #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT
28577  int sysctl_legacy_va_layout;
28578 @@ -209,6 +218,21 @@ static void *get_ipc(ctl_table *table, i
28579  #define get_ipc(T,W) ((T)->data)
28580  #endif
28581  
28582 +#ifdef CONFIG_PAX_SOFTMODE
28583 +static ctl_table pax_table[] = {
28584 +       {
28585 +               .ctl_name       = PAX_SOFTMODE,
28586 +               .procname       = "softmode",
28587 +               .data           = &pax_softmode,
28588 +               .maxlen         = sizeof(unsigned int),
28589 +               .mode           = 0600,
28590 +               .proc_handler   = &proc_dointvec,
28591 +       },
28592 +
28593 +       { .ctl_name = 0 }
28594 +};
28595 +#endif
28596 +
28597  /* /proc declarations: */
28598  
28599  #ifdef CONFIG_PROC_SYSCTL
28600 @@ -270,7 +294,6 @@ static ctl_table root_table[] = {
28601                 .mode           = 0555,
28602                 .child          = dev_table,
28603         },
28604 -
28605         { .ctl_name = 0 }
28606  };
28607  
28608 @@ -791,6 +814,23 @@ static ctl_table kern_table[] = {
28609         },
28610  #endif
28611  
28612 +#ifdef CONFIG_PAX_SOFTMODE
28613 +       {
28614 +               .ctl_name       = KERN_PAX,
28615 +               .procname       = "pax",
28616 +               .mode           = 0500,
28617 +               .child          = pax_table,
28618 +       },
28619 +#endif
28620 +
28621 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
28622 +       {
28623 +               .ctl_name       = KERN_GRSECURITY,
28624 +               .procname       = "grsecurity",
28625 +               .mode           = 0500,
28626 +               .child          = grsecurity_table,
28627 +       },
28628 +#endif
28629         { .ctl_name = 0 }
28630  };
28631  
28632 @@ -1305,6 +1345,10 @@ static int test_perm(int mode, int op)
28633  static inline int ctl_perm(ctl_table *table, int op)
28634  {
28635         int error;
28636 +       if (table->de && gr_handle_sysctl_mod(table->de->parent->name, table->de->name, op))
28637 +               return -EACCES;
28638 +       if (gr_handle_chroot_sysctl(op))
28639 +               return -EACCES;
28640         error = security_sysctl(table, op);
28641         if (error)
28642                 return error;
28643 @@ -1344,6 +1388,10 @@ repeat:
28644                                 table = table->child;
28645                                 goto repeat;
28646                         }
28647 +
28648 +                       if (!gr_handle_sysctl(table, oldval, newval))
28649 +                               return -EPERM;
28650 +
28651                         error = do_sysctl_strategy(table, name, nlen,
28652                                                    oldval, oldlenp,
28653                                                    newval, newlen);
28654 diff -urNp linux-2.6.20.3/kernel/time.c linux-2.6.20.3/kernel/time.c
28655 --- linux-2.6.20.3/kernel/time.c        2007-03-13 14:27:08.000000000 -0400
28656 +++ linux-2.6.20.3/kernel/time.c        2007-03-23 08:11:31.000000000 -0400
28657 @@ -36,6 +36,7 @@
28658  #include <linux/security.h>
28659  #include <linux/fs.h>
28660  #include <linux/module.h>
28661 +#include <linux/grsecurity.h>
28662  
28663  #include <asm/uaccess.h>
28664  #include <asm/unistd.h>
28665 @@ -93,6 +94,9 @@ asmlinkage long sys_stime(time_t __user 
28666                 return err;
28667  
28668         vx_settimeofday(&tv);
28669 +
28670 +       gr_log_timechange();
28671 +
28672         return 0;
28673  }
28674  
28675 @@ -199,6 +203,8 @@ asmlinkage long sys_settimeofday(struct 
28676                         return -EFAULT;
28677         }
28678  
28679 +       gr_log_timechange();
28680 +
28681         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
28682  }
28683  
28684 diff -urNp linux-2.6.20.3/lib/radix-tree.c linux-2.6.20.3/lib/radix-tree.c
28685 --- linux-2.6.20.3/lib/radix-tree.c     2007-03-13 14:27:08.000000000 -0400
28686 +++ linux-2.6.20.3/lib/radix-tree.c     2007-03-23 08:10:06.000000000 -0400
28687 @@ -76,7 +76,7 @@ struct radix_tree_preload {
28688         int nr;
28689         struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
28690  };
28691 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
28692 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, {NULL} };
28693  
28694  static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
28695  {
28696 diff -urNp linux-2.6.20.3/localversion-grsec linux-2.6.20.3/localversion-grsec
28697 --- linux-2.6.20.3/localversion-grsec   1969-12-31 19:00:00.000000000 -0500
28698 +++ linux-2.6.20.3/localversion-grsec   2007-03-23 08:11:31.000000000 -0400
28699 @@ -0,0 +1 @@
28700 +-grsec
28701 diff -urNp linux-2.6.20.3/Makefile linux-2.6.20.3/Makefile
28702 --- linux-2.6.20.3/Makefile     2007-03-13 14:27:08.000000000 -0400
28703 +++ linux-2.6.20.3/Makefile     2007-03-23 08:11:31.000000000 -0400
28704 @@ -312,7 +312,7 @@ LINUXINCLUDE    := -Iinclude \
28705  
28706  CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
28707  
28708 -CFLAGS          := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
28709 +CFLAGS          := -Wall -W -Wno-unused -Wno-sign-compare -Wundef -Wstrict-prototypes -Wno-trigraphs \
28710                     -fno-strict-aliasing -fno-common
28711  AFLAGS          := -D__ASSEMBLY__
28712  
28713 @@ -553,7 +553,7 @@ export mod_strip_cmd
28714  
28715  
28716  ifeq ($(KBUILD_EXTMOD),)
28717 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
28718 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
28719  
28720  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
28721                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
28722 diff -urNp linux-2.6.20.3/mm/filemap.c linux-2.6.20.3/mm/filemap.c
28723 --- linux-2.6.20.3/mm/filemap.c 2007-03-13 14:27:08.000000000 -0400
28724 +++ linux-2.6.20.3/mm/filemap.c 2007-03-23 08:11:31.000000000 -0400
28725 @@ -30,6 +30,7 @@
28726  #include <linux/security.h>
28727  #include <linux/syscalls.h>
28728  #include <linux/cpuset.h>
28729 +#include <linux/grsecurity.h>
28730  #include "filemap.h"
28731  #include "internal.h"
28732  
28733 @@ -1717,7 +1718,13 @@ int generic_file_mmap(struct file * file
28734         struct address_space *mapping = file->f_mapping;
28735  
28736         if (!mapping->a_ops->readpage)
28737 -               return -ENOEXEC;
28738 +               return -ENODEV;
28739 +
28740 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
28741 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
28742 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
28743 +#endif
28744 +
28745         file_accessed(file);
28746         vma->vm_ops = &generic_file_vm_ops;
28747         return 0;
28748 @@ -1955,6 +1962,7 @@ inline int generic_write_checks(struct f
28749                          *pos = i_size_read(inode);
28750  
28751                 if (limit != RLIM_INFINITY) {
28752 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
28753                         if (*pos >= limit) {
28754                                 send_sig(SIGXFSZ, current, 0);
28755                                 return -EFBIG;
28756 diff -urNp linux-2.6.20.3/mm/filemap_xip.c linux-2.6.20.3/mm/filemap_xip.c
28757 --- linux-2.6.20.3/mm/filemap_xip.c     2007-03-13 14:27:08.000000000 -0400
28758 +++ linux-2.6.20.3/mm/filemap_xip.c     2007-03-23 08:10:06.000000000 -0400
28759 @@ -262,6 +262,11 @@ int xip_file_mmap(struct file * file, st
28760  {
28761         BUG_ON(!file->f_mapping->a_ops->get_xip_page);
28762  
28763 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
28764 +       if ((vma->vm_mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
28765 +               vma->vm_page_prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(vma->vm_page_prot)))));
28766 +#endif
28767 +
28768         file_accessed(file);
28769         vma->vm_ops = &xip_file_vm_ops;
28770         return 0;
28771 diff -urNp linux-2.6.20.3/mm/madvise.c linux-2.6.20.3/mm/madvise.c
28772 --- linux-2.6.20.3/mm/madvise.c 2007-03-13 14:27:08.000000000 -0400
28773 +++ linux-2.6.20.3/mm/madvise.c 2007-03-23 08:10:06.000000000 -0400
28774 @@ -15,9 +15,46 @@
28775   * We can potentially split a vm area into separate
28776   * areas, each area with its own behavior.
28777   */
28778 +
28779 +#ifdef CONFIG_PAX_SEGMEXEC
28780 +static long __madvise_behavior(struct vm_area_struct * vma,
28781 +                    struct vm_area_struct **prev,
28782 +                    unsigned long start, unsigned long end, int behavior);
28783 +
28784 +static long madvise_behavior(struct vm_area_struct * vma,
28785 +                    struct vm_area_struct **prev,
28786 +                    unsigned long start, unsigned long end, int behavior)
28787 +{
28788 +       if (vma->vm_flags & VM_MIRROR) {
28789 +               struct vm_area_struct * vma_m, * prev_m;
28790 +               unsigned long start_m, end_m;
28791 +               int error;
28792 +
28793 +               start_m = vma->vm_start + vma->vm_mirror;
28794 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
28795 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
28796 +                       start_m = start + vma->vm_mirror;
28797 +                       end_m = end + vma->vm_mirror;
28798 +                       error = __madvise_behavior(vma_m, &prev_m, start_m, end_m, behavior);
28799 +                       if (error)
28800 +                               return error;
28801 +               } else {
28802 +                       printk("PAX: VMMIRROR: madvise bug in %s, %08lx\n", current->comm, vma->vm_start);
28803 +                       return -ENOMEM;
28804 +               }
28805 +       }
28806 +
28807 +       return __madvise_behavior(vma, prev, start, end, behavior);
28808 +}
28809 +
28810 +static long __madvise_behavior(struct vm_area_struct * vma,
28811 +                    struct vm_area_struct **prev,
28812 +                    unsigned long start, unsigned long end, int behavior)
28813 +#else
28814  static long madvise_behavior(struct vm_area_struct * vma,
28815                      struct vm_area_struct **prev,
28816                      unsigned long start, unsigned long end, int behavior)
28817 +#endif
28818  {
28819         struct mm_struct * mm = vma->vm_mm;
28820         int error = 0;
28821 diff -urNp linux-2.6.20.3/mm/memory.c linux-2.6.20.3/mm/memory.c
28822 --- linux-2.6.20.3/mm/memory.c  2007-03-13 14:27:08.000000000 -0400
28823 +++ linux-2.6.20.3/mm/memory.c  2007-03-23 08:11:31.000000000 -0400
28824 @@ -50,6 +50,7 @@
28825  #include <linux/delayacct.h>
28826  #include <linux/init.h>
28827  #include <linux/writeback.h>
28828 +#include <linux/grsecurity.h>
28829  
28830  #include <asm/pgalloc.h>
28831  #include <asm/uaccess.h>
28832 @@ -322,6 +323,11 @@ int __pte_alloc(struct mm_struct *mm, pm
28833  
28834  int __pte_alloc_kernel(pmd_t *pmd, unsigned long address)
28835  {
28836 +
28837 +#ifdef CONFIG_PAX_KERNEXEC
28838 +       unsigned long cr0;
28839 +#endif
28840 +
28841         pte_t *new = pte_alloc_one_kernel(&init_mm, address);
28842         if (!new)
28843                 return -ENOMEM;
28844 @@ -329,8 +335,19 @@ int __pte_alloc_kernel(pmd_t *pmd, unsig
28845         spin_lock(&init_mm.page_table_lock);
28846         if (pmd_present(*pmd))          /* Another has populated it */
28847                 pte_free_kernel(new);
28848 -       else
28849 +       else {
28850 +
28851 +#ifdef CONFIG_PAX_KERNEXEC
28852 +               pax_open_kernel(cr0);
28853 +#endif
28854 +
28855                 pmd_populate_kernel(&init_mm, pmd, new);
28856 +
28857 +#ifdef CONFIG_PAX_KERNEXEC
28858 +               pax_close_kernel(cr0);
28859 +#endif
28860 +
28861 +       }
28862         spin_unlock(&init_mm.page_table_lock);
28863         return 0;
28864  }
28865 @@ -995,7 +1012,7 @@ int get_user_pages(struct task_struct *t
28866                 struct vm_area_struct *vma;
28867                 unsigned int foll_flags;
28868  
28869 -               vma = find_extend_vma(mm, start);
28870 +               vma = find_vma(mm, start);
28871                 if (!vma && in_gate_area(tsk, start)) {
28872                         unsigned long pg = start & PAGE_MASK;
28873                         struct vm_area_struct *gate_vma = get_gate_vma(tsk);
28874 @@ -1035,7 +1052,7 @@ int get_user_pages(struct task_struct *t
28875                         continue;
28876                 }
28877  
28878 -               if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
28879 +               if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
28880                                 || !(vm_flags & vma->vm_flags))
28881                         return i ? : -EFAULT;
28882  
28883 @@ -1469,6 +1486,88 @@ static inline void cow_user_page(struct 
28884         copy_user_highpage(dst, src, va, vma);
28885  }
28886  
28887 +#ifdef CONFIG_PAX_SEGMEXEC
28888 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
28889 + *
28890 + * the ptl of the lower mapped page is held on entry and is not released on exit
28891 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
28892 + */
28893 +static void pax_mirror_fault(struct vm_area_struct *vma, unsigned long address, pte_t *pte)
28894 +{
28895 +       struct mm_struct *mm = vma->vm_mm;
28896 +       unsigned long address_m, pfn_m;
28897 +       struct vm_area_struct * vma_m = NULL;
28898 +       pte_t * pte_m, entry_m;
28899 +       struct page * page_m = NULL;
28900 +
28901 +       address_m = vma->vm_start + vma->vm_mirror;
28902 +       vma_m = find_vma(mm, address_m);
28903 +       BUG_ON(!vma_m || vma_m->vm_start != address_m);
28904 +
28905 +       address_m = address + vma->vm_mirror;
28906 +       pte_m = pte_offset_map_nested(pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m), address_m);
28907 +
28908 +       if (pte_same(*pte, *pte_m)) {
28909 +               pte_unmap_nested(pte_m);
28910 +               return;
28911 +       }
28912 +
28913 +       pfn_m = pte_pfn(*pte);
28914 +       if (pte_present(*pte_m)) {
28915 +               page_m = vm_normal_page(vma_m, address_m, *pte_m);
28916 +               if (page_m) {
28917 +                       flush_cache_page(vma_m, address_m, pfn_m);
28918 +                       flush_icache_page(vma_m, page_m);
28919 +               }
28920 +       }
28921 +
28922 +       if (pte_present(*pte_m))
28923 +               entry_m = ptep_clear_flush(vma_m, address_m, pte_m);
28924 +       else
28925 +               entry_m = ptep_get_and_clear(mm, address_m, pte_m);
28926 +
28927 +       if (pte_none(entry_m)) {
28928 +       } else if (pte_present(entry_m)) {
28929 +               if (page_m) {
28930 +                       page_remove_rmap(page_m, vma_m);
28931 +                       if (PageAnon(page_m))
28932 +                               dec_mm_counter(mm, anon_rss);
28933 +                       else
28934 +                               dec_mm_counter(mm, file_rss);
28935 +                       page_cache_release(page_m);
28936 +               }
28937 +       } else if (!pte_file(entry_m)) {
28938 +               free_swap_and_cache(pte_to_swp_entry(entry_m));
28939 +       } else {
28940 +               printk(KERN_ERR "PAX: VMMIRROR: bug in mirror_fault: %08lx, %08lx, %08lx, %08lx\n",
28941 +                               address, vma->vm_start, address_m, vma_m->vm_start);
28942 +       }
28943 +
28944 +       page_m = vm_normal_page(vma, address, *pte);
28945 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
28946 +       if (pte_write(*pte))
28947 +               entry_m = maybe_mkwrite(pte_mkdirty(entry_m), vma_m);
28948 +       if (page_m) {
28949 +               page_cache_get(page_m);
28950 +               /*
28951 +                * we can test PAGE_MAPPING_ANON without holding page_map_lock because
28952 +                * we hold the page table lock and have a reference to page_m
28953 +                */
28954 +               if (PageAnon(page_m)) {
28955 +                       page_add_anon_rmap(page_m, vma_m, address_m);
28956 +                       inc_mm_counter(mm, anon_rss);
28957 +               } else {
28958 +                       page_add_file_rmap(page_m);
28959 +                       inc_mm_counter(mm, file_rss);
28960 +               }
28961 +       }
28962 +       set_pte_at(mm, address_m, pte_m, entry_m);
28963 +       update_mmu_cache(vma_m, address_m, entry_m);
28964 +       lazy_mmu_prot_update(entry_m);
28965 +       pte_unmap_nested(pte_m);
28966 +}
28967 +#endif
28968 +
28969  /*
28970   * This routine handles present pages, when users try to write
28971   * to a shared page. It is done by copying the page to a new address
28972 @@ -1612,6 +1711,12 @@ gotten:
28973                 /* Free the old page.. */
28974                 new_page = old_page;
28975                 ret |= VM_FAULT_WRITE;
28976 +
28977 +#ifdef CONFIG_PAX_SEGMEXEC
28978 +               if (vma->vm_flags & VM_MIRROR)
28979 +                       pax_mirror_fault(vma, address, page_table);
28980 +#endif
28981 +
28982         }
28983         if (new_page)
28984                 page_cache_release(new_page);
28985 @@ -1871,6 +1976,7 @@ int vmtruncate(struct inode * inode, lof
28986  
28987  do_expand:
28988         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
28989 +       gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
28990         if (limit != RLIM_INFINITY && offset > limit)
28991                 goto out_sig;
28992         if (offset > inode->i_sb->s_maxbytes)
28993 @@ -2064,6 +2170,12 @@ static int do_swap_page(struct mm_struct
28994         /* No need to invalidate - it was non-present before */
28995         update_mmu_cache(vma, address, pte);
28996         lazy_mmu_prot_update(pte);
28997 +
28998 +#ifdef CONFIG_PAX_SEGMEXEC
28999 +       if (vma->vm_flags & VM_MIRROR)
29000 +               pax_mirror_fault(vma, address, page_table);
29001 +#endif
29002 +
29003  unlock:
29004         pte_unmap_unlock(page_table, ptl);
29005  out:
29006 @@ -2126,6 +2238,12 @@ static int do_anonymous_page(struct mm_s
29007         /* No need to invalidate - it was non-present before */
29008         update_mmu_cache(vma, address, entry);
29009         lazy_mmu_prot_update(entry);
29010 +
29011 +#ifdef CONFIG_PAX_SEGMEXEC
29012 +       if (vma->vm_flags & VM_MIRROR)
29013 +               pax_mirror_fault(vma, address, page_table);
29014 +#endif
29015 +
29016  unlock:
29017         pte_unmap_unlock(page_table, ptl);
29018         return VM_FAULT_MINOR;
29019 @@ -2271,6 +2389,12 @@ retry:
29020         /* no need to invalidate: a not-present page shouldn't be cached */
29021         update_mmu_cache(vma, address, entry);
29022         lazy_mmu_prot_update(entry);
29023 +
29024 +#ifdef CONFIG_PAX_SEGMEXEC
29025 +       if (vma->vm_flags & VM_MIRROR)
29026 +               pax_mirror_fault(vma, address, page_table);
29027 +#endif
29028 +
29029  unlock:
29030         pte_unmap_unlock(page_table, ptl);
29031         if (dirty_page) {
29032 @@ -2464,6 +2588,12 @@ static inline int handle_pte_fault(struc
29033                         flush_tlb_page(vma, address);
29034         }
29035  unlock:
29036 +
29037 +#ifdef CONFIG_PAX_SEGMEXEC
29038 +       if (vma->vm_flags & VM_MIRROR)
29039 +               pax_mirror_fault(vma, address, pte);
29040 +#endif
29041 +
29042         pte_unmap_unlock(pte, ptl);
29043         ret = VM_FAULT_MINOR;
29044  out:
29045 @@ -2460,6 +2590,49 @@ int __handle_mm_fault(struct mm_struct *
29046         if (unlikely(is_vm_hugetlb_page(vma)))
29047                 return hugetlb_fault(mm, vma, address, write_access);
29048  
29049 +#ifdef CONFIG_PAX_SEGMEXEC
29050 +       if (vma->vm_flags & VM_MIRROR) {
29051 +               unsigned long address_m;
29052 +               struct vm_area_struct * vma_m;
29053 +               pgd_t *pgd_m;
29054 +               pud_t *pud_m;
29055 +               pmd_t *pmd_m;
29056 +
29057 +               address_m = vma->vm_start + vma->vm_mirror;
29058 +               vma_m = find_vma(mm, address_m);
29059 +
29060 +               /* PaX: sanity checks */
29061 +               if (!vma_m) {
29062 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug, %08lx, %p, %08lx, %p\n",
29063 +                              address, vma, address_m, vma_m);
29064 +                       return VM_FAULT_SIGBUS;
29065 +               } else if (!(vma_m->vm_flags & VM_MIRROR) ||
29066 +                       vma_m->vm_start != address_m ||
29067 +                       vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start)
29068 +               {
29069 +                       printk(KERN_ERR "PAX: VMMIRROR: fault bug2, %08lx, %08lx, %08lx, %08lx, %08lx\n",
29070 +                              address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
29071 +                       return VM_FAULT_SIGBUS;
29072 +               }
29073 +
29074 +               if (address_m < address) {
29075 +                       address += vma->vm_mirror;
29076 +                       vma = vma_m;
29077 +               }
29078 +
29079 +               address_m = address + vma->vm_mirror;
29080 +               pgd_m = pgd_offset(mm, address_m);
29081 +               pud_m = pud_alloc(mm, pgd_m, address_m);
29082 +               if (!pud_m)
29083 +                       return VM_FAULT_OOM;
29084 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
29085 +               if (!pmd_m)
29086 +                       return VM_FAULT_OOM;
29087 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
29088 +                       return VM_FAULT_OOM;
29089 +       }
29090 +#endif
29091 +
29092         pgd = pgd_offset(mm, address);
29093         pud = pud_alloc(mm, pgd, address);
29094         if (!pud)
29095 diff -urNp linux-2.6.20.3/mm/mempolicy.c linux-2.6.20.3/mm/mempolicy.c
29096 --- linux-2.6.20.3/mm/mempolicy.c       2007-03-13 14:27:08.000000000 -0400
29097 +++ linux-2.6.20.3/mm/mempolicy.c       2007-03-23 08:10:06.000000000 -0400
29098 @@ -355,6 +355,12 @@ check_range(struct mm_struct *mm, unsign
29099                         if (prev && prev->vm_end < vma->vm_start)
29100                                 return ERR_PTR(-EFAULT);
29101                 }
29102 +
29103 +#ifdef CONFIG_PAX_SEGMEXEC
29104 +               if (vma->vm_flags & VM_MIRROR)
29105 +                       return ERR_PTR(-EFAULT);
29106 +#endif
29107 +
29108                 if (!is_vm_hugetlb_page(vma) &&
29109                     ((flags & MPOL_MF_STRICT) ||
29110                      ((flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) &&
29111 diff -urNp linux-2.6.20.3/mm/mlock.c linux-2.6.20.3/mm/mlock.c
29112 --- linux-2.6.20.3/mm/mlock.c   2007-03-13 14:27:08.000000000 -0400
29113 +++ linux-2.6.20.3/mm/mlock.c   2007-03-23 08:11:31.000000000 -0400
29114 @@ -11,44 +11,46 @@
29115  #include <linux/mempolicy.h>
29116  #include <linux/syscalls.h>
29117  #include <linux/vs_memory.h>
29118 +#include <linux/grsecurity.h>
29119  
29120 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29121 +       unsigned long start, unsigned long end, unsigned int newflags);
29122  
29123  static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29124         unsigned long start, unsigned long end, unsigned int newflags)
29125  {
29126         struct mm_struct * mm = vma->vm_mm;
29127 -       pgoff_t pgoff;
29128         int pages;
29129 -       int ret = 0;
29130 -
29131 -       if (newflags == vma->vm_flags) {
29132 -               *prev = vma;
29133 -               goto out;
29134 -       }
29135 -
29136 -       pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
29137 -       *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
29138 -                         vma->vm_file, pgoff, vma_policy(vma));
29139 -       if (*prev) {
29140 -               vma = *prev;
29141 -               goto success;
29142 -       }
29143 +       int ret;
29144  
29145 -       *prev = vma;
29146 +#ifdef CONFIG_PAX_SEGMEXEC
29147 +       struct vm_area_struct * vma_m = NULL, *prev_m;
29148 +       unsigned long start_m = 0UL, end_m = 0UL, newflags_m = 0UL;
29149 +
29150 +       if (vma->vm_flags & VM_MIRROR) {
29151 +               start_m = vma->vm_start + vma->vm_mirror;
29152 +               vma_m = find_vma_prev(mm, start_m, &prev_m);
29153 +               if (!vma_m || vma_m->vm_start != start_m || !(vma_m->vm_flags & VM_MIRROR)) {
29154 +                       printk("PAX: VMMIRROR: mlock bug in %s, %08lx\n", current->comm, vma->vm_start);
29155 +                       return -ENOMEM;
29156 +               }
29157  
29158 -       if (start != vma->vm_start) {
29159 -               ret = split_vma(mm, vma, start, 1);
29160 +               start_m = start + vma->vm_mirror;
29161 +               end_m = end + vma->vm_mirror;
29162 +               if (newflags & VM_LOCKED)
29163 +                       newflags_m = vma_m->vm_flags | VM_LOCKED;
29164 +               else
29165 +                       newflags_m = vma_m->vm_flags & ~VM_LOCKED;
29166 +               ret = __mlock_fixup(vma_m, &prev_m, start_m, end_m, newflags_m);
29167                 if (ret)
29168 -                       goto out;
29169 +                       return ret;
29170         }
29171 +#endif
29172  
29173 -       if (end != vma->vm_end) {
29174 -               ret = split_vma(mm, vma, end, 0);
29175 -               if (ret)
29176 -                       goto out;
29177 -       }
29178 +       ret = __mlock_fixup(vma, prev, start, end, newflags);
29179 +       if (ret)
29180 +               return ret;
29181  
29182 -success:
29183         /*
29184          * vm_flags is protected by the mmap_sem held in write mode.
29185          * It's okay if try_to_unmap_one unmaps a page just after we
29186 @@ -56,6 +58,11 @@ success:
29187          */
29188         vma->vm_flags = newflags;
29189  
29190 +#ifdef CONFIG_PAX_SEGMEXEC
29191 +       if (vma->vm_flags & VM_MIRROR)
29192 +               vma_m->vm_flags = newflags_m;
29193 +#endif
29194 +
29195         /*
29196          * Keep track of amount of locked VM.
29197          */
29198 @@ -66,6 +73,48 @@ success:
29199         }
29200  
29201         vx_vmlocked_sub(mm, pages);
29202 +
29203 +#ifdef CONFIG_PAX_SEGMEXEC
29204 +       if (vma->vm_flags & VM_MIRROR)
29205 +               mm->locked_vm -= pages;
29206 +#endif
29207 +
29208 +       if (ret == -ENOMEM)
29209 +               ret = -EAGAIN;
29210 +       return ret;
29211 +}
29212 +
29213 +static int __mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev,
29214 +       unsigned long start, unsigned long end, unsigned int newflags)
29215 +{
29216 +       struct mm_struct * mm = vma->vm_mm;
29217 +       pgoff_t pgoff;
29218 +       int ret = 0;
29219 +
29220 +       if (newflags == vma->vm_flags) {
29221 +               *prev = vma;
29222 +               goto out;
29223 +       }
29224 +
29225 +       pgoff = vma->vm_pgoff + ((start - vma->vm_start) >> PAGE_SHIFT);
29226 +       *prev = vma_merge(mm, *prev, start, end, newflags, vma->anon_vma,
29227 +                         vma->vm_file, pgoff, vma_policy(vma));
29228 +       if (*prev) {
29229 +               vma = *prev;
29230 +               goto out;
29231 +       }
29232 +
29233 +       *prev = vma;
29234 +
29235 +       if (start != vma->vm_start) {
29236 +               ret = split_vma(mm, vma, start, 1);
29237 +               if (ret)
29238 +                       goto out;
29239 +       }
29240 +
29241 +       if (end != vma->vm_end)
29242 +               ret = split_vma(mm, vma, end, 0);
29243 +
29244  out:
29245         if (ret == -ENOMEM)
29246                 ret = -EAGAIN;
29247 @@ -85,6 +134,17 @@ static int do_mlock(unsigned long start,
29248                 return -EINVAL;
29249         if (end == start)
29250                 return 0;
29251 +
29252 +#ifdef CONFIG_PAX_SEGMEXEC
29253 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
29254 +               if (end > SEGMEXEC_TASK_SIZE)
29255 +                       return -EINVAL;
29256 +       } else
29257 +#endif
29258 +
29259 +       if (end > TASK_SIZE)
29260 +               return -EINVAL;
29261 +
29262         vma = find_vma_prev(current->mm, start, &prev);
29263         if (!vma || vma->vm_start > start)
29264                 return -ENOMEM;
29265 @@ -141,6 +201,7 @@ asmlinkage long sys_mlock(unsigned long 
29266         lock_limit >>= PAGE_SHIFT;
29267  
29268         /* check against resource limits */
29269 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
29270         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
29271                 error = do_mlock(start, len, 1);
29272  out:
29273 @@ -173,6 +234,16 @@ static int do_mlockall(int flags)
29274         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
29275                 unsigned int newflags;
29276  
29277 +#ifdef CONFIG_PAX_SEGMEXEC
29278 +               if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
29279 +                       if (vma->vm_end > SEGMEXEC_TASK_SIZE)
29280 +                               break;
29281 +               } else
29282 +#endif
29283 +
29284 +               if (vma->vm_end > TASK_SIZE)
29285 +                       break;
29286 +
29287                 newflags = vma->vm_flags | VM_LOCKED;
29288                 if (!(flags & MCL_CURRENT))
29289                         newflags &= ~VM_LOCKED;
29290 @@ -202,6 +273,7 @@ asmlinkage long sys_mlockall(int flags)
29291         lock_limit >>= PAGE_SHIFT;
29292  
29293         ret = -ENOMEM;
29294 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
29295         if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
29296                 goto out;
29297         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
29298 diff -urNp linux-2.6.20.3/mm/mmap.c linux-2.6.20.3/mm/mmap.c
29299 --- linux-2.6.20.3/mm/mmap.c    2007-03-13 14:27:08.000000000 -0400
29300 +++ linux-2.6.20.3/mm/mmap.c    2007-03-23 08:11:31.000000000 -0400
29301 @@ -25,6 +25,7 @@
29302  #include <linux/mount.h>
29303  #include <linux/mempolicy.h>
29304  #include <linux/rmap.h>
29305 +#include <linux/grsecurity.h>
29306  
29307  #include <asm/uaccess.h>
29308  #include <asm/cacheflush.h>
29309 @@ -251,6 +252,7 @@ asmlinkage unsigned long sys_brk(unsigne
29310          * not page aligned -Ram Gupta
29311          */
29312         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
29313 +       gr_learn_resource(current, RLIMIT_DATA, brk - mm->start_data, 1);
29314         if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
29315                 goto out;
29316  
29317 @@ -639,11 +641,17 @@ again:                    remove_next = 1 + (end > next->
29318   * If the vma has a ->close operation then the driver probably needs to release
29319   * per-vma resources, so we don't attempt to merge those.
29320   */
29321 +#ifdef CONFIG_PAX_SEGMEXEC
29322 +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP | VM_MIRROR)
29323 +#else
29324  #define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP)
29325 +#endif
29326  
29327  static inline int is_mergeable_vma(struct vm_area_struct *vma,
29328                         struct file *file, unsigned long vm_flags)
29329  {
29330 +       if ((vma->vm_flags | vm_flags) & VM_SPECIAL)
29331 +               return 0;
29332         if (vma->vm_flags != vm_flags)
29333                 return 0;
29334         if (vma->vm_file != file)
29335 @@ -868,14 +876,11 @@ none:
29336  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
29337                                                 struct file *file, long pages)
29338  {
29339 -       const unsigned long stack_flags
29340 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
29341 -
29342         if (file) {
29343                 mm->shared_vm += pages;
29344                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
29345                         mm->exec_vm += pages;
29346 -       } else if (flags & stack_flags)
29347 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
29348                 mm->stack_vm += pages;
29349         if (flags & (VM_RESERVED|VM_IO))
29350                 mm->reserved_vm += pages;
29351 @@ -886,10 +891,55 @@ void vm_stat_account(struct mm_struct *m
29352   * The caller must hold down_write(current->mm->mmap_sem).
29353   */
29354  
29355 +#ifdef CONFIG_PAX_SEGMEXEC
29356 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
29357 +                       unsigned long len, unsigned long prot,
29358 +                       unsigned long flags, unsigned long pgoff);
29359 +
29360  unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
29361                         unsigned long len, unsigned long prot,
29362                         unsigned long flags, unsigned long pgoff)
29363  {
29364 +       unsigned long ret = -EINVAL;
29365 +
29366 +       if (flags & MAP_MIRROR)
29367 +               return ret;
29368 +
29369 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) &&
29370 +           (len > SEGMEXEC_TASK_SIZE || (addr > SEGMEXEC_TASK_SIZE-len)))
29371 +               return ret;
29372 +
29373 +       ret = __do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
29374 +
29375 +       if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && ret < TASK_SIZE && ((flags & MAP_TYPE) == MAP_PRIVATE)
29376 +
29377 +#ifdef CONFIG_PAX_MPROTECT
29378 +           && (!(current->mm->pax_flags & MF_PAX_MPROTECT) || ((prot & PROT_EXEC) && file && !(prot & PROT_WRITE)))
29379 +#endif
29380 +
29381 +          )
29382 +       {
29383 +               unsigned long ret_m;
29384 +               prot = prot & PROT_EXEC ? prot & ~PROT_WRITE : PROT_NONE;
29385 +               ret_m = __do_mmap_pgoff(NULL, ret + SEGMEXEC_TASK_SIZE, 0UL, prot, flags | MAP_MIRROR | MAP_FIXED, ret);
29386 +               if (ret_m >= TASK_SIZE) {
29387 +                       do_munmap(current->mm, ret, len);
29388 +                       ret = ret_m;
29389 +               }
29390 +       }
29391 +
29392 +       return ret;
29393 +}
29394 +
29395 +static unsigned long __do_mmap_pgoff(struct file * file, unsigned long addr,
29396 +                       unsigned long len, unsigned long prot,
29397 +                       unsigned long flags, unsigned long pgoff)
29398 +#else
29399 +unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
29400 +                       unsigned long len, unsigned long prot,
29401 +                       unsigned long flags, unsigned long pgoff)
29402 +#endif
29403 +{
29404         struct mm_struct * mm = current->mm;
29405         struct vm_area_struct * vma, * prev;
29406         struct inode *inode;
29407 @@ -900,13 +950,35 @@ unsigned long do_mmap_pgoff(struct file 
29408         int accountable = 1;
29409         unsigned long charged = 0, reqprot = prot;
29410  
29411 +#ifdef CONFIG_PAX_SEGMEXEC
29412 +       struct vm_area_struct * vma_m = NULL;
29413 +
29414 +       if (flags & MAP_MIRROR) {
29415 +               /* PaX: sanity checks, to be removed when proved to be stable */
29416 +               if (file || len || ((flags & MAP_TYPE) != MAP_PRIVATE))
29417 +                       return -EINVAL;
29418 +
29419 +               vma_m = find_vma(mm, pgoff);
29420 +
29421 +               if (!vma_m || is_vm_hugetlb_page(vma_m) ||
29422 +                   vma_m->vm_start != pgoff ||
29423 +                   (vma_m->vm_flags & VM_SPECIAL) ||
29424 +                   (prot & PROT_WRITE))
29425 +                       return -EINVAL;
29426 +
29427 +               file = vma_m->vm_file;
29428 +               pgoff = vma_m->vm_pgoff;
29429 +               len = vma_m->vm_end - vma_m->vm_start;
29430 +       }
29431 +#endif
29432 +
29433         /*
29434          * Does the application expect PROT_READ to imply PROT_EXEC?
29435          *
29436          * (the exception is when the underlying filesystem is noexec
29437          *  mounted, in which case we dont add PROT_EXEC.)
29438          */
29439 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
29440 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
29441                 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
29442                         prot |= PROT_EXEC;
29443  
29444 @@ -933,7 +1005,7 @@ unsigned long do_mmap_pgoff(struct file 
29445         /* Obtain the address to map to. we verify (or select) it and ensure
29446          * that it represents a valid section of the address space.
29447          */
29448 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
29449 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
29450         if (addr & ~PAGE_MASK)
29451                 return addr;
29452  
29453 @@ -944,6 +1016,21 @@ unsigned long do_mmap_pgoff(struct file 
29454         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
29455                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
29456  
29457 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29458 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29459 +
29460 +#ifdef CONFIG_PAX_MPROTECT
29461 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
29462 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
29463 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
29464 +                       else
29465 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
29466 +               }
29467 +#endif
29468 +
29469 +       }
29470 +#endif
29471 +
29472         if (flags & MAP_LOCKED) {
29473                 if (!can_do_mlock())
29474                         return -EPERM;
29475 @@ -956,6 +1043,7 @@ unsigned long do_mmap_pgoff(struct file 
29476                 locked += mm->locked_vm;
29477                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
29478                 lock_limit >>= PAGE_SHIFT;
29479 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
29480                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29481                         return -EAGAIN;
29482         }
29483 @@ -1013,6 +1101,11 @@ unsigned long do_mmap_pgoff(struct file 
29484                         /*
29485                          * Set pgoff according to addr for anon_vma.
29486                          */
29487 +
29488 +#ifdef CONFIG_PAX_SEGMEXEC
29489 +                       if (!(flags & MAP_MIRROR))
29490 +#endif
29491 +
29492                         pgoff = addr >> PAGE_SHIFT;
29493                         break;
29494                 default:
29495 @@ -1024,14 +1117,17 @@ unsigned long do_mmap_pgoff(struct file 
29496         if (error)
29497                 return error;
29498                 
29499 +       if (!gr_acl_handle_mmap(file, prot))
29500 +               return -EACCES;
29501 +
29502         /* Clear old maps */
29503         error = -ENOMEM;
29504 -munmap_back:
29505         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29506         if (vma && vma->vm_start < addr + len) {
29507                 if (do_munmap(mm, addr, len))
29508                         return -ENOMEM;
29509 -               goto munmap_back;
29510 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29511 +               BUG_ON(vma && vma->vm_start < addr + len);
29512         }
29513  
29514         /* Check against address space limit. */
29515 @@ -1079,6 +1175,13 @@ munmap_back:
29516         vma->vm_start = addr;
29517         vma->vm_end = addr + len;
29518         vma->vm_flags = vm_flags;
29519 +
29520 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
29521 +       if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
29522 +               vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29523 +       else
29524 +#endif
29525 +
29526         vma->vm_page_prot = protection_map[vm_flags &
29527                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29528         vma->vm_pgoff = pgoff;
29529 @@ -1104,6 +1207,14 @@ munmap_back:
29530                         goto free_vma;
29531         }
29532  
29533 +#ifdef CONFIG_PAX_SEGMEXEC
29534 +       if (flags & MAP_MIRROR) {
29535 +               vma_m->vm_flags |= VM_MIRROR;
29536 +               vma_m->vm_mirror = vma->vm_start - vma_m->vm_start;
29537 +               vma->vm_mirror = vma_m->vm_start - vma->vm_start;
29538 +       }
29539 +#endif
29540 +
29541         /* We set VM_ACCOUNT in a shared mapping's vm_flags, to inform
29542          * shmem_zero_setup (perhaps called through /dev/zero's ->mmap)
29543          * that memory reservation must be checked; but that reservation
29544 @@ -1121,9 +1232,17 @@ munmap_back:
29545         pgoff = vma->vm_pgoff;
29546         vm_flags = vma->vm_flags;
29547  
29548 -       if (vma_wants_writenotify(vma))
29549 +       if (vma_wants_writenotify(vma)) {
29550 +
29551 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
29552 +               if ((file || !(mm->pax_flags & MF_PAX_PAGEEXEC)) && (vm_flags & (VM_READ|VM_WRITE)))
29553 +                       vma->vm_page_prot = protection_map[(vm_flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC)];
29554 +               else
29555 +#endif
29556 +
29557                 vma->vm_page_prot =
29558                         protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC)];
29559 +       }
29560  
29561         if (!file || !vma_merge(mm, prev, addr, vma->vm_end,
29562                         vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
29563 @@ -1143,6 +1262,7 @@ munmap_back:
29564  out:   
29565         vx_vmpages_add(mm, len >> PAGE_SHIFT);
29566         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
29567 +       track_exec_limit(mm, addr, addr + len, vm_flags);
29568         if (vm_flags & VM_LOCKED) {
29569                 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29570                 make_pages_present(addr, addr + len);
29571 @@ -1197,6 +1317,10 @@ arch_get_unmapped_area(struct file *filp
29572         if (len > TASK_SIZE)
29573                 return -ENOMEM;
29574  
29575 +#ifdef CONFIG_PAX_RANDMMAP
29576 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
29577 +#endif
29578 +
29579         if (addr) {
29580                 addr = PAGE_ALIGN(addr);
29581                 vma = find_vma(mm, addr);
29582 @@ -1207,7 +1331,7 @@ arch_get_unmapped_area(struct file *filp
29583         if (len > mm->cached_hole_size) {
29584                 start_addr = addr = mm->free_area_cache;
29585         } else {
29586 -               start_addr = addr = TASK_UNMAPPED_BASE;
29587 +               start_addr = addr = mm->mmap_base;
29588                 mm->cached_hole_size = 0;
29589         }
29590  
29591 @@ -1219,9 +1343,8 @@ full_search:
29592                          * Start a new search - just in case we missed
29593                          * some holes.
29594                          */
29595 -                       if (start_addr != TASK_UNMAPPED_BASE) {
29596 -                               addr = TASK_UNMAPPED_BASE;
29597 -                               start_addr = addr;
29598 +                       if (start_addr != mm->mmap_base) {
29599 +                               start_addr = addr = mm->mmap_base;
29600                                 mm->cached_hole_size = 0;
29601                                 goto full_search;
29602                         }
29603 @@ -1246,7 +1369,7 @@ void arch_unmap_area(struct mm_struct *m
29604         /*
29605          * Is this a new hole at the lowest possible address?
29606          */
29607 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
29608 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
29609                 mm->free_area_cache = addr;
29610                 mm->cached_hole_size = ~0UL;
29611         }
29612 @@ -1264,12 +1387,16 @@ arch_get_unmapped_area_topdown(struct fi
29613  {
29614         struct vm_area_struct *vma;
29615         struct mm_struct *mm = current->mm;
29616 -       unsigned long addr = addr0;
29617 +       unsigned long base = mm->mmap_base, addr = addr0;
29618  
29619         /* requested length too big for entire address space */
29620         if (len > TASK_SIZE)
29621                 return -ENOMEM;
29622  
29623 +#ifdef CONFIG_PAX_RANDMMAP
29624 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
29625 +#endif
29626 +
29627         /* requesting a specific address */
29628         if (addr) {
29629                 addr = PAGE_ALIGN(addr);
29630 @@ -1327,13 +1454,21 @@ bottomup:
29631          * can happen with large stack limits and large mmap()
29632          * allocations.
29633          */
29634 +       mm->mmap_base = TASK_UNMAPPED_BASE;
29635 +
29636 +#ifdef CONFIG_PAX_RANDMMAP
29637 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
29638 +               mm->mmap_base += mm->delta_mmap;
29639 +#endif
29640 +
29641 +       mm->free_area_cache = mm->mmap_base;
29642         mm->cached_hole_size = ~0UL;
29643 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
29644         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
29645         /*
29646          * Restore the topdown base:
29647          */
29648 -       mm->free_area_cache = mm->mmap_base;
29649 +       mm->mmap_base = base;
29650 +       mm->free_area_cache = base;
29651         mm->cached_hole_size = ~0UL;
29652  
29653         return addr;
29654 @@ -1349,8 +1484,10 @@ void arch_unmap_area_topdown(struct mm_s
29655                 mm->free_area_cache = addr;
29656  
29657         /* dont allow allocations above current base */
29658 -       if (mm->free_area_cache > mm->mmap_base)
29659 +       if (mm->free_area_cache > mm->mmap_base) {
29660                 mm->free_area_cache = mm->mmap_base;
29661 +               mm->cached_hole_size = ~0UL;
29662 +       }
29663  }
29664  
29665  unsigned long
29666 @@ -1484,6 +1621,7 @@ static int acct_stack_growth(struct vm_a
29667                 return -ENOMEM;
29668  
29669         /* Stack limit test */
29670 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
29671         if (size > rlim[RLIMIT_STACK].rlim_cur)
29672                 return -ENOMEM;
29673  
29674 @@ -1493,6 +1631,7 @@ static int acct_stack_growth(struct vm_a
29675                 unsigned long limit;
29676                 locked = mm->locked_vm + grow;
29677                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
29678 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
29679                 if (locked > limit && !capable(CAP_IPC_LOCK))
29680                         return -ENOMEM;
29681         }
29682 @@ -1571,23 +1710,6 @@ int expand_stack(struct vm_area_struct *
29683  {
29684         return expand_upwards(vma, address);
29685  }
29686 -
29687 -struct vm_area_struct *
29688 -find_extend_vma(struct mm_struct *mm, unsigned long addr)
29689 -{
29690 -       struct vm_area_struct *vma, *prev;
29691 -
29692 -       addr &= PAGE_MASK;
29693 -       vma = find_vma_prev(mm, addr, &prev);
29694 -       if (vma && (vma->vm_start <= addr))
29695 -               return vma;
29696 -       if (!prev || expand_stack(prev, addr))
29697 -               return NULL;
29698 -       if (prev->vm_flags & VM_LOCKED) {
29699 -               make_pages_present(addr, prev->vm_end);
29700 -       }
29701 -       return prev;
29702 -}
29703  #else
29704  /*
29705   * vma is the first one with address < vma->vm_start.  Have to extend vma.
29706 @@ -1616,41 +1738,54 @@ int expand_stack(struct vm_area_struct *
29707         if (address < vma->vm_start) {
29708                 unsigned long size, grow;
29709  
29710 +#ifdef CONFIG_PAX_SEGMEXEC
29711 +               struct vm_area_struct *vma_m = NULL;
29712 +               unsigned long address_m = 0UL;
29713 +
29714 +               if (vma->vm_flags & VM_MIRROR) {
29715 +                       address_m = vma->vm_start + vma->vm_mirror;
29716 +                       vma_m = find_vma(vma->vm_mm, address_m);
29717 +                       if (!vma_m || vma_m->vm_start != address_m ||
29718 +                           !(vma_m->vm_flags & VM_MIRROR) ||
29719 +                           vma->vm_end - vma->vm_start !=
29720 +                           vma_m->vm_end - vma_m->vm_start ||
29721 +                           vma->anon_vma != vma_m->anon_vma) {
29722 +                               printk(KERN_ERR "PAX: VMMIRROR: expand bug, %08lx, %08lx, %08lx, %08lx, %08lx\n",
29723 +                                      address, vma->vm_start, vma_m->vm_start, vma->vm_end, vma_m->vm_end);
29724 +                               anon_vma_unlock(vma);
29725 +                               return -EFAULT;
29726 +                       }
29727 +                       address_m = address + vma->vm_mirror;
29728 +               }
29729 +#endif
29730 +
29731                 size = vma->vm_end - address;
29732                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
29733  
29734 +#ifdef CONFIG_PAX_SEGMEXEC
29735 +               if (vma_m)
29736 +                       error = acct_stack_growth(vma, size, 2*grow);
29737 +               else
29738 +#endif
29739 +
29740                 error = acct_stack_growth(vma, size, grow);
29741                 if (!error) {
29742                         vma->vm_start = address;
29743                         vma->vm_pgoff -= grow;
29744 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
29745 +
29746 +#ifdef CONFIG_PAX_SEGMEXEC
29747 +                       if (vma_m) {
29748 +                               vma_m->vm_start = address_m;
29749 +                               vma_m->vm_pgoff -= grow;
29750 +                       }
29751 +#endif
29752 +
29753                 }
29754         }
29755         anon_vma_unlock(vma);
29756         return error;
29757  }
29758 -
29759 -struct vm_area_struct *
29760 -find_extend_vma(struct mm_struct * mm, unsigned long addr)
29761 -{
29762 -       struct vm_area_struct * vma;
29763 -       unsigned long start;
29764 -
29765 -       addr &= PAGE_MASK;
29766 -       vma = find_vma(mm,addr);
29767 -       if (!vma)
29768 -               return NULL;
29769 -       if (vma->vm_start <= addr)
29770 -               return vma;
29771 -       if (!(vma->vm_flags & VM_GROWSDOWN))
29772 -               return NULL;
29773 -       start = vma->vm_start;
29774 -       if (expand_stack(vma, addr))
29775 -               return NULL;
29776 -       if (vma->vm_flags & VM_LOCKED) {
29777 -               make_pages_present(addr, start);
29778 -       }
29779 -       return vma;
29780 -}
29781  #endif
29782  
29783  /*
29784 @@ -1784,8 +1919,25 @@ int split_vma(struct mm_struct * mm, str
29785   * work.  This now handles partial unmappings.
29786   * Jeremy Fitzhardinge <jeremy@goop.org>
29787   */
29788 +#ifdef CONFIG_PAX_SEGMEXEC
29789 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len);
29790 +
29791  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
29792  {
29793 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
29794 +               int ret = __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
29795 +               if (ret)
29796 +                       return ret;
29797 +       }
29798 +
29799 +       return __do_munmap(mm, start, len);
29800 +}
29801 +
29802 +static int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
29803 +#else
29804 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
29805 +#endif
29806 +{
29807         unsigned long end;
29808         struct vm_area_struct *vma, *prev, *last;
29809  
29810 @@ -1838,6 +1990,8 @@ int do_munmap(struct mm_struct *mm, unsi
29811         /* Fix up all other VM information */
29812         remove_vma_list(mm, vma);
29813  
29814 +       track_exec_limit(mm, start, end, 0UL);
29815 +
29816         return 0;
29817  }
29818  
29819 @@ -1850,6 +2004,12 @@ asmlinkage long sys_munmap(unsigned long
29820  
29821         profile_munmap(addr);
29822  
29823 +#ifdef CONFIG_PAX_SEGMEXEC
29824 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
29825 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
29826 +               return -EINVAL;
29827 +#endif
29828 +
29829         down_write(&mm->mmap_sem);
29830         ret = do_munmap(mm, addr, len);
29831         up_write(&mm->mmap_sem);
29832 @@ -1871,11 +2031,35 @@ static inline void verify_mm_writelocked
29833   *  anonymous maps.  eventually we may be able to do some
29834   *  brk-specific accounting here.
29835   */
29836 +#ifdef CONFIG_PAX_SEGMEXEC
29837 +static unsigned long __do_brk(unsigned long addr, unsigned long len);
29838 +
29839 +unsigned long do_brk(unsigned long addr, unsigned long len)
29840 +{
29841 +       unsigned long ret;
29842 +
29843 +       ret = __do_brk(addr, len);
29844 +       if (ret == addr && (current->mm->pax_flags & (MF_PAX_SEGMEXEC | MF_PAX_MPROTECT)) == MF_PAX_SEGMEXEC) {
29845 +               unsigned long ret_m;
29846 +
29847 +               ret_m = __do_mmap_pgoff(NULL, addr + SEGMEXEC_TASK_SIZE, 0UL, PROT_NONE, MAP_PRIVATE | MAP_FIXED | MAP_MIRROR, addr);
29848 +               if (ret_m > TASK_SIZE) {
29849 +                       do_munmap(current->mm, addr, len);
29850 +                       ret = ret_m;
29851 +               }
29852 +       }
29853 +
29854 +       return ret;
29855 +}
29856 +
29857 +static unsigned long __do_brk(unsigned long addr, unsigned long len)
29858 +#else
29859  unsigned long do_brk(unsigned long addr, unsigned long len)
29860 +#endif
29861  {
29862         struct mm_struct * mm = current->mm;
29863         struct vm_area_struct * vma, * prev;
29864 -       unsigned long flags;
29865 +       unsigned long flags, task_size = TASK_SIZE;
29866         struct rb_node ** rb_link, * rb_parent;
29867         pgoff_t pgoff = addr >> PAGE_SHIFT;
29868         int error;
29869 @@ -1884,7 +2068,12 @@ unsigned long do_brk(unsigned long addr,
29870         if (!len)
29871                 return addr;
29872  
29873 -       if ((addr + len) > TASK_SIZE || (addr + len) < addr)
29874 +#ifdef CONFIG_PAX_SEGMEXEC
29875 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
29876 +               task_size = SEGMEXEC_TASK_SIZE;
29877 +#endif
29878 +
29879 +       if ((addr + len) > task_size || (addr + len) < addr)
29880                 return -EINVAL;
29881  
29882         if (is_hugepage_only_range(mm, addr, len))
29883 @@ -1892,6 +2081,18 @@ unsigned long do_brk(unsigned long addr,
29884  
29885         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
29886  
29887 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
29888 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
29889 +               flags &= ~VM_EXEC;
29890 +
29891 +#ifdef CONFIG_PAX_MPROTECT
29892 +               if (mm->pax_flags & MF_PAX_MPROTECT)
29893 +                       flags &= ~VM_MAYEXEC;
29894 +#endif
29895 +
29896 +       }
29897 +#endif
29898 +
29899         error = arch_mmap_check(addr, len, flags);
29900         if (error)
29901                 return error;
29902 @@ -1905,6 +2106,7 @@ unsigned long do_brk(unsigned long addr,
29903                 locked += mm->locked_vm;
29904                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
29905                 lock_limit >>= PAGE_SHIFT;
29906 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
29907                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
29908                         return -EAGAIN;
29909                 if (!vx_vmlocked_avail(mm, len >> PAGE_SHIFT))
29910 @@ -1920,12 +2122,12 @@ unsigned long do_brk(unsigned long addr,
29911         /*
29912          * Clear old maps.  this also does some error checking for us
29913          */
29914 - munmap_back:
29915         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29916         if (vma && vma->vm_start < addr + len) {
29917                 if (do_munmap(mm, addr, len))
29918                         return -ENOMEM;
29919 -               goto munmap_back;
29920 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
29921 +               BUG_ON(vma && vma->vm_start < addr + len);
29922         }
29923  
29924         /* Check against address space limits *after* clearing old maps... */
29925 @@ -1958,6 +2160,13 @@ unsigned long do_brk(unsigned long addr,
29926         vma->vm_end = addr + len;
29927         vma->vm_pgoff = pgoff;
29928         vma->vm_flags = flags;
29929 +
29930 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
29931 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
29932 +               vma->vm_page_prot = protection_map[(flags | VM_EXEC) & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29933 +       else
29934 +#endif
29935 +
29936         vma->vm_page_prot = protection_map[flags &
29937                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
29938         vma_link(mm, vma, prev, rb_link, rb_parent);
29939 @@ -1967,6 +2176,7 @@ out:
29940                 vx_vmlocked_add(mm, len >> PAGE_SHIFT);
29941                 make_pages_present(addr, addr + len);
29942         }
29943 +       track_exec_limit(mm, addr, addr + len, flags);
29944         return addr;
29945  }
29946  
29947 @@ -2105,7 +2315,7 @@ int may_expand_vm(struct mm_struct *mm, 
29948         unsigned long lim;
29949  
29950         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
29951 -
29952 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
29953         if (cur + npages > lim)
29954                 return 0;
29955         if (!vx_vmpages_avail(mm, npages))
29956 diff -urNp linux-2.6.20.3/mm/mprotect.c linux-2.6.20.3/mm/mprotect.c
29957 --- linux-2.6.20.3/mm/mprotect.c        2007-03-13 14:27:08.000000000 -0400
29958 +++ linux-2.6.20.3/mm/mprotect.c        2007-03-23 08:27:30.000000000 -0400
29959 @@ -21,10 +21,17 @@
29960  #include <linux/syscalls.h>
29961  #include <linux/swap.h>
29962  #include <linux/swapops.h>
29963 +#include <linux/grsecurity.h>
29964 +
29965 +#ifdef CONFIG_PAX_MPROTECT
29966 +#include <linux/elf.h>
29967 +#endif
29968 +
29969  #include <asm/uaccess.h>
29970  #include <asm/pgtable.h>
29971  #include <asm/cacheflush.h>
29972  #include <asm/tlbflush.h>
29973 +#include <asm/mmu_context.h>
29974  
29975  static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
29976                 unsigned long addr, unsigned long end, pgprot_t newprot,
29977 @@ -128,6 +135,94 @@ static void change_protection(struct vm_
29978         flush_tlb_range(vma, start, end);
29979  }
29980  
29981 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
29982 +/* called while holding the mmap semaphor for writing */
29983 +static inline void establish_user_cs_limit(struct mm_struct *mm, unsigned long start, unsigned long end)
29984 +{
29985 +       struct vm_area_struct *vma = find_vma(mm, start);
29986 +
29987 +       for (; vma && vma->vm_start < end; vma = vma->vm_next)
29988 +               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
29989 +
29990 +}
29991 +
29992 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
29993 +{
29994 +       unsigned long oldlimit, newlimit = 0UL;
29995 +
29996 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC))
29997 +               return;
29998 +
29999 +       spin_lock(&mm->page_table_lock);
30000 +       oldlimit = mm->context.user_cs_limit;
30001 +       if ((prot & VM_EXEC) && oldlimit < end)
30002 +               /* USER_CS limit moved up */
30003 +               newlimit = end;
30004 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
30005 +               /* USER_CS limit moved down */
30006 +               newlimit = start;
30007 +
30008 +       if (newlimit) {
30009 +               mm->context.user_cs_limit = newlimit;
30010 +
30011 +#ifdef CONFIG_SMP
30012 +               wmb();
30013 +               cpus_clear(mm->context.cpu_user_cs_mask);
30014 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
30015 +#endif
30016 +
30017 +               set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
30018 +       }
30019 +       spin_unlock(&mm->page_table_lock);
30020 +       if (newlimit == end)
30021 +               establish_user_cs_limit(mm, oldlimit, end);
30022 +}
30023 +#endif
30024 +
30025 +#ifdef CONFIG_PAX_SEGMEXEC
30026 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30027 +       unsigned long start, unsigned long end, unsigned int newflags);
30028 +
30029 +static int mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30030 +       unsigned long start, unsigned long end, unsigned int newflags)
30031 +{
30032 +       if (vma->vm_flags & VM_MIRROR) {
30033 +               struct vm_area_struct * vma_m, * prev_m;
30034 +               unsigned long start_m, end_m;
30035 +               int error;
30036 +
30037 +               start_m = vma->vm_start + vma->vm_mirror;
30038 +               vma_m = find_vma_prev(vma->vm_mm, start_m, &prev_m);
30039 +               if (vma_m && vma_m->vm_start == start_m && (vma_m->vm_flags & VM_MIRROR)) {
30040 +                       start_m = start + vma->vm_mirror;
30041 +                       end_m = end + vma->vm_mirror;
30042 +
30043 +                       if (vma_m->vm_start >= SEGMEXEC_TASK_SIZE && !(newflags & VM_EXEC))
30044 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, vma_m->vm_flags & ~(VM_READ | VM_WRITE | VM_EXEC));
30045 +                       else
30046 +                               error = __mprotect_fixup(vma_m, &prev_m, start_m, end_m, newflags);
30047 +                       if (error)
30048 +                               return error;
30049 +               } else {
30050 +                       printk("PAX: VMMIRROR: mprotect bug in %s, %08lx\n", current->comm, vma->vm_start);
30051 +                       return -ENOMEM;
30052 +               }
30053 +       }
30054 +
30055 +       return __mprotect_fixup(vma, pprev, start, end, newflags);
30056 +}
30057 +
30058 +static int __mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30059 +       unsigned long start, unsigned long end, unsigned int newflags)
30060 +{
30061 +       struct mm_struct * mm = vma->vm_mm;
30062 +       unsigned long oldflags = vma->vm_flags;
30063 +       long nrpages = (end - start) >> PAGE_SHIFT;
30064 +       unsigned long charged = 0;
30065 +       pgoff_t pgoff;
30066 +       int error;
30067 +       int dirty_accountable = 0;
30068 +#else
30069  static int
30070  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
30071         unsigned long start, unsigned long end, unsigned long newflags)
30072 @@ -144,6 +239,7 @@ mprotect_fixup(struct vm_area_struct *vm
30073                 *pprev = vma;
30074                 return 0;
30075         }
30076 +#endif
30077  
30078         /*
30079          * If we make a private mapping writable we increase our commit;
30080 @@ -193,12 +289,29 @@ success:
30081          * held in write mode.
30082          */
30083         vma->vm_flags = newflags;
30084 -       vma->vm_page_prot = protection_map[newflags &
30085 -               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
30086         if (vma_wants_writenotify(vma)) {
30087 +
30088 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
30089 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
30090 +                       vma->vm_page_prot = protection_map[(newflags | VM_EXEC) &
30091 +                               (VM_READ|VM_WRITE|VM_EXEC)];
30092 +               else
30093 +#endif
30094 +
30095                 vma->vm_page_prot = protection_map[newflags &
30096                         (VM_READ|VM_WRITE|VM_EXEC)];
30097                 dirty_accountable = 1;
30098 +       } else {
30099 +
30100 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
30101 +               if (!(mm->pax_flags & MF_PAX_PAGEEXEC) && (newflags & (VM_READ|VM_WRITE)))
30102 +                       vma->vm_page_prot = protection_map[(newflags | VM_EXEC) &
30103 +                               (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
30104 +               else
30105 +#endif
30106 +
30107 +               vma->vm_page_prot = protection_map[newflags &
30108 +                       (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
30109         }
30110  
30111         if (is_vm_hugetlb_page(vma))
30112 @@ -214,6 +327,69 @@ fail:
30113         return error;
30114  }
30115  
30116 +#ifdef CONFIG_PAX_MPROTECT
30117 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
30118 + * therefore we'll grant them VM_MAYWRITE once during their life.
30119 + *
30120 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
30121 + * basis because we want to allow the common case and not the special ones.
30122 + */
30123 +static inline void pax_handle_maywrite(struct vm_area_struct * vma, unsigned long start)
30124 +{
30125 +       struct elfhdr elf_h;
30126 +       struct elf_phdr elf_p, p_dyn;
30127 +       elf_dyn dyn;
30128 +       unsigned long i, j = 65536UL / sizeof(struct elf_phdr);
30129 +
30130 +#ifndef CONFIG_PAX_NOELFRELOCS
30131 +       if ((vma->vm_start != start) ||
30132 +           !vma->vm_file ||
30133 +           !(vma->vm_flags & VM_MAYEXEC) ||
30134 +           (vma->vm_flags & VM_MAYNOTWRITE))
30135 +#endif
30136 +
30137 +               return;
30138 +
30139 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char*)&elf_h, sizeof(elf_h)) ||
30140 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
30141 +
30142 +#ifdef CONFIG_PAX_ETEXECRELOCS
30143 +           (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC) ||
30144 +#else
30145 +           elf_h.e_type != ET_DYN ||
30146 +#endif
30147 +
30148 +           !elf_check_arch(&elf_h) ||
30149 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
30150 +           elf_h.e_phnum > j)
30151 +               return;
30152 +
30153 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
30154 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char*)&elf_p, sizeof(elf_p)))
30155 +                       return;
30156 +               if (elf_p.p_type == PT_DYNAMIC) {
30157 +                       p_dyn = elf_p;
30158 +                       j = i;
30159 +               }
30160 +       }
30161 +       if (elf_h.e_phnum <= j)
30162 +               return;
30163 +
30164 +       i = 0UL;
30165 +       do {
30166 +               if (sizeof(dyn) != kernel_read(vma->vm_file, p_dyn.p_offset + i*sizeof(dyn), (char*)&dyn, sizeof(dyn)))
30167 +                       return;
30168 +               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
30169 +                       vma->vm_flags |= VM_MAYWRITE | VM_MAYNOTWRITE;
30170 +                       gr_log_textrel(vma);
30171 +                       return;
30172 +               }
30173 +               i++;
30174 +       } while (dyn.d_tag != DT_NULL);
30175 +       return;
30176 +}
30177 +#endif
30178 +
30179  asmlinkage long
30180  sys_mprotect(unsigned long start, size_t len, unsigned long prot)
30181  {
30182 @@ -233,6 +409,17 @@ sys_mprotect(unsigned long start, size_t
30183         end = start + len;
30184         if (end <= start)
30185                 return -ENOMEM;
30186 +
30187 +#ifdef CONFIG_PAX_SEGMEXEC
30188 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
30189 +               if (end > SEGMEXEC_TASK_SIZE)
30190 +                       return -EINVAL;
30191 +       } else
30192 +#endif
30193 +
30194 +       if (end > TASK_SIZE)
30195 +               return -EINVAL;
30196 +
30197         if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC | PROT_SEM))
30198                 return -EINVAL;
30199  
30200 @@ -240,7 +427,7 @@ sys_mprotect(unsigned long start, size_t
30201         /*
30202          * Does the application expect PROT_READ to imply PROT_EXEC:
30203          */
30204 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
30205 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
30206                 prot |= PROT_EXEC;
30207  
30208         vm_flags = calc_vm_prot_bits(prot);
30209 @@ -272,6 +459,16 @@ sys_mprotect(unsigned long start, size_t
30210         if (start > vma->vm_start)
30211                 prev = vma;
30212  
30213 +#ifdef CONFIG_PAX_MPROTECT
30214 +       if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && (prot & PROT_WRITE))
30215 +               pax_handle_maywrite(vma, start);
30216 +#endif
30217 +
30218 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
30219 +               error = -EACCES;
30220 +               goto out;
30221 +       }
30222 +
30223         for (nstart = start ; ; ) {
30224                 unsigned long newflags;
30225  
30226 @@ -285,6 +482,12 @@ sys_mprotect(unsigned long start, size_t
30227                         goto out;
30228                 }
30229  
30230 +#ifdef CONFIG_PAX_MPROTECT
30231 +               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
30232 +               if ((vma->vm_mm->pax_flags & MF_PAX_MPROTECT) && !(prot & PROT_WRITE) && (vma->vm_flags & VM_MAYNOTWRITE))
30233 +                       newflags &= ~VM_MAYWRITE;
30234 +#endif
30235 +
30236                 error = security_file_mprotect(vma, reqprot, prot);
30237                 if (error)
30238                         goto out;
30239 @@ -308,6 +511,9 @@ sys_mprotect(unsigned long start, size_t
30240                         goto out;
30241                 }
30242         }
30243 +
30244 +       track_exec_limit(current->mm, start, end, vm_flags);
30245 +
30246  out:
30247         up_write(&current->mm->mmap_sem);
30248         return error;
30249 diff -urNp linux-2.6.20.3/mm/mremap.c linux-2.6.20.3/mm/mremap.c
30250 --- linux-2.6.20.3/mm/mremap.c  2007-03-13 14:27:08.000000000 -0400
30251 +++ linux-2.6.20.3/mm/mremap.c  2007-03-23 08:10:06.000000000 -0400
30252 @@ -106,6 +106,12 @@ static void move_ptes(struct vm_area_str
30253                         continue;
30254                 pte = ptep_clear_flush(vma, old_addr, old_pte);
30255                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
30256 +
30257 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30258 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_EXEC))
30259 +                       pte_exprotect(pte);
30260 +#endif
30261 +
30262                 set_pte_at(mm, new_addr, new_pte, pte);
30263         }
30264  
30265 @@ -254,6 +260,7 @@ unsigned long do_mremap(unsigned long ad
30266         struct vm_area_struct *vma;
30267         unsigned long ret = -EINVAL;
30268         unsigned long charged = 0;
30269 +       unsigned long task_size = TASK_SIZE;
30270  
30271         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
30272                 goto out;
30273 @@ -272,6 +279,15 @@ unsigned long do_mremap(unsigned long ad
30274         if (!new_len)
30275                 goto out;
30276  
30277 +#ifdef CONFIG_PAX_SEGMEXEC
30278 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
30279 +               task_size = SEGMEXEC_TASK_SIZE;
30280 +#endif
30281 +
30282 +       if (new_len > task_size || addr > task_size-new_len ||
30283 +           old_len > task_size || addr > task_size-old_len)
30284 +               goto out;
30285 +
30286         /* new_addr is only valid if MREMAP_FIXED is specified */
30287         if (flags & MREMAP_FIXED) {
30288                 if (new_addr & ~PAGE_MASK)
30289 @@ -279,16 +295,13 @@ unsigned long do_mremap(unsigned long ad
30290                 if (!(flags & MREMAP_MAYMOVE))
30291                         goto out;
30292  
30293 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
30294 +               if (new_addr > task_size - new_len)
30295                         goto out;
30296  
30297                 /* Check if the location we're moving into overlaps the
30298                  * old location at all, and fail if it does.
30299                  */
30300 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
30301 -                       goto out;
30302 -
30303 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
30304 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
30305                         goto out;
30306  
30307                 ret = do_munmap(mm, new_addr, new_len);
30308 @@ -322,6 +335,14 @@ unsigned long do_mremap(unsigned long ad
30309                 ret = -EINVAL;
30310                 goto out;
30311         }
30312 +
30313 +#ifdef CONFIG_PAX_SEGMEXEC
30314 +       if (vma->vm_flags & VM_MIRROR) {
30315 +               ret = -EINVAL;
30316 +               goto out;
30317 +       }
30318 +#endif
30319 +
30320         /* We can't remap across vm area boundaries */
30321         if (old_len > vma->vm_end - addr)
30322                 goto out;
30323 @@ -355,7 +376,7 @@ unsigned long do_mremap(unsigned long ad
30324         if (old_len == vma->vm_end - addr &&
30325             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
30326             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
30327 -               unsigned long max_addr = TASK_SIZE;
30328 +               unsigned long max_addr = task_size;
30329                 if (vma->vm_next)
30330                         max_addr = vma->vm_next->vm_start;
30331                 /* can we just expand the current mapping? */
30332 @@ -373,6 +394,7 @@ unsigned long do_mremap(unsigned long ad
30333                                                    addr + new_len);
30334                         }
30335                         ret = addr;
30336 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
30337                         goto out;
30338                 }
30339         }
30340 @@ -383,8 +405,8 @@ unsigned long do_mremap(unsigned long ad
30341          */
30342         ret = -ENOMEM;
30343         if (flags & MREMAP_MAYMOVE) {
30344 +               unsigned long map_flags = 0;
30345                 if (!(flags & MREMAP_FIXED)) {
30346 -                       unsigned long map_flags = 0;
30347                         if (vma->vm_flags & VM_MAYSHARE)
30348                                 map_flags |= MAP_SHARED;
30349  
30350 @@ -394,7 +416,12 @@ unsigned long do_mremap(unsigned long ad
30351                         if (new_addr & ~PAGE_MASK)
30352                                 goto out;
30353                 }
30354 +               map_flags = vma->vm_flags;
30355                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
30356 +               if (!(ret & ~PAGE_MASK)) {
30357 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
30358 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
30359 +               }
30360         }
30361  out:
30362         if (ret & ~PAGE_MASK)
30363 diff -urNp linux-2.6.20.3/mm/nommu.c linux-2.6.20.3/mm/nommu.c
30364 --- linux-2.6.20.3/mm/nommu.c   2007-03-13 14:27:08.000000000 -0400
30365 +++ linux-2.6.20.3/mm/nommu.c   2007-03-23 08:10:06.000000000 -0400
30366 @@ -350,15 +350,6 @@ struct vm_area_struct *find_vma(struct m
30367  EXPORT_SYMBOL(find_vma);
30368  
30369  /*
30370 - * find a VMA
30371 - * - we don't extend stack VMAs under NOMMU conditions
30372 - */
30373 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
30374 -{
30375 -       return find_vma(mm, addr);
30376 -}
30377 -
30378 -/*
30379   * look up the first VMA exactly that exactly matches addr
30380   * - should be called with mm->mmap_sem at least held readlocked
30381   */
30382 diff -urNp linux-2.6.20.3/mm/page_alloc.c linux-2.6.20.3/mm/page_alloc.c
30383 --- linux-2.6.20.3/mm/page_alloc.c      2007-03-13 14:27:08.000000000 -0400
30384 +++ linux-2.6.20.3/mm/page_alloc.c      2007-03-23 08:10:06.000000000 -0400
30385 @@ -384,7 +384,7 @@ static inline int page_is_buddy(struct p
30386  static inline void __free_one_page(struct page *page,
30387                 struct zone *zone, unsigned int order)
30388  {
30389 -       unsigned long page_idx;
30390 +       unsigned long page_idx, index;
30391         int order_size = 1 << order;
30392  
30393         if (unlikely(PageCompound(page)))
30394 @@ -395,6 +395,11 @@ static inline void __free_one_page(struc
30395         VM_BUG_ON(page_idx & (order_size - 1));
30396         VM_BUG_ON(bad_range(zone, page));
30397  
30398 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
30399 +       for (index = order_size; index; --index)
30400 +               sanitize_highpage(page + index - 1);
30401 +#endif
30402 +
30403         zone->free_pages += order_size;
30404         while (order < MAX_ORDER-1) {
30405                 unsigned long combined_idx;
30406 diff -urNp linux-2.6.20.3/mm/rmap.c linux-2.6.20.3/mm/rmap.c
30407 --- linux-2.6.20.3/mm/rmap.c    2007-03-13 14:27:08.000000000 -0400
30408 +++ linux-2.6.20.3/mm/rmap.c    2007-03-23 08:10:06.000000000 -0400
30409 @@ -100,6 +100,19 @@ int anon_vma_prepare(struct vm_area_stru
30410                         vma->anon_vma = anon_vma;
30411                         list_add_tail(&vma->anon_vma_node, &anon_vma->head);
30412                         allocated = NULL;
30413 +
30414 +#ifdef CONFIG_PAX_SEGMEXEC
30415 +                       if (vma->vm_flags & VM_MIRROR) {
30416 +                               struct vm_area_struct *vma_m;
30417 +
30418 +                               vma_m = find_vma(mm, vma->vm_start + vma->vm_mirror);
30419 +                               BUG_ON(!vma_m || vma_m->vm_start != vma->vm_start + vma->vm_mirror);
30420 +                               BUG_ON(vma_m->anon_vma || vma->vm_pgoff != vma_m->vm_pgoff);
30421 +                               vma_m->anon_vma = anon_vma;
30422 +                               __anon_vma_link(vma_m);
30423 +                       }
30424 +#endif
30425 +
30426                 }
30427                 spin_unlock(&mm->page_table_lock);
30428  
30429 diff -urNp linux-2.6.20.3/mm/shmem.c linux-2.6.20.3/mm/shmem.c
30430 --- linux-2.6.20.3/mm/shmem.c   2007-03-13 14:27:08.000000000 -0400
30431 +++ linux-2.6.20.3/mm/shmem.c   2007-03-23 08:11:31.000000000 -0400
30432 @@ -2416,7 +2416,7 @@ static struct file_system_type tmpfs_fs_
30433         .get_sb         = shmem_get_sb,
30434         .kill_sb        = kill_litter_super,
30435  };
30436 -static struct vfsmount *shm_mnt;
30437 +struct vfsmount *shm_mnt;
30438  
30439  static int __init init_tmpfs(void)
30440  {
30441 diff -urNp linux-2.6.20.3/mm/slab.c linux-2.6.20.3/mm/slab.c
30442 --- linux-2.6.20.3/mm/slab.c    2007-03-13 14:27:08.000000000 -0400
30443 +++ linux-2.6.20.3/mm/slab.c    2007-03-23 08:10:06.000000000 -0400
30444 @@ -305,7 +305,7 @@ struct kmem_list3 {
30445   * Need this for bootstrapping a per node allocator.
30446   */
30447  #define NUM_INIT_LISTS (2 * MAX_NUMNODES + 1)
30448 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
30449 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
30450  #define        CACHE_CACHE 0
30451  #define        SIZE_AC 1
30452  #define        SIZE_L3 (1 + MAX_NUMNODES)
30453 @@ -662,14 +662,14 @@ struct cache_names {
30454  static struct cache_names __initdata cache_names[] = {
30455  #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
30456  #include <linux/kmalloc_sizes.h>
30457 -       {NULL,}
30458 +       {NULL, NULL}
30459  #undef CACHE
30460  };
30461  
30462  static struct arraycache_init initarray_cache __initdata =
30463 -    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
30464 +    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
30465  static struct arraycache_init initarray_generic =
30466 -    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
30467 +    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
30468  
30469  /* internal cache of cache description objs */
30470  static struct kmem_cache cache_cache = {
30471 @@ -1694,6 +1694,11 @@ static void store_stackinfo(struct kmem_
30472  
30473                 while (!kstack_end(sptr)) {
30474                         svalue = *sptr++;
30475 +
30476 +#ifdef CONFIG_PAX_KERNEXEC
30477 +                       svalue += __KERNEL_TEXT_OFFSET;
30478 +#endif
30479 +
30480                         if (kernel_text_address(svalue)) {
30481                                 *addr++ = svalue;
30482                                 size -= sizeof(unsigned long);
30483 diff -urNp linux-2.6.20.3/mm/swap.c linux-2.6.20.3/mm/swap.c
30484 --- linux-2.6.20.3/mm/swap.c    2007-03-13 14:27:08.000000000 -0400
30485 +++ linux-2.6.20.3/mm/swap.c    2007-03-23 08:10:06.000000000 -0400
30486 @@ -174,8 +174,8 @@ EXPORT_SYMBOL(mark_page_accessed);
30487   * lru_cache_add: add a page to the page lists
30488   * @page: the page to add
30489   */
30490 -static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
30491 -static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
30492 +static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, 0, {NULL} };
30493 +static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, 0, {NULL} };
30494  
30495  void fastcall lru_cache_add(struct page *page)
30496  {
30497 diff -urNp linux-2.6.20.3/mm/thrash.c linux-2.6.20.3/mm/thrash.c
30498 --- linux-2.6.20.3/mm/thrash.c  2007-03-13 14:27:08.000000000 -0400
30499 +++ linux-2.6.20.3/mm/thrash.c  2007-03-23 08:10:06.000000000 -0400
30500 @@ -48,9 +48,8 @@ void grab_swap_token(void)
30501                 if (current_interval < current->mm->last_interval)
30502                         current->mm->token_priority++;
30503                 else {
30504 -                       current->mm->token_priority--;
30505 -                       if (unlikely(current->mm->token_priority < 0))
30506 -                               current->mm->token_priority = 0;
30507 +                       if (likely(current->mm->token_priority > 0))
30508 +                               current->mm->token_priority--;
30509                 }
30510                 /* Check if we deserve the token */
30511                 if (current->mm->token_priority >
30512 diff -urNp linux-2.6.20.3/mm/tiny-shmem.c linux-2.6.20.3/mm/tiny-shmem.c
30513 --- linux-2.6.20.3/mm/tiny-shmem.c      2007-03-13 14:27:08.000000000 -0400
30514 +++ linux-2.6.20.3/mm/tiny-shmem.c      2007-03-23 08:11:31.000000000 -0400
30515 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
30516         .kill_sb        = kill_litter_super,
30517  };
30518  
30519 -static struct vfsmount *shm_mnt;
30520 +struct vfsmount *shm_mnt;
30521  
30522  static int __init init_tmpfs(void)
30523  {
30524 diff -urNp linux-2.6.20.3/mm/vmalloc.c linux-2.6.20.3/mm/vmalloc.c
30525 --- linux-2.6.20.3/mm/vmalloc.c 2007-03-13 14:27:08.000000000 -0400
30526 +++ linux-2.6.20.3/mm/vmalloc.c 2007-03-23 08:10:06.000000000 -0400
30527 @@ -195,6 +195,8 @@ static struct vm_struct *__get_vm_area_n
30528  
30529         write_lock(&vmlist_lock);
30530         for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
30531 +               if (addr > end - size)
30532 +                       goto out;
30533                 if ((unsigned long)tmp->addr < addr) {
30534                         if((unsigned long)tmp->addr + tmp->size >= addr)
30535                                 addr = ALIGN(tmp->size + 
30536 @@ -206,8 +208,6 @@ static struct vm_struct *__get_vm_area_n
30537                 if (size + addr <= (unsigned long)tmp->addr)
30538                         goto found;
30539                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
30540 -               if (addr > end - size)
30541 -                       goto out;
30542         }
30543  
30544  found:
30545 diff -urNp linux-2.6.20.3/net/core/flow.c linux-2.6.20.3/net/core/flow.c
30546 --- linux-2.6.20.3/net/core/flow.c      2007-03-13 14:27:08.000000000 -0400
30547 +++ linux-2.6.20.3/net/core/flow.c      2007-03-23 08:10:06.000000000 -0400
30548 @@ -40,7 +40,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
30549  
30550  static u32 flow_hash_shift;
30551  #define flow_hash_size (1 << flow_hash_shift)
30552 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
30553 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
30554  
30555  #define flow_table(cpu) (per_cpu(flow_tables, cpu))
30556  
30557 @@ -53,7 +53,7 @@ struct flow_percpu_info {
30558         u32 hash_rnd;
30559         int count;
30560  } ____cacheline_aligned;
30561 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
30562 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
30563  
30564  #define flow_hash_rnd_recalc(cpu) \
30565         (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
30566 @@ -70,7 +70,7 @@ struct flow_flush_info {
30567         atomic_t cpuleft;
30568         struct completion completion;
30569  };
30570 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
30571 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
30572  
30573  #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
30574  
30575 diff -urNp linux-2.6.20.3/net/core/sock.c linux-2.6.20.3/net/core/sock.c
30576 --- linux-2.6.20.3/net/core/sock.c      2007-03-13 14:27:08.000000000 -0400
30577 +++ linux-2.6.20.3/net/core/sock.c      2007-03-23 08:10:06.000000000 -0400
30578 @@ -808,7 +808,7 @@ lenout:
30579   *
30580   * (We also register the sk_lock with the lock validator.)
30581   */
30582 -static void inline sock_lock_init(struct sock *sk)
30583 +static inline void sock_lock_init(struct sock *sk)
30584  {
30585         sock_lock_init_class_and_name(sk,
30586                         af_family_slock_key_strings[sk->sk_family],
30587 diff -urNp linux-2.6.20.3/net/dccp/ccids/ccid3.c linux-2.6.20.3/net/dccp/ccids/ccid3.c
30588 --- linux-2.6.20.3/net/dccp/ccids/ccid3.c       2007-03-13 14:27:08.000000000 -0400
30589 +++ linux-2.6.20.3/net/dccp/ccids/ccid3.c       2007-03-23 08:10:06.000000000 -0400
30590 @@ -45,7 +45,7 @@
30591  static int ccid3_debug;
30592  #define ccid3_pr_debug(format, a...)   DCCP_PR_DEBUG(ccid3_debug, format, ##a)
30593  #else
30594 -#define ccid3_pr_debug(format, a...)
30595 +#define ccid3_pr_debug(format, a...) do {} while (0)
30596  #endif
30597  
30598  static struct dccp_tx_hist *ccid3_tx_hist;
30599 @@ -784,7 +784,7 @@ static u32 ccid3_hc_rx_calc_first_li(str
30600         struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
30601         u32 x_recv, p;
30602         suseconds_t rtt, delta;
30603 -       struct timeval tstamp = { 0, };
30604 +       struct timeval tstamp = { 0, 0 };
30605         int interval = 0;
30606         int win_count = 0;
30607         int step = 0;
30608 diff -urNp linux-2.6.20.3/net/dccp/dccp.h linux-2.6.20.3/net/dccp/dccp.h
30609 --- linux-2.6.20.3/net/dccp/dccp.h      2007-03-13 14:27:08.000000000 -0400
30610 +++ linux-2.6.20.3/net/dccp/dccp.h      2007-03-23 08:10:06.000000000 -0400
30611 @@ -46,8 +46,8 @@ extern int dccp_debug;
30612  #define dccp_pr_debug(format, a...)      DCCP_PR_DEBUG(dccp_debug, format, ##a)
30613  #define dccp_pr_debug_cat(format, a...)   DCCP_PRINTK(dccp_debug, format, ##a)
30614  #else
30615 -#define dccp_pr_debug(format, a...)
30616 -#define dccp_pr_debug_cat(format, a...)
30617 +#define dccp_pr_debug(format, a...) do {} while (0)
30618 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
30619  #endif
30620  
30621  extern struct inet_hashinfo dccp_hashinfo;
30622 diff -urNp linux-2.6.20.3/net/ipv4/inet_connection_sock.c linux-2.6.20.3/net/ipv4/inet_connection_sock.c
30623 --- linux-2.6.20.3/net/ipv4/inet_connection_sock.c      2007-03-13 14:27:08.000000000 -0400
30624 +++ linux-2.6.20.3/net/ipv4/inet_connection_sock.c      2007-03-23 08:11:31.000000000 -0400
30625 @@ -15,6 +15,7 @@
30626  
30627  #include <linux/module.h>
30628  #include <linux/jhash.h>
30629 +#include <linux/grsecurity.h>
30630  
30631  #include <net/inet_connection_sock.h>
30632  #include <net/inet_hashtables.h>
30633 diff -urNp linux-2.6.20.3/net/ipv4/inet_hashtables.c linux-2.6.20.3/net/ipv4/inet_hashtables.c
30634 --- linux-2.6.20.3/net/ipv4/inet_hashtables.c   2007-03-13 14:27:08.000000000 -0400
30635 +++ linux-2.6.20.3/net/ipv4/inet_hashtables.c   2007-03-23 08:11:31.000000000 -0400
30636 @@ -18,11 +18,14 @@
30637  #include <linux/sched.h>
30638  #include <linux/slab.h>
30639  #include <linux/wait.h>
30640 +#include <linux/grsecurity.h>
30641  
30642  #include <net/inet_connection_sock.h>
30643  #include <net/inet_hashtables.h>
30644  #include <net/ip.h>
30645  
30646 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
30647 +
30648  /*
30649   * Allocate and initialize a new local port bind bucket.
30650   * The bindhash mutex for snum's hash chain must be held here.
30651 @@ -338,6 +341,8 @@ ok:
30652                 }
30653                 spin_unlock(&head->lock);
30654  
30655 +               gr_update_task_in_ip_table(current, inet_sk(sk));
30656 +
30657                 if (tw) {
30658                         inet_twsk_deschedule(tw, death_row);
30659                         inet_twsk_put(tw);
30660 diff -urNp linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c
30661 --- linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c     1969-12-31 19:00:00.000000000 -0500
30662 +++ linux-2.6.20.3/net/ipv4/netfilter/ipt_stealth.c     2007-03-23 08:11:31.000000000 -0400
30663 @@ -0,0 +1,113 @@
30664 +/* Kernel module to add stealth support.
30665 + *
30666 + * Copyright (C) 2002-2006 Brad Spengler  <spender@grsecurity.net>
30667 + *
30668 + */
30669 +
30670 +#include <linux/kernel.h>
30671 +#include <linux/module.h>
30672 +#include <linux/skbuff.h>
30673 +#include <linux/net.h>
30674 +#include <linux/sched.h>
30675 +#include <linux/inet.h>
30676 +#include <linux/stddef.h>
30677 +
30678 +#include <net/ip.h>
30679 +#include <net/sock.h>
30680 +#include <net/tcp.h>
30681 +#include <net/udp.h>
30682 +#include <net/route.h>
30683 +#include <net/inet_common.h>
30684 +
30685 +#include <linux/netfilter_ipv4/ip_tables.h>
30686 +
30687 +MODULE_LICENSE("GPL");
30688 +
30689 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
30690 +
30691 +static int
30692 +match(const struct sk_buff *skb,
30693 +      const struct net_device *in,
30694 +      const struct net_device *out,
30695 +      const struct xt_match *match,
30696 +      const void *matchinfo,
30697 +      int offset,
30698 +      unsigned int protoff,
30699 +      int *hotdrop)
30700 +{
30701 +       struct iphdr *ip = skb->nh.iph;
30702 +       struct tcphdr th;
30703 +       struct udphdr uh;
30704 +       struct sock *sk = NULL;
30705 +
30706 +       if (!ip || offset) return 0;
30707 +
30708 +       switch(ip->protocol) {
30709 +       case IPPROTO_TCP:
30710 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &th, sizeof(th)) < 0) {
30711 +                       *hotdrop = 1;
30712 +                       return 0;
30713 +               }
30714 +               if (!(th.syn && !th.ack)) return 0;
30715 +               sk = inet_lookup_listener(&tcp_hashinfo, ip->daddr, ntohs(th.dest), ((struct rtable*)skb->dst)->rt_iif);        
30716 +               break;
30717 +       case IPPROTO_UDP:
30718 +               if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &uh, sizeof(uh)) < 0) {
30719 +                       *hotdrop = 1;
30720 +                       return 0;
30721 +               }
30722 +               sk = udp_v4_lookup(ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
30723 +               break;
30724 +       default:
30725 +               return 0;
30726 +       }
30727 +
30728 +       if(!sk) // port is being listened on, match this
30729 +               return 1;
30730 +       else {
30731 +               sock_put(sk);
30732 +               return 0;
30733 +       }
30734 +}
30735 +
30736 +/* Called when user tries to insert an entry of this type. */
30737 +static int
30738 +checkentry(const char *tablename,
30739 +           const void *nip,
30740 +          const struct xt_match *match,
30741 +           void *matchinfo,
30742 +           unsigned int hook_mask)
30743 +{
30744 +       const struct ipt_ip *ip = (const struct ipt_ip *)nip;
30745 +
30746 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
30747 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
30748 +               && (hook_mask & (1 << NF_IP_LOCAL_IN)))
30749 +                       return 1;
30750 +
30751 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
30752 +
30753 +        return 0;
30754 +}
30755 +
30756 +
30757 +static struct ipt_match stealth_match = {
30758 +       .name = "stealth",
30759 +       .match = match,
30760 +       .checkentry = checkentry,
30761 +       .destroy = NULL,
30762 +       .me = THIS_MODULE
30763 +};
30764 +
30765 +static int __init init(void)
30766 +{
30767 +       return ipt_register_match(&stealth_match);
30768 +}
30769 +
30770 +static void __exit fini(void)
30771 +{
30772 +       ipt_unregister_match(&stealth_match);
30773 +}
30774 +
30775 +module_init(init);
30776 +module_exit(fini);
30777 diff -urNp linux-2.6.20.3/net/ipv4/netfilter/Kconfig linux-2.6.20.3/net/ipv4/netfilter/Kconfig
30778 --- linux-2.6.20.3/net/ipv4/netfilter/Kconfig   2007-03-13 14:27:08.000000000 -0400
30779 +++ linux-2.6.20.3/net/ipv4/netfilter/Kconfig   2007-03-23 08:11:31.000000000 -0400
30780 @@ -330,6 +330,21 @@ config IP_NF_MATCH_ADDRTYPE
30781           If you want to compile it as a module, say M here and read
30782           <file:Documentation/modules.txt>.  If unsure, say `N'.
30783  
30784 +config IP_NF_MATCH_STEALTH
30785 +       tristate "stealth match support"
30786 +       depends on IP_NF_IPTABLES
30787 +       help
30788 +         Enabling this option will drop all syn packets coming to unserved tcp
30789 +         ports as well as all packets coming to unserved udp ports.  If you
30790 +         are using your system to route any type of packets (ie. via NAT)
30791 +         you should put this module at the end of your ruleset, since it will
30792 +         drop packets that aren't going to ports that are listening on your
30793 +         machine itself, it doesn't take into account that the packet might be
30794 +         destined for someone on your internal network if you're using NAT for
30795 +         instance.
30796 +
30797 +         To compile it as a module, choose M here.  If unsure, say N.
30798 +
30799  # `filter', generic and specific targets
30800  config IP_NF_FILTER
30801         tristate "Packet filtering"
30802 diff -urNp linux-2.6.20.3/net/ipv4/netfilter/Makefile linux-2.6.20.3/net/ipv4/netfilter/Makefile
30803 --- linux-2.6.20.3/net/ipv4/netfilter/Makefile  2007-03-13 14:27:08.000000000 -0400
30804 +++ linux-2.6.20.3/net/ipv4/netfilter/Makefile  2007-03-23 08:11:31.000000000 -0400
30805 @@ -104,6 +104,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn
30806  obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
30807  obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o
30808  obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
30809 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
30810  
30811  obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o
30812  
30813 diff -urNp linux-2.6.20.3/net/ipv4/tcp_ipv4.c linux-2.6.20.3/net/ipv4/tcp_ipv4.c
30814 --- linux-2.6.20.3/net/ipv4/tcp_ipv4.c  2007-03-13 14:27:08.000000000 -0400
30815 +++ linux-2.6.20.3/net/ipv4/tcp_ipv4.c  2007-03-23 08:11:31.000000000 -0400
30816 @@ -61,6 +61,7 @@
30817  #include <linux/jhash.h>
30818  #include <linux/init.h>
30819  #include <linux/times.h>
30820 +#include <linux/grsecurity.h>
30821  
30822  #include <net/icmp.h>
30823  #include <net/inet_hashtables.h>
30824 diff -urNp linux-2.6.20.3/net/ipv4/udp.c linux-2.6.20.3/net/ipv4/udp.c
30825 --- linux-2.6.20.3/net/ipv4/udp.c       2007-03-13 14:27:08.000000000 -0400
30826 +++ linux-2.6.20.3/net/ipv4/udp.c       2007-03-23 08:11:31.000000000 -0400
30827 @@ -97,12 +97,19 @@
30828  #include <linux/skbuff.h>
30829  #include <linux/proc_fs.h>
30830  #include <linux/seq_file.h>
30831 +#include <linux/grsecurity.h>
30832  #include <net/icmp.h>
30833  #include <net/route.h>
30834  #include <net/checksum.h>
30835  #include <net/xfrm.h>
30836  #include "udp_impl.h"
30837  
30838 +extern int gr_search_udp_recvmsg(const struct sock *sk,
30839 +                                const struct sk_buff *skb);
30840 +extern int gr_search_udp_sendmsg(const struct sock *sk,
30841 +                                const struct sockaddr_in *addr);
30842 +
30843 +
30844  /*
30845   *     Snmp MIB for the UDP layer
30846   */
30847 @@ -284,6 +291,13 @@ static struct sock *__udp4_lib_lookup(__
30848         return result;
30849  }
30850  
30851 +struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
30852 +                          __be32 daddr, __be16 dport, int dif)
30853 +{
30854 +       return __udp4_lib_lookup(saddr, sport, daddr, dport, dif, udp_hash);
30855 +}
30856 +
30857 +
30858  static inline struct sock *udp_v4_mcast_next(struct sock *sk,
30859                                              __be16 loc_port, __be32 loc_addr,
30860                                              __be16 rmt_port, __be32 rmt_addr,
30861 @@ -566,9 +580,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
30862                 dport = usin->sin_port;
30863                 if (dport == 0)
30864                         return -EINVAL;
30865 +
30866 +               if (!gr_search_udp_sendmsg(sk, usin))
30867 +                       return -EPERM;
30868         } else {
30869                 if (sk->sk_state != TCP_ESTABLISHED)
30870                         return -EDESTADDRREQ;
30871 +
30872 +               if (!gr_search_udp_sendmsg(sk, NULL))
30873 +                       return -EPERM;
30874 +
30875                 daddr = inet->daddr;
30876                 dport = inet->dport;
30877                 /* Open fast path for connected socket.
30878 @@ -825,6 +846,11 @@ try_again:
30879         if (!skb)
30880                 goto out;
30881    
30882 +       if (!gr_search_udp_recvmsg(sk, skb)) {
30883 +               err = -EPERM;
30884 +               goto out_free;
30885 +       }
30886 +
30887         copied = skb->len - sizeof(struct udphdr);
30888         if (copied > len) {
30889                 copied = len;
30890 diff -urNp linux-2.6.20.3/net/ipv6/addrconf.c linux-2.6.20.3/net/ipv6/addrconf.c
30891 --- linux-2.6.20.3/net/ipv6/addrconf.c  2007-03-13 14:27:08.000000000 -0400
30892 +++ linux-2.6.20.3/net/ipv6/addrconf.c  2007-03-23 08:10:06.000000000 -0400
30893 @@ -877,7 +877,7 @@ struct ipv6_saddr_score {
30894  #define IPV6_SADDR_SCORE_LABEL         0x0020
30895  #define IPV6_SADDR_SCORE_PRIVACY       0x0040
30896  
30897 -static int inline ipv6_saddr_preferred(int type)
30898 +static inline int ipv6_saddr_preferred(int type)
30899  {
30900         if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4|
30901                     IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED))
30902 @@ -886,7 +886,7 @@ static int inline ipv6_saddr_preferred(i
30903  }
30904  
30905  /* static matching label */
30906 -static int inline ipv6_saddr_label(const struct in6_addr *addr, int type)
30907 +static inline int ipv6_saddr_label(const struct in6_addr *addr, int type)
30908  {
30909   /*
30910    *    prefix (longest match)  label
30911 @@ -3365,7 +3365,7 @@ errout:
30912                 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
30913  }
30914  
30915 -static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
30916 +static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
30917                                 __s32 *array, int bytes)
30918  {
30919         BUG_ON(bytes < (DEVCONF_MAX * 4));
30920 diff -urNp linux-2.6.20.3/net/ipv6/exthdrs.c linux-2.6.20.3/net/ipv6/exthdrs.c
30921 --- linux-2.6.20.3/net/ipv6/exthdrs.c   2007-03-13 14:27:08.000000000 -0400
30922 +++ linux-2.6.20.3/net/ipv6/exthdrs.c   2007-03-23 08:10:06.000000000 -0400
30923 @@ -691,7 +691,7 @@ static struct tlvtype_proc tlvprochopopt
30924                 .type   = IPV6_TLV_JUMBO,
30925                 .func   = ipv6_hop_jumbo,
30926         },
30927 -       { -1, }
30928 +       { -1, NULL }
30929  };
30930  
30931  int ipv6_parse_hopopts(struct sk_buff **skbp)
30932 diff -urNp linux-2.6.20.3/net/ipv6/raw.c linux-2.6.20.3/net/ipv6/raw.c
30933 --- linux-2.6.20.3/net/ipv6/raw.c       2007-03-13 14:27:08.000000000 -0400
30934 +++ linux-2.6.20.3/net/ipv6/raw.c       2007-03-23 08:10:06.000000000 -0400
30935 @@ -548,7 +548,7 @@ out:
30936         return err;
30937  }
30938  
30939 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
30940 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
30941                         struct flowi *fl, struct rt6_info *rt, 
30942                         unsigned int flags)
30943  {
30944 diff -urNp linux-2.6.20.3/net/ipv6/route.c linux-2.6.20.3/net/ipv6/route.c
30945 --- linux-2.6.20.3/net/ipv6/route.c     2007-03-13 14:27:08.000000000 -0400
30946 +++ linux-2.6.20.3/net/ipv6/route.c     2007-03-23 08:10:06.000000000 -0400
30947 @@ -308,7 +308,7 @@ static inline void rt6_probe(struct rt6_
30948  /*
30949   * Default Router Selection (RFC 2461 6.3.6)
30950   */
30951 -static int inline rt6_check_dev(struct rt6_info *rt, int oif)
30952 +static inline int rt6_check_dev(struct rt6_info *rt, int oif)
30953  {
30954         struct net_device *dev = rt->rt6i_dev;
30955         if (!oif || dev->ifindex == oif)
30956 @@ -319,7 +319,7 @@ static int inline rt6_check_dev(struct r
30957         return 0;
30958  }
30959  
30960 -static int inline rt6_check_neigh(struct rt6_info *rt)
30961 +static inline int rt6_check_neigh(struct rt6_info *rt)
30962  {
30963         struct neighbour *neigh = rt->rt6i_nexthop;
30964         int m = 0;
30965 diff -urNp linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c
30966 --- linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c      2007-03-13 14:27:08.000000000 -0400
30967 +++ linux-2.6.20.3/net/ipv6/xfrm6_tunnel.c      2007-03-23 08:10:06.000000000 -0400
30968 @@ -58,7 +58,7 @@ static struct kmem_cache *xfrm6_tunnel_s
30969  static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE];
30970  static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE];
30971  
30972 -static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
30973 +static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
30974  {
30975         unsigned h;
30976  
30977 @@ -70,7 +70,7 @@ static unsigned inline xfrm6_tunnel_spi_
30978         return h;
30979  }
30980  
30981 -static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi)
30982 +static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi)
30983  {
30984         return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE;
30985  }
30986 diff -urNp linux-2.6.20.3/net/sctp/sm_statetable.c linux-2.6.20.3/net/sctp/sm_statetable.c
30987 --- linux-2.6.20.3/net/sctp/sm_statetable.c     2007-03-13 14:27:08.000000000 -0400
30988 +++ linux-2.6.20.3/net/sctp/sm_statetable.c     2007-03-23 08:10:06.000000000 -0400
30989 @@ -960,7 +960,7 @@ static const sctp_sm_table_entry_t *sctp
30990         if (state > SCTP_STATE_MAX)
30991                 return &bug;
30992  
30993 -       if (cid >= 0 && cid <= SCTP_CID_BASE_MAX)
30994 +       if (cid <= SCTP_CID_BASE_MAX)
30995                 return &chunk_event_table[cid][state];
30996  
30997         if (sctp_prsctp_enable) {
30998 diff -urNp linux-2.6.20.3/net/sctp/socket.c linux-2.6.20.3/net/sctp/socket.c
30999 --- linux-2.6.20.3/net/sctp/socket.c    2007-03-13 14:27:08.000000000 -0400
31000 +++ linux-2.6.20.3/net/sctp/socket.c    2007-03-23 08:10:06.000000000 -0400
31001 @@ -1358,11 +1358,11 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
31002         struct sctp_chunk *chunk;
31003         union sctp_addr to;
31004         struct sockaddr *msg_name = NULL;
31005 -       struct sctp_sndrcvinfo default_sinfo = { 0 };
31006 +       struct sctp_sndrcvinfo default_sinfo;
31007         struct sctp_sndrcvinfo *sinfo;
31008         struct sctp_initmsg *sinit;
31009         sctp_assoc_t associd = 0;
31010 -       sctp_cmsgs_t cmsgs = { NULL };
31011 +       sctp_cmsgs_t cmsgs = { NULL, NULL };
31012         int err;
31013         sctp_scope_t scope;
31014         long timeo;
31015 diff -urNp linux-2.6.20.3/net/socket.c linux-2.6.20.3/net/socket.c
31016 --- linux-2.6.20.3/net/socket.c 2007-03-13 14:27:08.000000000 -0400
31017 +++ linux-2.6.20.3/net/socket.c 2007-03-23 08:11:31.000000000 -0400
31018 @@ -84,6 +84,7 @@
31019  #include <linux/kmod.h>
31020  #include <linux/audit.h>
31021  #include <linux/wireless.h>
31022 +#include <linux/in.h>
31023  
31024  #include <asm/uaccess.h>
31025  #include <asm/unistd.h>
31026 @@ -95,6 +96,21 @@
31027  #include <linux/vs_base.h>
31028  #include <linux/vs_socket.h>
31029  
31030 +extern void gr_attach_curr_ip(const struct sock *sk);
31031 +extern int gr_handle_sock_all(const int family, const int type,
31032 +                             const int protocol);
31033 +extern int gr_handle_sock_server(const struct sockaddr *sck);
31034 +extern int gr_handle_sock_server_other(const struct socket *sck);
31035 +extern int gr_handle_sock_client(const struct sockaddr *sck);
31036 +extern int gr_search_connect(const struct socket * sock,
31037 +                            const struct sockaddr_in * addr);
31038 +extern int gr_search_bind(const struct socket * sock,
31039 +                          const struct sockaddr_in * addr);
31040 +extern int gr_search_listen(const struct socket * sock);
31041 +extern int gr_search_accept(const struct socket * sock);
31042 +extern int gr_search_socket(const int domain, const int type,
31043 +                           const int protocol);
31044 +
31045  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
31046  static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
31047                          unsigned long nr_segs, loff_t pos);
31048 @@ -297,7 +313,7 @@ static int sockfs_get_sb(struct file_sys
31049                              mnt);
31050  }
31051  
31052 -static struct vfsmount *sock_mnt __read_mostly;
31053 +struct vfsmount *sock_mnt __read_mostly;
31054  
31055  static struct file_system_type sock_fs_type = {
31056         .name =         "sockfs",
31057 @@ -1181,6 +1197,16 @@ asmlinkage long sys_socket(int family, i
31058         int retval;
31059         struct socket *sock;
31060  
31061 +       if(!gr_search_socket(family, type, protocol)) {
31062 +               retval = -EACCES;
31063 +               goto out;
31064 +       }
31065 +
31066 +       if (gr_handle_sock_all(family, type, protocol)) {
31067 +               retval = -EACCES;
31068 +               goto out;
31069 +       }
31070 +
31071         retval = sock_create(family, type, protocol, &sock);
31072         if (retval < 0)
31073                 goto out;
31074 @@ -1276,12 +1302,20 @@ asmlinkage long sys_bind(int fd, struct 
31075  {
31076         struct socket *sock;
31077         char address[MAX_SOCK_ADDR];
31078 +       struct sockaddr *sck;
31079         int err, fput_needed;
31080  
31081         sock = sockfd_lookup_light(fd, &err, &fput_needed);
31082         if(sock) {
31083                 err = move_addr_to_kernel(umyaddr, addrlen, address);
31084                 if (err >= 0) {
31085 +                       sck = (struct sockaddr *)address;
31086 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)sck) ||
31087 +                           gr_handle_sock_server(sck)) {
31088 +                               err = -EACCES;
31089 +                               goto error;
31090 +                       }
31091 +
31092                         err = security_socket_bind(sock,
31093                                                    (struct sockaddr *)address,
31094                                                    addrlen);
31095 @@ -1290,6 +1324,7 @@ asmlinkage long sys_bind(int fd, struct 
31096                                                       (struct sockaddr *)
31097                                                       address, addrlen);
31098                 }
31099 +error:
31100                 fput_light(sock->file, fput_needed);
31101         }
31102         return err;
31103 @@ -1313,10 +1348,17 @@ asmlinkage long sys_listen(int fd, int b
31104                 if ((unsigned)backlog > sysctl_somaxconn)
31105                         backlog = sysctl_somaxconn;
31106  
31107 +               if (gr_handle_sock_server_other(sock) ||
31108 +                   !gr_search_listen(sock)) {
31109 +                       err = -EPERM;
31110 +                       goto error;
31111 +               }
31112 +
31113                 err = security_socket_listen(sock, backlog);
31114                 if (!err)
31115                         err = sock->ops->listen(sock, backlog);
31116  
31117 +error:
31118                 fput_light(sock->file, fput_needed);
31119         }
31120         return err;
31121 @@ -1353,6 +1395,13 @@ asmlinkage long sys_accept(int fd, struc
31122         newsock->type = sock->type;
31123         newsock->ops = sock->ops;
31124  
31125 +       if (gr_handle_sock_server_other(sock) ||
31126 +           !gr_search_accept(sock)) {
31127 +               err = -EPERM;
31128 +               sock_release(newsock);
31129 +               goto out_put;
31130 +       }
31131 +
31132         /*
31133          * We don't need try_module_get here, as the listening socket (sock)
31134          * has the protocol module (sock->ops->owner) held.
31135 @@ -1396,6 +1445,7 @@ asmlinkage long sys_accept(int fd, struc
31136         err = newfd;
31137  
31138         security_socket_post_accept(sock, newsock);
31139 +       gr_attach_curr_ip(newsock->sk);
31140  
31141  out_put:
31142         fput_light(sock->file, fput_needed);
31143 @@ -1424,6 +1474,7 @@ asmlinkage long sys_connect(int fd, stru
31144  {
31145         struct socket *sock;
31146         char address[MAX_SOCK_ADDR];
31147 +       struct sockaddr *sck;
31148         int err, fput_needed;
31149  
31150         sock = sockfd_lookup_light(fd, &err, &fput_needed);
31151 @@ -1433,6 +1484,13 @@ asmlinkage long sys_connect(int fd, stru
31152         if (err < 0)
31153                 goto out_put;
31154  
31155 +       sck = (struct sockaddr *)address;
31156 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
31157 +           gr_handle_sock_client(sck)) {
31158 +               err = -EACCES;
31159 +               goto out_put;
31160 +       }
31161 +
31162         err =
31163             security_socket_connect(sock, (struct sockaddr *)address, addrlen);
31164         if (err)
31165 @@ -1706,6 +1764,7 @@ asmlinkage long sys_shutdown(int fd, int
31166                         err = sock->ops->shutdown(sock, how);
31167                 fput_light(sock->file, fput_needed);
31168         }
31169 +
31170         return err;
31171  }
31172  
31173 diff -urNp linux-2.6.20.3/net/unix/af_unix.c linux-2.6.20.3/net/unix/af_unix.c
31174 --- linux-2.6.20.3/net/unix/af_unix.c   2007-03-13 14:27:08.000000000 -0400
31175 +++ linux-2.6.20.3/net/unix/af_unix.c   2007-03-23 08:11:31.000000000 -0400
31176 @@ -118,6 +118,7 @@
31177  #include <linux/security.h>
31178  #include <linux/vs_context.h>
31179  #include <linux/vs_limit.h>
31180 +#include <linux/grsecurity.h>
31181  
31182  int sysctl_unix_max_dgram_qlen __read_mostly = 10;
31183  
31184 @@ -711,6 +712,11 @@ static struct sock *unix_find_other(stru
31185                 if (err)
31186                         goto put_fail;
31187  
31188 +               if (!gr_acl_handle_unix(nd.dentry, nd.mnt)) {
31189 +                       err = -EACCES;
31190 +                       goto put_fail;
31191 +               }
31192 +
31193                 err = -ECONNREFUSED;
31194                 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
31195                         goto put_fail;
31196 @@ -734,6 +740,13 @@ static struct sock *unix_find_other(stru
31197                 if (u) {
31198                         struct dentry *dentry;
31199                         dentry = unix_sk(u)->dentry;
31200 +
31201 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
31202 +                               err = -EPERM;
31203 +                               sock_put(u);
31204 +                               goto fail;
31205 +                       }
31206 +
31207                         if (dentry)
31208                                 touch_atime(unix_sk(u)->mnt, dentry);
31209                 } else
31210 @@ -808,9 +821,18 @@ static int unix_bind(struct socket *sock
31211                  */
31212                 mode = S_IFSOCK |
31213                        (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
31214 +
31215 +               if (!gr_acl_handle_mknod(dentry, nd.dentry, nd.mnt, mode)) {
31216 +                       err = -EACCES;
31217 +                       goto out_mknod_dput;
31218 +               }
31219 +
31220                 err = vfs_mknod(nd.dentry->d_inode, dentry, mode, 0, NULL);
31221                 if (err)
31222                         goto out_mknod_dput;
31223 +
31224 +               gr_handle_create(dentry, nd.mnt);
31225 +
31226                 mutex_unlock(&nd.dentry->d_inode->i_mutex);
31227                 dput(nd.dentry);
31228                 nd.dentry = dentry;
31229 @@ -828,6 +850,10 @@ static int unix_bind(struct socket *sock
31230                         goto out_unlock;
31231                 }
31232  
31233 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
31234 +               sk->sk_peercred.pid = current->pid;
31235 +#endif
31236 +
31237                 list = &unix_socket_table[addr->hash];
31238         } else {
31239                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
31240 diff -urNp linux-2.6.20.3/net/xfrm/xfrm_user.c linux-2.6.20.3/net/xfrm/xfrm_user.c
31241 --- linux-2.6.20.3/net/xfrm/xfrm_user.c 2007-03-13 14:27:08.000000000 -0400
31242 +++ linux-2.6.20.3/net/xfrm/xfrm_user.c 2007-03-23 08:10:06.000000000 -0400
31243 @@ -1855,7 +1855,7 @@ nlmsg_failure:
31244         return -1;
31245  }
31246  
31247 -static int inline xfrm_sa_len(struct xfrm_state *x)
31248 +static inline int xfrm_sa_len(struct xfrm_state *x)
31249  {
31250         int l = 0;
31251         if (x->aalg)
31252 diff -urNp linux-2.6.20.3/scripts/pnmtologo.c linux-2.6.20.3/scripts/pnmtologo.c
31253 --- linux-2.6.20.3/scripts/pnmtologo.c  2007-03-13 14:27:08.000000000 -0400
31254 +++ linux-2.6.20.3/scripts/pnmtologo.c  2007-03-23 08:10:06.000000000 -0400
31255 @@ -237,14 +237,14 @@ static void write_header(void)
31256      fprintf(out, " *  Linux logo %s\n", logoname);
31257      fputs(" */\n\n", out);
31258      fputs("#include <linux/linux_logo.h>\n\n", out);
31259 -    fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
31260 +    fprintf(out, "static unsigned char %s_data[] = {\n",
31261             logoname);
31262  }
31263  
31264  static void write_footer(void)
31265  {
31266      fputs("\n};\n\n", out);
31267 -    fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
31268 +    fprintf(out, "struct linux_logo %s = {\n", logoname);
31269      fprintf(out, "    .type\t= %s,\n", logo_types[logo_type]);
31270      fprintf(out, "    .width\t= %d,\n", logo_width);
31271      fprintf(out, "    .height\t= %d,\n", logo_height);
31272 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
31273      fputs("\n};\n\n", out);
31274  
31275      /* write logo clut */
31276 -    fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
31277 +    fprintf(out, "static unsigned char %s_clut[] = {\n",
31278             logoname);
31279      write_hex_cnt = 0;
31280      for (i = 0; i < logo_clutsize; i++) {
31281 diff -urNp linux-2.6.20.3/security/commoncap.c linux-2.6.20.3/security/commoncap.c
31282 --- linux-2.6.20.3/security/commoncap.c 2007-03-13 14:27:08.000000000 -0400
31283 +++ linux-2.6.20.3/security/commoncap.c 2007-03-23 08:11:31.000000000 -0400
31284 @@ -24,10 +24,11 @@
31285  #include <linux/xattr.h>
31286  #include <linux/hugetlb.h>
31287  #include <linux/vs_context.h>
31288 +#include <linux/grsecurity.h>
31289  
31290  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
31291  {
31292 -       cap_t(NETLINK_CB(skb).eff_cap) = vx_mbcap(cap_effective);
31293 +       cap_t(NETLINK_CB(skb).eff_cap) = gr_cap_rtnetlink();
31294         return 0;
31295  }
31296  
31297 @@ -44,7 +45,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
31298  int cap_capable (struct task_struct *tsk, int cap)
31299  {
31300         /* Derived from include/linux/sched.h:capable. */
31301 -       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
31302 +       if (vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap))
31303 +               return 0;
31304 +       return -EPERM;
31305 +}
31306 +
31307 +int cap_capable_nolog (struct task_struct *tsk, int cap)
31308 +{
31309 +       /* tsk = current for all callers */
31310 +       if ((vx_cap_raised(tsk->vx_info, tsk->cap_effective, cap)) && gr_is_capable_nolog(cap))
31311                 return 0;
31312         return -EPERM;
31313  }
31314 @@ -163,8 +172,11 @@ void cap_bprm_apply_creds (struct linux_
31315                 }
31316         }
31317  
31318 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
31319 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
31320 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
31321 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
31322 +
31323 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
31324 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
31325  
31326         /* For init, we want to retain the capabilities set
31327          * in the init_task struct. Thus we skip the usual
31328 @@ -175,6 +187,8 @@ void cap_bprm_apply_creds (struct linux_
31329                     cap_intersect (new_permitted, bprm->cap_effective);
31330         }
31331  
31332 +       gr_handle_chroot_caps(current);
31333 +
31334         /* AUD: Audit candidate if current->cap_effective is set */
31335  
31336         current->keep_capabilities = 0;
31337 @@ -320,12 +334,13 @@ int cap_vm_enough_memory(long pages)
31338  {
31339         int cap_sys_admin = 0;
31340  
31341 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
31342 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
31343                 cap_sys_admin = 1;
31344         return __vm_enough_memory(pages, cap_sys_admin);
31345  }
31346  
31347  EXPORT_SYMBOL(cap_capable);
31348 +EXPORT_SYMBOL(cap_capable_nolog);
31349  EXPORT_SYMBOL(cap_settime);
31350  EXPORT_SYMBOL(cap_ptrace);
31351  EXPORT_SYMBOL(cap_capget);
31352 diff -urNp linux-2.6.20.3/security/dummy.c linux-2.6.20.3/security/dummy.c
31353 --- linux-2.6.20.3/security/dummy.c     2007-03-13 14:27:08.000000000 -0400
31354 +++ linux-2.6.20.3/security/dummy.c     2007-03-23 08:11:31.000000000 -0400
31355 @@ -29,6 +29,7 @@
31356  #include <linux/ptrace.h>
31357  #include <linux/file.h>
31358  #include <linux/vs_context.h>
31359 +#include <linux/grsecurity.h>
31360  
31361  static int dummy_ptrace (struct task_struct *parent, struct task_struct *child)
31362  {
31363 @@ -139,8 +140,11 @@ static void dummy_bprm_apply_creds (stru
31364                 }
31365         }
31366  
31367 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
31368 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
31369 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
31370 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
31371 +
31372 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
31373 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
31374  
31375         dummy_capget(current, &current->cap_effective, &current->cap_inheritable, &current->cap_permitted);
31376  }
31377 diff -urNp linux-2.6.20.3/security/Kconfig linux-2.6.20.3/security/Kconfig
31378 --- linux-2.6.20.3/security/Kconfig     2007-03-13 14:27:08.000000000 -0400
31379 +++ linux-2.6.20.3/security/Kconfig     2007-03-23 09:03:54.000000000 -0400
31380 @@ -4,6 +4,432 @@
31381  
31382  menu "Security options"
31383  
31384 +menu "PaX"
31385 +
31386 +config PAX
31387 +       bool "Enable various PaX features"
31388 +       depends on GRKERNSEC && (ALPHA || ARM || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
31389 +       help
31390 +         This allows you to enable various PaX features.  PaX adds
31391 +         intrusion prevention mechanisms to the kernel that reduce
31392 +         the risks posed by exploitable memory corruption bugs.
31393 +
31394 +menu "PaX Control"
31395 +       depends on PAX
31396 +
31397 +config PAX_SOFTMODE
31398 +       bool 'Support soft mode'
31399 +       help
31400 +         Enabling this option will allow you to run PaX in soft mode, that
31401 +         is, PaX features will not be enforced by default, only on executables
31402 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
31403 +         is the only way to mark executables for soft mode use.
31404 +
31405 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
31406 +         line option on boot.  Furthermore you can control various PaX features
31407 +         at runtime via the entries in /proc/sys/kernel/pax.
31408 +
31409 +config PAX_EI_PAX
31410 +       bool 'Use legacy ELF header marking'
31411 +       help
31412 +         Enabling this option will allow you to control PaX features on
31413 +         a per executable basis via the 'chpax' utility available at
31414 +         http://pax.grsecurity.net/.  The control flags will be read from
31415 +         an otherwise reserved part of the ELF header.  This marking has
31416 +         numerous drawbacks (no support for soft-mode, toolchain does not
31417 +         know about the non-standard use of the ELF header) therefore it
31418 +         has been deprecated in favour of PT_PAX_FLAGS support.
31419 +
31420 +         If you have applications not marked by the PT_PAX_FLAGS ELF
31421 +         program header then you MUST enable this option otherwise they
31422 +         will not get any protection.
31423 +
31424 +         Note that if you enable PT_PAX_FLAGS marking support as well,
31425 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
31426 +
31427 +config PAX_PT_PAX_FLAGS
31428 +       bool 'Use ELF program header marking'
31429 +       help
31430 +         Enabling this option will allow you to control PaX features on
31431 +         a per executable basis via the 'paxctl' utility available at
31432 +         http://pax.grsecurity.net/.  The control flags will be read from
31433 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
31434 +         has the benefits of supporting both soft mode and being fully
31435 +         integrated into the toolchain (the binutils patch is available
31436 +         from http://pax.grsecurity.net).
31437 +
31438 +         If you have applications not marked by the PT_PAX_FLAGS ELF
31439 +         program header then you MUST enable the EI_PAX marking support
31440 +         otherwise they will not get any protection.
31441 +
31442 +         Note that if you enable the legacy EI_PAX marking support as well,
31443 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
31444 +
31445 +choice
31446 +       prompt 'MAC system integration'
31447 +       default PAX_NO_ACL_FLAGS
31448 +       help
31449 +         Mandatory Access Control systems have the option of controlling
31450 +         PaX flags on a per executable basis, choose the method supported
31451 +         by your particular system.
31452 +
31453 +         - "none": if your MAC system does not interact with PaX,
31454 +         - "direct": if your MAC system defines pax_set_flags() itself,
31455 +         - "hook": if your MAC system uses the pax_set_flags_func callback.
31456 +
31457 +         NOTE: this option is for developers/integrators only.
31458 +
31459 +config PAX_NO_ACL_FLAGS
31460 +       bool 'none'
31461 +
31462 +config PAX_HAVE_ACL_FLAGS
31463 +       bool 'direct'
31464 +
31465 +config PAX_HOOK_ACL_FLAGS
31466 +       bool 'hook'
31467 +endchoice
31468 +
31469 +endmenu
31470 +
31471 +menu "Non-executable pages"
31472 +       depends on PAX
31473 +
31474 +config PAX_NOEXEC
31475 +       bool "Enforce non-executable pages"
31476 +       depends on (PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS) && (ALPHA || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86 || X86_64)
31477 +       help
31478 +         By design some architectures do not allow for protecting memory
31479 +         pages against execution or even if they do, Linux does not make
31480 +         use of this feature.  In practice this means that if a page is
31481 +         readable (such as the stack or heap) it is also executable.
31482 +
31483 +         There is a well known exploit technique that makes use of this
31484 +         fact and a common programming mistake where an attacker can
31485 +         introduce code of his choice somewhere in the attacked program's
31486 +         memory (typically the stack or the heap) and then execute it.
31487 +
31488 +         If the attacked program was running with different (typically
31489 +         higher) privileges than that of the attacker, then he can elevate
31490 +         his own privilege level (e.g. get a root shell, write to files for
31491 +         which he does not have write access to, etc).
31492 +
31493 +         Enabling this option will let you choose from various features
31494 +         that prevent the injection and execution of 'foreign' code in
31495 +         a program.
31496 +
31497 +         This will also break programs that rely on the old behaviour and
31498 +         expect that dynamically allocated memory via the malloc() family
31499 +         of functions is executable (which it is not).  Notable examples
31500 +         are the XFree86 4.x server, the java runtime and wine.
31501 +
31502 +config PAX_PAGEEXEC
31503 +       bool "Paging based non-executable pages"
31504 +       depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MPENTIUM4 || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2)
31505 +       help
31506 +         This implementation is based on the paging feature of the CPU.
31507 +         On i386 and ppc there is a variable but usually low performance
31508 +         impact on applications.  On alpha, ia64, parisc, sparc, sparc64
31509 +         and x86_64 there is no performance impact.
31510 +
31511 +config PAX_SEGMEXEC
31512 +       bool "Segmentation based non-executable pages"
31513 +       depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
31514 +       help
31515 +         This implementation is based on the segmentation feature of the
31516 +         CPU and has little performance impact, however applications will
31517 +         be limited to a 1.5 GB address space instead of the normal 3 GB.
31518 +
31519 +choice
31520 +       prompt "Default non-executable page method"
31521 +       depends on PAX_PAGEEXEC && PAX_SEGMEXEC
31522 +       default PAX_DEFAULT_SEGMEXEC
31523 +       help
31524 +         Select the default non-executable page method applied to applications
31525 +         that do not select one themselves.
31526 +
31527 +config PAX_DEFAULT_PAGEEXEC
31528 +       bool "PAGEEXEC"
31529 +
31530 +config PAX_DEFAULT_SEGMEXEC
31531 +       bool "SEGMEXEC"
31532 +endchoice
31533 +
31534 +config PAX_EMUTRAMP
31535 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86_32)
31536 +       default y if PARISC || PPC32
31537 +       help
31538 +         There are some programs and libraries that for one reason or
31539 +         another attempt to execute special small code snippets from
31540 +         non-executable memory pages.  Most notable examples are the
31541 +         signal handler return code generated by the kernel itself and
31542 +         the GCC trampolines.
31543 +
31544 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
31545 +         such programs will no longer work under your kernel.
31546 +
31547 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
31548 +         utilities to enable trampoline emulation for the affected programs
31549 +         yet still have the protection provided by the non-executable pages.
31550 +
31551 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
31552 +         well, otherwise your system will not even boot.
31553 +
31554 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
31555 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
31556 +         for the affected files.
31557 +
31558 +         NOTE: enabling this feature *may* open up a loophole in the
31559 +         protection provided by non-executable pages that an attacker
31560 +         could abuse.  Therefore the best solution is to not have any
31561 +         files on your system that would require this option.  This can
31562 +         be achieved by not using libc5 (which relies on the kernel
31563 +         signal handler return code) and not using or rewriting programs
31564 +         that make use of the nested function implementation of GCC.
31565 +         Skilled users can just fix GCC itself so that it implements
31566 +         nested function calls in a way that does not interfere with PaX.
31567 +
31568 +config PAX_EMUSIGRT
31569 +       bool "Automatically emulate sigreturn trampolines"
31570 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
31571 +       default y
31572 +       help
31573 +         Enabling this option will have the kernel automatically detect
31574 +         and emulate signal return trampolines executing on the stack
31575 +         that would otherwise lead to task termination.
31576 +
31577 +         This solution is intended as a temporary one for users with
31578 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
31579 +         Modula-3 runtime, etc) or executables linked to such, basically
31580 +         everything that does not specify its own SA_RESTORER function in
31581 +         normal executable memory like glibc 2.1+ does.
31582 +
31583 +         On parisc and ppc you MUST enable this option, otherwise your
31584 +         system will not even boot.
31585 +
31586 +         NOTE: this feature cannot be disabled on a per executable basis
31587 +         and since it *does* open up a loophole in the protection provided
31588 +         by non-executable pages, the best solution is to not have any
31589 +         files on your system that would require this option.
31590 +
31591 +config PAX_MPROTECT
31592 +       bool "Restrict mprotect()"
31593 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
31594 +       help
31595 +         Enabling this option will prevent programs from
31596 +          - changing the executable status of memory pages that were
31597 +            not originally created as executable,
31598 +          - making read-only executable pages writable again,
31599 +          - creating executable pages from anonymous memory.
31600 +
31601 +         You should say Y here to complete the protection provided by
31602 +         the enforcement of non-executable pages.
31603 +
31604 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
31605 +         this feature on a per file basis.
31606 +
31607 +config PAX_NOELFRELOCS
31608 +       bool "Disallow ELF text relocations"
31609 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86 || X86_64)
31610 +       help
31611 +         Non-executable pages and mprotect() restrictions are effective
31612 +         in preventing the introduction of new executable code into an
31613 +         attacked task's address space.  There remain only two venues
31614 +         for this kind of attack: if the attacker can execute already
31615 +         existing code in the attacked task then he can either have it
31616 +         create and mmap() a file containing his code or have it mmap()
31617 +         an already existing ELF library that does not have position
31618 +         independent code in it and use mprotect() on it to make it
31619 +         writable and copy his code there.  While protecting against
31620 +         the former approach is beyond PaX, the latter can be prevented
31621 +         by having only PIC ELF libraries on one's system (which do not
31622 +         need to relocate their code).  If you are sure this is your case,
31623 +         then enable this option otherwise be careful as you may not even
31624 +         be able to boot or log on your system (for example, some PAM
31625 +         modules are erroneously compiled as non-PIC by default).
31626 +
31627 +         NOTE: if you are using dynamic ELF executables (as suggested
31628 +         when using ASLR) then you must have made sure that you linked
31629 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
31630 +         referenced there has already been updated to support this).
31631 +
31632 +config PAX_ETEXECRELOCS
31633 +       bool "Allow ELF ET_EXEC text relocations"
31634 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
31635 +       default y
31636 +       help
31637 +         On some architectures there are incorrectly created applications
31638 +         that require text relocations and would not work without enabling
31639 +         this option.  If you are an alpha, ia64 or parisc user, you should
31640 +         enable this option and disable it once you have made sure that
31641 +         none of your applications need it.
31642 +
31643 +config PAX_EMUPLT
31644 +       bool "Automatically emulate ELF PLT"
31645 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
31646 +       default y
31647 +       help
31648 +         Enabling this option will have the kernel automatically detect
31649 +         and emulate the Procedure Linkage Table entries in ELF files.
31650 +         On some architectures such entries are in writable memory, and
31651 +         become non-executable leading to task termination.  Therefore
31652 +         it is mandatory that you enable this option on alpha, parisc, ppc,
31653 +         sparc and sparc64, otherwise your system would not even boot.
31654 +
31655 +         NOTE: this feature *does* open up a loophole in the protection
31656 +         provided by the non-executable pages, therefore the proper
31657 +         solution is to modify the toolchain to produce a PLT that does
31658 +         not need to be writable.
31659 +
31660 +config PAX_DLRESOLVE
31661 +       bool
31662 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
31663 +       default y
31664 +
31665 +config PAX_SYSCALL
31666 +       bool
31667 +       depends on PAX_PAGEEXEC && PPC32
31668 +       default y
31669 +
31670 +config PAX_KERNEXEC
31671 +       bool "Enforce non-executable kernel pages"
31672 +       depends on PAX_NOEXEC && X86_32 && !HOTPLUG_PCI_COMPAQ_NVRAM && !PCI_BIOS && !EFI && !COMPAT_VDSO && X86_WP_WORKS_OK
31673 +       help
31674 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
31675 +         that is, enabling this option will make it harder to inject
31676 +         and execute 'foreign' code in kernel memory itself.
31677 +
31678 +endmenu
31679 +
31680 +menu "Address Space Layout Randomization"
31681 +       depends on PAX
31682 +
31683 +config PAX_ASLR
31684 +       bool "Address Space Layout Randomization"
31685 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
31686 +       help
31687 +         Many if not most exploit techniques rely on the knowledge of
31688 +         certain addresses in the attacked program.  The following options
31689 +         will allow the kernel to apply a certain amount of randomization
31690 +         to specific parts of the program thereby forcing an attacker to
31691 +         guess them in most cases.  Any failed guess will most likely crash
31692 +         the attacked program which allows the kernel to detect such attempts
31693 +         and react on them.  PaX itself provides no reaction mechanisms,
31694 +         instead it is strongly encouraged that you make use of Nergal's
31695 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
31696 +         (http://www.grsecurity.net/) built-in crash detection features or
31697 +         develop one yourself.
31698 +
31699 +         By saying Y here you can choose to randomize the following areas:
31700 +          - top of the task's kernel stack
31701 +          - top of the task's userland stack
31702 +          - base address for mmap() requests that do not specify one
31703 +            (this includes all libraries)
31704 +          - base address of the main executable
31705 +
31706 +         It is strongly recommended to say Y here as address space layout
31707 +         randomization has negligible impact on performance yet it provides
31708 +         a very effective protection.
31709 +
31710 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
31711 +         this feature on a per file basis.
31712 +
31713 +config PAX_RANDKSTACK
31714 +       bool "Randomize kernel stack base"
31715 +       depends on PAX_ASLR && X86_TSC && X86_32
31716 +       help
31717 +         By saying Y here the kernel will randomize every task's kernel
31718 +         stack on every system call.  This will not only force an attacker
31719 +         to guess it but also prevent him from making use of possible
31720 +         leaked information about it.
31721 +
31722 +         Since the kernel stack is a rather scarce resource, randomization
31723 +         may cause unexpected stack overflows, therefore you should very
31724 +         carefully test your system.  Note that once enabled in the kernel
31725 +         configuration, this feature cannot be disabled on a per file basis.
31726 +
31727 +config PAX_RANDUSTACK
31728 +       bool "Randomize user stack base"
31729 +       depends on PAX_ASLR
31730 +       help
31731 +         By saying Y here the kernel will randomize every task's userland
31732 +         stack.  The randomization is done in two steps where the second
31733 +         one may apply a big amount of shift to the top of the stack and
31734 +         cause problems for programs that want to use lots of memory (more
31735 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
31736 +         For this reason the second step can be controlled by 'chpax' or
31737 +         'paxctl' on a per file basis.
31738 +
31739 +config PAX_RANDMMAP
31740 +       bool "Randomize mmap() base"
31741 +       depends on PAX_ASLR
31742 +       help
31743 +         By saying Y here the kernel will use a randomized base address for
31744 +         mmap() requests that do not specify one themselves.  As a result
31745 +         all dynamically loaded libraries will appear at random addresses
31746 +         and therefore be harder to exploit by a technique where an attacker
31747 +         attempts to execute library code for his purposes (e.g. spawn a
31748 +         shell from an exploited program that is running at an elevated
31749 +         privilege level).
31750 +
31751 +         Furthermore, if a program is relinked as a dynamic ELF file, its
31752 +         base address will be randomized as well, completing the full
31753 +         randomization of the address space layout.  Attacking such programs
31754 +         becomes a guess game.  You can find an example of doing this at
31755 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
31756 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
31757 +
31758 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
31759 +         feature on a per file basis.
31760 +
31761 +endmenu
31762 +
31763 +menu "Miscellaneous hardening features"
31764 +
31765 +config PAX_MEMORY_SANITIZE
31766 +       bool "Sanitize all freed memory"
31767 +       help
31768 +         By saying Y here the kernel will erase memory pages as soon as they
31769 +         are freed.  This in turn reduces the lifetime of data stored in the
31770 +         pages, making it less likely that sensitive information such as
31771 +         passwords, cryptographic secrets, etc stay in memory for too long.
31772 +
31773 +         This is especially useful for programs whose runtime is short, long
31774 +         lived processes and the kernel itself benefit from this as long as
31775 +         they operate on whole memory pages and ensure timely freeing of pages
31776 +         that may hold sensitive information.
31777 +
31778 +         The tradeoff is performance impact, on a single CPU system kernel
31779 +         compilation sees a 3% slowdown, other systems and workloads may vary
31780 +         and you are advised to test this feature on your expected workload
31781 +         before deploying it.
31782 +
31783 +         Note that this feature does not protect data stored in live pages,
31784 +         e.g., process memory swapped to disk may stay there for a long time.
31785 +
31786 +config PAX_MEMORY_UDEREF
31787 +       bool "Prevent invalid userland pointer dereference"
31788 +       depends on X86_32 && !COMPAT_VDSO
31789 +       help
31790 +         By saying Y here the kernel will be prevented from dereferencing
31791 +         userland pointers in contexts where the kernel expects only kernel
31792 +         pointers.  This is both a useful runtime debugging feature and a
31793 +         security measure that prevents exploiting a class of kernel bugs.
31794 +
31795 +         The tradeoff is that some virtualization solutions may experience
31796 +         a huge slowdown and therefore you should not enable this feature
31797 +         for kernels meant to run in such environments.  Whether a given VM
31798 +         solution is affected or not is best determined by simply trying it
31799 +         out, the performance impact will be obvious right on boot as this
31800 +         mechanism engages from very early on.  A good rule of thumb is that
31801 +         VMs running on CPUs without hardware virtualization support (i.e.,
31802 +         the majority of IA-32 CPUs) will likely experience the slowdown.
31803 +
31804 +endmenu
31805 +
31806 +endmenu
31807 +
31808 +source grsecurity/Kconfig
31809 +
31810  config KEYS
31811         bool "Enable access key retention support"
31812         depends on !VSERVER_SECURITY
31813 diff -urNp linux-2.6.20.3/sound/core/oss/pcm_oss.c linux-2.6.20.3/sound/core/oss/pcm_oss.c
31814 --- linux-2.6.20.3/sound/core/oss/pcm_oss.c     2007-03-13 14:27:08.000000000 -0400
31815 +++ linux-2.6.20.3/sound/core/oss/pcm_oss.c     2007-03-23 08:10:06.000000000 -0400
31816 @@ -2881,8 +2881,8 @@ static void snd_pcm_oss_proc_done(struct
31817         }
31818  }
31819  #else /* !CONFIG_SND_VERBOSE_PROCFS */
31820 -#define snd_pcm_oss_proc_init(pcm)
31821 -#define snd_pcm_oss_proc_done(pcm)
31822 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
31823 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
31824  #endif /* CONFIG_SND_VERBOSE_PROCFS */
31825  
31826  /*
31827 diff -urNp linux-2.6.20.3/sound/core/seq/seq_lock.h linux-2.6.20.3/sound/core/seq/seq_lock.h
31828 --- linux-2.6.20.3/sound/core/seq/seq_lock.h    2007-03-13 14:27:08.000000000 -0400
31829 +++ linux-2.6.20.3/sound/core/seq/seq_lock.h    2007-03-23 08:10:06.000000000 -0400
31830 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
31831  #else /* SMP || CONFIG_SND_DEBUG */
31832  
31833  typedef spinlock_t snd_use_lock_t;     /* dummy */
31834 -#define snd_use_lock_init(lockp) /**/
31835 -#define snd_use_lock_use(lockp) /**/
31836 -#define snd_use_lock_free(lockp) /**/
31837 -#define snd_use_lock_sync(lockp) /**/
31838 +#define snd_use_lock_init(lockp) do {} while (0)
31839 +#define snd_use_lock_use(lockp) do {} while (0)
31840 +#define snd_use_lock_free(lockp) do {} while (0)
31841 +#define snd_use_lock_sync(lockp) do {} while (0)
31842  
31843  #endif /* SMP || CONFIG_SND_DEBUG */
31844  
31845 diff -urNp linux-2.6.20.3/sound/pci/ac97/ac97_codec.c linux-2.6.20.3/sound/pci/ac97/ac97_codec.c
31846 --- linux-2.6.20.3/sound/pci/ac97/ac97_codec.c  2007-03-13 14:27:08.000000000 -0400
31847 +++ linux-2.6.20.3/sound/pci/ac97/ac97_codec.c  2007-03-23 08:10:06.000000000 -0400
31848 @@ -67,129 +67,129 @@ struct ac97_codec_id {
31849  };
31850  
31851  static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = {
31852 -{ 0x414b4d00, 0xffffff00, "Asahi Kasei",       NULL,   NULL },
31853 -{ 0x41445300, 0xffffff00, "Analog Devices",    NULL,   NULL },
31854 -{ 0x414c4300, 0xffffff00, "Realtek",           NULL,   NULL },
31855 -{ 0x414c4700, 0xffffff00, "Realtek",           NULL,   NULL },
31856 -{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
31857 -{ 0x43525900, 0xffffff00, "Cirrus Logic",      NULL,   NULL },
31858 -{ 0x43585400, 0xffffff00, "Conexant",           NULL,  NULL },
31859 -{ 0x44543000, 0xffffff00, "Diamond Technology", NULL,  NULL },
31860 -{ 0x454d4300, 0xffffff00, "eMicro",            NULL,   NULL },
31861 -{ 0x45838300, 0xffffff00, "ESS Technology",    NULL,   NULL },
31862 -{ 0x48525300, 0xffffff00, "Intersil",          NULL,   NULL },
31863 -{ 0x49434500, 0xffffff00, "ICEnsemble",                NULL,   NULL },
31864 -{ 0x49544500, 0xffffff00, "ITE Tech.Inc",      NULL,   NULL },
31865 -{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL },
31866 -{ 0x50534300, 0xffffff00, "Philips",           NULL,   NULL },
31867 -{ 0x53494c00, 0xffffff00, "Silicon Laboratory",        NULL,   NULL },
31868 -{ 0x54524100, 0xffffff00, "TriTech",           NULL,   NULL },
31869 -{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL,   NULL },
31870 -{ 0x56494100, 0xffffff00, "VIA Technologies",   NULL,  NULL },
31871 -{ 0x57454300, 0xffffff00, "Winbond",           NULL,   NULL },
31872 -{ 0x574d4c00, 0xffffff00, "Wolfson",           NULL,   NULL },
31873 -{ 0x594d4800, 0xffffff00, "Yamaha",            NULL,   NULL },
31874 -{ 0x83847600, 0xffffff00, "SigmaTel",          NULL,   NULL },
31875 -{ 0,         0,          NULL,                 NULL,   NULL }
31876 +{ 0x414b4d00, 0xffffff00, "Asahi Kasei",       NULL,   NULL, 0 },
31877 +{ 0x41445300, 0xffffff00, "Analog Devices",    NULL,   NULL, 0 },
31878 +{ 0x414c4300, 0xffffff00, "Realtek",           NULL,   NULL, 0 },
31879 +{ 0x414c4700, 0xffffff00, "Realtek",           NULL,   NULL, 0 },
31880 +{ 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL, 0 },
31881 +{ 0x43525900, 0xffffff00, "Cirrus Logic",      NULL,   NULL, 0 },
31882 +{ 0x43585400, 0xffffff00, "Conexant",           NULL,  NULL, 0 },
31883 +{ 0x44543000, 0xffffff00, "Diamond Technology", NULL,  NULL, 0 },
31884 +{ 0x454d4300, 0xffffff00, "eMicro",            NULL,   NULL, 0 },
31885 +{ 0x45838300, 0xffffff00, "ESS Technology",    NULL,   NULL, 0 },
31886 +{ 0x48525300, 0xffffff00, "Intersil",          NULL,   NULL, 0 },
31887 +{ 0x49434500, 0xffffff00, "ICEnsemble",                NULL,   NULL, 0 },
31888 +{ 0x49544500, 0xffffff00, "ITE Tech.Inc",      NULL,   NULL, 0 },
31889 +{ 0x4e534300, 0xffffff00, "National Semiconductor", NULL, NULL, 0 },
31890 +{ 0x50534300, 0xffffff00, "Philips",           NULL,   NULL, 0 },
31891 +{ 0x53494c00, 0xffffff00, "Silicon Laboratory",        NULL,   NULL, 0 },
31892 +{ 0x54524100, 0xffffff00, "TriTech",           NULL,   NULL, 0 },
31893 +{ 0x54584e00, 0xffffff00, "Texas Instruments", NULL,   NULL, 0 },
31894 +{ 0x56494100, 0xffffff00, "VIA Technologies",   NULL,  NULL, 0 },
31895 +{ 0x57454300, 0xffffff00, "Winbond",           NULL,   NULL, 0 },
31896 +{ 0x574d4c00, 0xffffff00, "Wolfson",           NULL,   NULL, 0 },
31897 +{ 0x594d4800, 0xffffff00, "Yamaha",            NULL,   NULL, 0 },
31898 +{ 0x83847600, 0xffffff00, "SigmaTel",          NULL,   NULL, 0 },
31899 +{ 0,         0,          NULL,                 NULL,   NULL, 0 }
31900  };
31901  
31902  static const struct ac97_codec_id snd_ac97_codec_ids[] = {
31903 -{ 0x414b4d00, 0xffffffff, "AK4540",            NULL,           NULL },
31904 -{ 0x414b4d01, 0xffffffff, "AK4542",            NULL,           NULL },
31905 -{ 0x414b4d02, 0xffffffff, "AK4543",            NULL,           NULL },
31906 -{ 0x414b4d06, 0xffffffff, "AK4544A",           NULL,           NULL },
31907 -{ 0x414b4d07, 0xffffffff, "AK4545",            NULL,           NULL },
31908 -{ 0x41445303, 0xffffffff, "AD1819",            patch_ad1819,   NULL },
31909 -{ 0x41445340, 0xffffffff, "AD1881",            patch_ad1881,   NULL },
31910 -{ 0x41445348, 0xffffffff, "AD1881A",           patch_ad1881,   NULL },
31911 -{ 0x41445360, 0xffffffff, "AD1885",            patch_ad1885,   NULL },
31912 -{ 0x41445361, 0xffffffff, "AD1886",            patch_ad1886,   NULL },
31913 -{ 0x41445362, 0xffffffff, "AD1887",            patch_ad1881,   NULL },
31914 -{ 0x41445363, 0xffffffff, "AD1886A",           patch_ad1881,   NULL },
31915 -{ 0x41445368, 0xffffffff, "AD1888",            patch_ad1888,   NULL },
31916 -{ 0x41445370, 0xffffffff, "AD1980",            patch_ad1980,   NULL },
31917 -{ 0x41445372, 0xffffffff, "AD1981A",           patch_ad1981a,  NULL },
31918 -{ 0x41445374, 0xffffffff, "AD1981B",           patch_ad1981b,  NULL },
31919 -{ 0x41445375, 0xffffffff, "AD1985",            patch_ad1985,   NULL },
31920 -{ 0x41445378, 0xffffffff, "AD1986",            patch_ad1985,   NULL },
31921 -{ 0x414c4300, 0xffffff00, "ALC100,100P",       NULL,           NULL },
31922 -{ 0x414c4710, 0xfffffff0, "ALC200,200P",       NULL,           NULL },
31923 -{ 0x414c4721, 0xffffffff, "ALC650D",           NULL,   NULL }, /* already patched */
31924 -{ 0x414c4722, 0xffffffff, "ALC650E",           NULL,   NULL }, /* already patched */
31925 -{ 0x414c4723, 0xffffffff, "ALC650F",           NULL,   NULL }, /* already patched */
31926 -{ 0x414c4720, 0xfffffff0, "ALC650",            patch_alc650,   NULL },
31927 -{ 0x414c4760, 0xfffffff0, "ALC655",            patch_alc655,   NULL },
31928 -{ 0x414c4781, 0xffffffff, "ALC658D",           NULL,   NULL }, /* already patched */
31929 -{ 0x414c4780, 0xfffffff0, "ALC658",            patch_alc655,   NULL },
31930 -{ 0x414c4790, 0xfffffff0, "ALC850",            patch_alc850,   NULL },
31931 -{ 0x414c4730, 0xffffffff, "ALC101",            NULL,           NULL },
31932 -{ 0x414c4740, 0xfffffff0, "ALC202",            NULL,           NULL },
31933 -{ 0x414c4750, 0xfffffff0, "ALC250",            NULL,           NULL },
31934 -{ 0x414c4770, 0xfffffff0, "ALC203",            NULL,           NULL },
31935 -{ 0x434d4941, 0xffffffff, "CMI9738",           patch_cm9738,   NULL },
31936 -{ 0x434d4961, 0xffffffff, "CMI9739",           patch_cm9739,   NULL },
31937 -{ 0x434d4969, 0xffffffff, "CMI9780",           patch_cm9780,   NULL },
31938 -{ 0x434d4978, 0xffffffff, "CMI9761A",          patch_cm9761,   NULL },
31939 -{ 0x434d4982, 0xffffffff, "CMI9761B",          patch_cm9761,   NULL },
31940 -{ 0x434d4983, 0xffffffff, "CMI9761A+",         patch_cm9761,   NULL },
31941 -{ 0x43525900, 0xfffffff8, "CS4297",            NULL,           NULL },
31942 -{ 0x43525910, 0xfffffff8, "CS4297A",           patch_cirrus_spdif,     NULL },
31943 -{ 0x43525920, 0xfffffff8, "CS4298",            patch_cirrus_spdif,             NULL },
31944 -{ 0x43525928, 0xfffffff8, "CS4294",            NULL,           NULL },
31945 -{ 0x43525930, 0xfffffff8, "CS4299",            patch_cirrus_cs4299,    NULL },
31946 -{ 0x43525948, 0xfffffff8, "CS4201",            NULL,           NULL },
31947 -{ 0x43525958, 0xfffffff8, "CS4205",            patch_cirrus_spdif,     NULL },
31948 -{ 0x43525960, 0xfffffff8, "CS4291",            NULL,           NULL },
31949 -{ 0x43525970, 0xfffffff8, "CS4202",            NULL,           NULL },
31950 -{ 0x43585421, 0xffffffff, "HSD11246",          NULL,           NULL }, // SmartMC II
31951 -{ 0x43585428, 0xfffffff8, "Cx20468",           patch_conexant, NULL }, // SmartAMC fixme: the mask might be different
31952 -{ 0x44543031, 0xfffffff0, "DT0398",            NULL,           NULL },
31953 -{ 0x454d4328, 0xffffffff, "EM28028",           NULL,           NULL },  // same as TR28028?
31954 -{ 0x45838308, 0xffffffff, "ESS1988",           NULL,           NULL },
31955 -{ 0x48525300, 0xffffff00, "HMP9701",           NULL,           NULL },
31956 -{ 0x49434501, 0xffffffff, "ICE1230",           NULL,           NULL },
31957 -{ 0x49434511, 0xffffffff, "ICE1232",           NULL,           NULL }, // alias VIA VT1611A?
31958 -{ 0x49434514, 0xffffffff, "ICE1232A",          NULL,           NULL },
31959 -{ 0x49434551, 0xffffffff, "VT1616",            patch_vt1616,   NULL }, 
31960 -{ 0x49434552, 0xffffffff, "VT1616i",           patch_vt1616,   NULL }, // VT1616 compatible (chipset integrated)
31961 -{ 0x49544520, 0xffffffff, "IT2226E",           NULL,           NULL },
31962 -{ 0x49544561, 0xffffffff, "IT2646E",           patch_it2646,   NULL },
31963 -{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48",        NULL,           NULL }, // only guess --jk
31964 -{ 0x4e534331, 0xffffffff, "LM4549",            NULL,           NULL },
31965 -{ 0x4e534350, 0xffffffff, "LM4550",            patch_lm4550,   NULL }, // volume wrap fix 
31966 -{ 0x50534304, 0xffffffff, "UCB1400",           patch_ucb1400,  NULL },
31967 +{ 0x414b4d00, 0xffffffff, "AK4540",            NULL,           NULL, 0 },
31968 +{ 0x414b4d01, 0xffffffff, "AK4542",            NULL,           NULL, 0 },
31969 +{ 0x414b4d02, 0xffffffff, "AK4543",            NULL,           NULL, 0 },
31970 +{ 0x414b4d06, 0xffffffff, "AK4544A",           NULL,           NULL, 0 },
31971 +{ 0x414b4d07, 0xffffffff, "AK4545",            NULL,           NULL, 0 },
31972 +{ 0x41445303, 0xffffffff, "AD1819",            patch_ad1819,   NULL, 0 },
31973 +{ 0x41445340, 0xffffffff, "AD1881",            patch_ad1881,   NULL, 0 },
31974 +{ 0x41445348, 0xffffffff, "AD1881A",           patch_ad1881,   NULL, 0 },
31975 +{ 0x41445360, 0xffffffff, "AD1885",            patch_ad1885,   NULL, 0 },
31976 +{ 0x41445361, 0xffffffff, "AD1886",            patch_ad1886,   NULL, 0 },
31977 +{ 0x41445362, 0xffffffff, "AD1887",            patch_ad1881,   NULL, 0 },
31978 +{ 0x41445363, 0xffffffff, "AD1886A",           patch_ad1881,   NULL, 0 },
31979 +{ 0x41445368, 0xffffffff, "AD1888",            patch_ad1888,   NULL, 0 },
31980 +{ 0x41445370, 0xffffffff, "AD1980",            patch_ad1980,   NULL, 0 },
31981 +{ 0x41445372, 0xffffffff, "AD1981A",           patch_ad1981a,  NULL, 0 },
31982 +{ 0x41445374, 0xffffffff, "AD1981B",           patch_ad1981b,  NULL, 0 },
31983 +{ 0x41445375, 0xffffffff, "AD1985",            patch_ad1985,   NULL, 0 },
31984 +{ 0x41445378, 0xffffffff, "AD1986",            patch_ad1985,   NULL, 0 },
31985 +{ 0x414c4300, 0xffffff00, "ALC100,100P",       NULL,           NULL, 0 },
31986 +{ 0x414c4710, 0xfffffff0, "ALC200,200P",       NULL,           NULL, 0 },
31987 +{ 0x414c4721, 0xffffffff, "ALC650D",           NULL,   NULL, 0 }, /* already patched */
31988 +{ 0x414c4722, 0xffffffff, "ALC650E",           NULL,   NULL, 0 }, /* already patched */
31989 +{ 0x414c4723, 0xffffffff, "ALC650F",           NULL,   NULL, 0 }, /* already patched */
31990 +{ 0x414c4720, 0xfffffff0, "ALC650",            patch_alc650,   NULL, 0 },
31991 +{ 0x414c4760, 0xfffffff0, "ALC655",            patch_alc655,   NULL, 0 },
31992 +{ 0x414c4781, 0xffffffff, "ALC658D",           NULL,   NULL, 0 }, /* already patched */
31993 +{ 0x414c4780, 0xfffffff0, "ALC658",            patch_alc655,   NULL, 0 },
31994 +{ 0x414c4790, 0xfffffff0, "ALC850",            patch_alc850,   NULL, 0 },
31995 +{ 0x414c4730, 0xffffffff, "ALC101",            NULL,           NULL, 0 },
31996 +{ 0x414c4740, 0xfffffff0, "ALC202",            NULL,           NULL, 0 },
31997 +{ 0x414c4750, 0xfffffff0, "ALC250",            NULL,           NULL, 0 },
31998 +{ 0x414c4770, 0xfffffff0, "ALC203",            NULL,           NULL, 0 },
31999 +{ 0x434d4941, 0xffffffff, "CMI9738",           patch_cm9738,   NULL, 0 },
32000 +{ 0x434d4961, 0xffffffff, "CMI9739",           patch_cm9739,   NULL, 0 },
32001 +{ 0x434d4969, 0xffffffff, "CMI9780",           patch_cm9780,   NULL, 0 },
32002 +{ 0x434d4978, 0xffffffff, "CMI9761A",          patch_cm9761,   NULL, 0 },
32003 +{ 0x434d4982, 0xffffffff, "CMI9761B",          patch_cm9761,   NULL, 0 },
32004 +{ 0x434d4983, 0xffffffff, "CMI9761A+",         patch_cm9761,   NULL, 0 },
32005 +{ 0x43525900, 0xfffffff8, "CS4297",            NULL,           NULL, 0 },
32006 +{ 0x43525910, 0xfffffff8, "CS4297A",           patch_cirrus_spdif,     NULL, 0 },
32007 +{ 0x43525920, 0xfffffff8, "CS4298",            patch_cirrus_spdif,             NULL, 0 },
32008 +{ 0x43525928, 0xfffffff8, "CS4294",            NULL,           NULL, 0 },
32009 +{ 0x43525930, 0xfffffff8, "CS4299",            patch_cirrus_cs4299,    NULL, 0 },
32010 +{ 0x43525948, 0xfffffff8, "CS4201",            NULL,           NULL, 0 },
32011 +{ 0x43525958, 0xfffffff8, "CS4205",            patch_cirrus_spdif,     NULL, 0 },
32012 +{ 0x43525960, 0xfffffff8, "CS4291",            NULL,           NULL, 0 },
32013 +{ 0x43525970, 0xfffffff8, "CS4202",            NULL,           NULL, 0 },
32014 +{ 0x43585421, 0xffffffff, "HSD11246",          NULL,           NULL, 0 },      // SmartMC II
32015 +{ 0x43585428, 0xfffffff8, "Cx20468",           patch_conexant, NULL, 0 }, // SmartAMC fixme: the mask might be different
32016 +{ 0x44543031, 0xfffffff0, "DT0398",            NULL,           NULL, 0 },
32017 +{ 0x454d4328, 0xffffffff, "EM28028",           NULL,           NULL, 0 },  // same as TR28028?
32018 +{ 0x45838308, 0xffffffff, "ESS1988",           NULL,           NULL, 0 },
32019 +{ 0x48525300, 0xffffff00, "HMP9701",           NULL,           NULL, 0 },
32020 +{ 0x49434501, 0xffffffff, "ICE1230",           NULL,           NULL, 0 },
32021 +{ 0x49434511, 0xffffffff, "ICE1232",           NULL,           NULL, 0 }, // alias VIA VT1611A?
32022 +{ 0x49434514, 0xffffffff, "ICE1232A",          NULL,           NULL, 0 },
32023 +{ 0x49434551, 0xffffffff, "VT1616",            patch_vt1616,   NULL, 0 },
32024 +{ 0x49434552, 0xffffffff, "VT1616i",           patch_vt1616,   NULL, 0 }, // VT1616 compatible (chipset integrated)
32025 +{ 0x49544520, 0xffffffff, "IT2226E",           NULL,           NULL, 0 },
32026 +{ 0x49544561, 0xffffffff, "IT2646E",           patch_it2646,   NULL, 0 },
32027 +{ 0x4e534300, 0xffffffff, "LM4540,43,45,46,48",        NULL,           NULL, 0 }, // only guess --jk
32028 +{ 0x4e534331, 0xffffffff, "LM4549",            NULL,           NULL, 0 },
32029 +{ 0x4e534350, 0xffffffff, "LM4550",            patch_lm4550,   NULL, 0 }, // volume wrap fix 
32030 +{ 0x50534304, 0xffffffff, "UCB1400",           patch_ucb1400,  NULL, 0 },
32031  { 0x53494c20, 0xffffffe0, "Si3036,8",          mpatch_si3036,  mpatch_si3036, AC97_MODEM_PATCH },
32032 -{ 0x54524102, 0xffffffff, "TR28022",           NULL,           NULL },
32033 -{ 0x54524106, 0xffffffff, "TR28026",           NULL,           NULL },
32034 -{ 0x54524108, 0xffffffff, "TR28028",           patch_tritech_tr28028,  NULL }, // added by xin jin [07/09/99]
32035 -{ 0x54524123, 0xffffffff, "TR28602",           NULL,           NULL }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
32036 -{ 0x54584e20, 0xffffffff, "TLC320AD9xC",       NULL,           NULL },
32037 -{ 0x56494161, 0xffffffff, "VIA1612A",          NULL,           NULL }, // modified ICE1232 with S/PDIF
32038 -{ 0x56494170, 0xffffffff, "VIA1617A",          patch_vt1617a,  NULL }, // modified VT1616 with S/PDIF
32039 -{ 0x56494182, 0xffffffff, "VIA1618",           NULL,           NULL },
32040 -{ 0x57454301, 0xffffffff, "W83971D",           NULL,           NULL },
32041 -{ 0x574d4c00, 0xffffffff, "WM9701A",           NULL,           NULL },
32042 -{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
32043 -{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q",   patch_wolfson04, NULL},
32044 -{ 0x574d4C05, 0xffffffff, "WM9705,WM9710",     patch_wolfson05, NULL},
32045 -{ 0x574d4C09, 0xffffffff, "WM9709",            NULL,           NULL},
32046 -{ 0x574d4C12, 0xffffffff, "WM9711,WM9712",     patch_wolfson11, NULL},
32047 +{ 0x54524102, 0xffffffff, "TR28022",           NULL,           NULL, 0 },
32048 +{ 0x54524106, 0xffffffff, "TR28026",           NULL,           NULL, 0 },
32049 +{ 0x54524108, 0xffffffff, "TR28028",           patch_tritech_tr28028,  NULL, 0 }, // added by xin jin [07/09/99]
32050 +{ 0x54524123, 0xffffffff, "TR28602",           NULL,           NULL, 0 }, // only guess --jk [TR28023 = eMicro EM28023 (new CT1297)]
32051 +{ 0x54584e20, 0xffffffff, "TLC320AD9xC",       NULL,           NULL, 0 },
32052 +{ 0x56494161, 0xffffffff, "VIA1612A",          NULL,           NULL, 0 }, // modified ICE1232 with S/PDIF
32053 +{ 0x56494170, 0xffffffff, "VIA1617A",          patch_vt1617a,  NULL, 0 }, // modified VT1616 with S/PDIF
32054 +{ 0x56494182, 0xffffffff, "VIA1618",           NULL,           NULL, 0 },
32055 +{ 0x57454301, 0xffffffff, "W83971D",           NULL,           NULL, 0 },
32056 +{ 0x574d4c00, 0xffffffff, "WM9701A",           NULL,           NULL, 0 },
32057 +{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL, 0},
32058 +{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q",   patch_wolfson04, NULL, 0},
32059 +{ 0x574d4C05, 0xffffffff, "WM9705,WM9710",     patch_wolfson05, NULL, 0},
32060 +{ 0x574d4C09, 0xffffffff, "WM9709",            NULL,           NULL, 0},
32061 +{ 0x574d4C12, 0xffffffff, "WM9711,WM9712",     patch_wolfson11, NULL, 0},
32062  { 0x574d4c13, 0xffffffff, "WM9713,WM9714",     patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
32063 -{ 0x594d4800, 0xffffffff, "YMF743",            NULL,           NULL },
32064 -{ 0x594d4802, 0xffffffff, "YMF752",            NULL,           NULL },
32065 -{ 0x594d4803, 0xffffffff, "YMF753",            patch_yamaha_ymf753,    NULL },
32066 -{ 0x83847600, 0xffffffff, "STAC9700,83,84",    patch_sigmatel_stac9700,        NULL },
32067 -{ 0x83847604, 0xffffffff, "STAC9701,3,4,5",    NULL,           NULL },
32068 -{ 0x83847605, 0xffffffff, "STAC9704",          NULL,           NULL },
32069 -{ 0x83847608, 0xffffffff, "STAC9708,11",       patch_sigmatel_stac9708,        NULL },
32070 -{ 0x83847609, 0xffffffff, "STAC9721,23",       patch_sigmatel_stac9721,        NULL },
32071 -{ 0x83847644, 0xffffffff, "STAC9744",          patch_sigmatel_stac9744,        NULL },
32072 -{ 0x83847650, 0xffffffff, "STAC9750,51",       NULL,           NULL }, // patch?
32073 -{ 0x83847652, 0xffffffff, "STAC9752,53",       NULL,           NULL }, // patch?
32074 -{ 0x83847656, 0xffffffff, "STAC9756,57",       patch_sigmatel_stac9756,        NULL },
32075 -{ 0x83847658, 0xffffffff, "STAC9758,59",       patch_sigmatel_stac9758,        NULL },
32076 -{ 0x83847666, 0xffffffff, "STAC9766,67",       NULL,           NULL }, // patch?
32077 -{ 0,         0,          NULL,                 NULL,           NULL }
32078 +{ 0x594d4800, 0xffffffff, "YMF743",            NULL,           NULL, 0 },
32079 +{ 0x594d4802, 0xffffffff, "YMF752",            NULL,           NULL, 0 },
32080 +{ 0x594d4803, 0xffffffff, "YMF753",            patch_yamaha_ymf753,    NULL, 0 },
32081 +{ 0x83847600, 0xffffffff, "STAC9700,83,84",    patch_sigmatel_stac9700,        NULL, 0 },
32082 +{ 0x83847604, 0xffffffff, "STAC9701,3,4,5",    NULL,           NULL, 0 },
32083 +{ 0x83847605, 0xffffffff, "STAC9704",          NULL,           NULL, 0 },
32084 +{ 0x83847608, 0xffffffff, "STAC9708,11",       patch_sigmatel_stac9708,        NULL, 0 },
32085 +{ 0x83847609, 0xffffffff, "STAC9721,23",       patch_sigmatel_stac9721,        NULL, 0 },
32086 +{ 0x83847644, 0xffffffff, "STAC9744",          patch_sigmatel_stac9744,        NULL, 0 },
32087 +{ 0x83847650, 0xffffffff, "STAC9750,51",       NULL,           NULL, 0 },      // patch?
32088 +{ 0x83847652, 0xffffffff, "STAC9752,53",       NULL,           NULL, 0 }, // patch?
32089 +{ 0x83847656, 0xffffffff, "STAC9756,57",       patch_sigmatel_stac9756,        NULL, 0 },
32090 +{ 0x83847658, 0xffffffff, "STAC9758,59",       patch_sigmatel_stac9758,        NULL, 0 },
32091 +{ 0x83847666, 0xffffffff, "STAC9766,67",       NULL,           NULL, 0 }, // patch?
32092 +{ 0,         0,          NULL,                 NULL,           NULL, 0 }
32093  };
32094  
32095  
32096 diff -urNp linux-2.6.20.3/sound/pci/ac97/ac97_patch.c linux-2.6.20.3/sound/pci/ac97/ac97_patch.c
32097 --- linux-2.6.20.3/sound/pci/ac97/ac97_patch.c  2007-03-13 14:27:08.000000000 -0400
32098 +++ linux-2.6.20.3/sound/pci/ac97/ac97_patch.c  2007-03-23 08:10:06.000000000 -0400
32099 @@ -1404,7 +1404,7 @@ static const struct snd_ac97_res_table a
32100         { AC97_VIDEO, 0x9f1f },
32101         { AC97_AUX, 0x9f1f },
32102         { AC97_PCM, 0x9f1f },
32103 -       { } /* terminator */
32104 +       { 0, 0} /* terminator */
32105  };
32106  
32107  int patch_ad1819(struct snd_ac97 * ac97)
32108 @@ -2924,7 +2924,7 @@ static struct snd_ac97_res_table lm4550_
32109         { AC97_AUX, 0x1f1f },
32110         { AC97_PCM, 0x1f1f },
32111         { AC97_REC_GAIN, 0x0f0f },
32112 -       { } /* terminator */
32113 +       { 0, 0 } /* terminator */
32114  };
32115  
32116  int patch_lm4550(struct snd_ac97 *ac97)
32117 diff -urNp linux-2.6.20.3/sound/pci/ens1370.c linux-2.6.20.3/sound/pci/ens1370.c
32118 --- linux-2.6.20.3/sound/pci/ens1370.c  2007-03-13 14:27:08.000000000 -0400
32119 +++ linux-2.6.20.3/sound/pci/ens1370.c  2007-03-23 08:10:06.000000000 -0400
32120 @@ -455,7 +455,7 @@ static struct pci_device_id snd_audiopci
32121         { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* ES1373 - CT5880 */
32122         { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* Ectiva EV1938 */
32123  #endif
32124 -       { 0, }
32125 +       { 0, 0, 0, 0, 0, 0, 0 }
32126  };
32127  
32128  MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
32129 diff -urNp linux-2.6.20.3/sound/pci/intel8x0.c linux-2.6.20.3/sound/pci/intel8x0.c
32130 --- linux-2.6.20.3/sound/pci/intel8x0.c 2007-03-13 14:27:08.000000000 -0400
32131 +++ linux-2.6.20.3/sound/pci/intel8x0.c 2007-03-23 08:10:06.000000000 -0400
32132 @@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
32133         { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
32134         { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
32135         { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
32136 -       { 0, }
32137 +       { 0, 0, 0, 0, 0, 0, 0 }
32138  };
32139  
32140  MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
32141 @@ -2046,7 +2046,7 @@ static struct ac97_quirk ac97_quirks[] _
32142                 .type = AC97_TUNE_HP_ONLY
32143         },
32144  #endif
32145 -       { } /* terminator */
32146 +       { 0, 0, 0, 0, NULL, 0 } /* terminator */
32147  };
32148  
32149  static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
32150 diff -urNp linux-2.6.20.3/sound/pci/intel8x0m.c linux-2.6.20.3/sound/pci/intel8x0m.c
32151 --- linux-2.6.20.3/sound/pci/intel8x0m.c        2007-03-13 14:27:08.000000000 -0400
32152 +++ linux-2.6.20.3/sound/pci/intel8x0m.c        2007-03-23 08:10:06.000000000 -0400
32153 @@ -244,7 +244,7 @@ static struct pci_device_id snd_intel8x0
32154         { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
32155         { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
32156  #endif
32157 -       { 0, }
32158 +       { 0, 0, 0, 0, 0, 0, 0 }
32159  };
32160  
32161  MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
32162 @@ -1297,7 +1297,7 @@ static struct shortname_table {
32163         { 0x5455, "ALi M5455" },
32164         { 0x746d, "AMD AMD8111" },
32165  #endif
32166 -       { 0 },
32167 +       { 0, NULL },
32168  };
32169  
32170  static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
This page took 2.630443 seconds and 3 git commands to generate.