]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.6-grsec_full.patch
- updated to 2.6.27.21
[packages/kernel.git] / linux-2.6-grsec_full.patch
1      !
2    -~*~-
3     /!\
4    /%;@\
5   o/@,%\o
6   /%;`@,\
7  o/@'%',\o
8  '^^^N^^^`
9
10 diff -urNp linux-2.6.27.10/arch/alpha/include/asm/elf.h linux-2.6.27.10/arch/alpha/include/asm/elf.h
11 --- linux-2.6.27.10/arch/alpha/include/asm/elf.h        2008-11-07 12:55:34.000000000 -0500
12 +++ linux-2.6.27.10/arch/alpha/include/asm/elf.h        2008-11-18 03:39:50.000000000 -0500
13 @@ -91,6 +91,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
14  
15  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x1000000)
16  
17 +#ifdef CONFIG_PAX_ASLR
18 +#define PAX_ELF_ET_DYN_BASE    (current->personality & ADDR_LIMIT_32BIT ? 0x10000 : 0x120000000UL)
19 +
20 +#define PAX_DELTA_MMAP_LEN     (current->personality & ADDR_LIMIT_32BIT ? 14 : 28)
21 +#define PAX_DELTA_STACK_LEN    (current->personality & ADDR_LIMIT_32BIT ? 14 : 19)
22 +#endif
23 +
24  /* $0 is set by ld.so to a pointer to a function which might be 
25     registered using atexit.  This provides a mean for the dynamic
26     linker to call DT_FINI functions for shared libraries that have
27 diff -urNp linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h
28 --- linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
29 +++ linux-2.6.27.10/arch/alpha/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
30 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
31  D(10)  KM_IRQ1,
32  D(11)  KM_SOFTIRQ0,
33  D(12)  KM_SOFTIRQ1,
34 -D(13)  KM_TYPE_NR
35 +D(13)  KM_CLEARPAGE,
36 +D(14)  KM_TYPE_NR
37  };
38  
39  #undef D
40 diff -urNp linux-2.6.27.10/arch/alpha/include/asm/pgtable.h linux-2.6.27.10/arch/alpha/include/asm/pgtable.h
41 --- linux-2.6.27.10/arch/alpha/include/asm/pgtable.h    2008-11-07 12:55:34.000000000 -0500
42 +++ linux-2.6.27.10/arch/alpha/include/asm/pgtable.h    2008-11-18 03:39:50.000000000 -0500
43 @@ -101,6 +101,17 @@ struct vm_area_struct;
44  #define PAGE_SHARED    __pgprot(_PAGE_VALID | __ACCESS_BITS)
45  #define PAGE_COPY      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
46  #define PAGE_READONLY  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW)
47 +
48 +#ifdef CONFIG_PAX_PAGEEXEC
49 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOE)
50 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
51 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_VALID | __ACCESS_BITS | _PAGE_FOW | _PAGE_FOE)
52 +#else
53 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
54 +# define PAGE_COPY_NOEXEC      PAGE_COPY
55 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
56 +#endif
57 +
58  #define PAGE_KERNEL    __pgprot(_PAGE_VALID | _PAGE_ASM | _PAGE_KRE | _PAGE_KWE)
59  
60  #define _PAGE_NORMAL(x) __pgprot(_PAGE_VALID | __ACCESS_BITS | (x))
61 diff -urNp linux-2.6.27.10/arch/alpha/kernel/module.c linux-2.6.27.10/arch/alpha/kernel/module.c
62 --- linux-2.6.27.10/arch/alpha/kernel/module.c  2008-11-07 12:55:34.000000000 -0500
63 +++ linux-2.6.27.10/arch/alpha/kernel/module.c  2008-11-18 03:38:43.000000000 -0500
64 @@ -182,7 +182,7 @@ apply_relocate_add(Elf64_Shdr *sechdrs, 
65  
66         /* The small sections were sorted to the end of the segment.
67            The following should definitely cover them.  */
68 -       gp = (u64)me->module_core + me->core_size - 0x8000;
69 +       gp = (u64)me->module_core_rw + me->core_size_rw - 0x8000;
70         got = sechdrs[me->arch.gotsecindex].sh_addr;
71  
72         for (i = 0; i < n; i++) {
73 diff -urNp linux-2.6.27.10/arch/alpha/kernel/osf_sys.c linux-2.6.27.10/arch/alpha/kernel/osf_sys.c
74 --- linux-2.6.27.10/arch/alpha/kernel/osf_sys.c 2008-11-07 12:55:34.000000000 -0500
75 +++ linux-2.6.27.10/arch/alpha/kernel/osf_sys.c 2008-11-18 03:38:43.000000000 -0500
76 @@ -1232,6 +1232,10 @@ arch_get_unmapped_area(struct file *filp
77            merely specific addresses, but regions of memory -- perhaps
78            this feature should be incorporated into all ports?  */
79  
80 +#ifdef CONFIG_PAX_RANDMMAP
81 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
82 +#endif
83 +
84         if (addr) {
85                 addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit);
86                 if (addr != (unsigned long) -ENOMEM)
87 @@ -1239,8 +1243,8 @@ arch_get_unmapped_area(struct file *filp
88         }
89  
90         /* Next, try allocating at TASK_UNMAPPED_BASE.  */
91 -       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE),
92 -                                        len, limit);
93 +       addr = arch_get_unmapped_area_1 (PAGE_ALIGN(current->mm->mmap_base), len, limit);
94 +
95         if (addr != (unsigned long) -ENOMEM)
96                 return addr;
97  
98 diff -urNp linux-2.6.27.10/arch/alpha/kernel/ptrace.c linux-2.6.27.10/arch/alpha/kernel/ptrace.c
99 --- linux-2.6.27.10/arch/alpha/kernel/ptrace.c  2008-11-07 12:55:34.000000000 -0500
100 +++ linux-2.6.27.10/arch/alpha/kernel/ptrace.c  2008-11-18 03:38:43.000000000 -0500
101 @@ -15,6 +15,7 @@
102  #include <linux/security.h>
103  #include <linux/signal.h>
104  #include <linux/vs_base.h>
105 +#include <linux/grsecurity.h>
106  
107  #include <asm/uaccess.h>
108  #include <asm/pgtable.h>
109 @@ -266,6 +267,9 @@ long arch_ptrace(struct task_struct *chi
110         size_t copied;
111         long ret;
112  
113 +       if (gr_handle_ptrace(child, request))
114 +               return -EPERM;
115 +
116         switch (request) {
117         /* When I and D space are separate, these will need to be fixed.  */
118         case PTRACE_PEEKTEXT: /* read word at location addr. */
119 diff -urNp linux-2.6.27.10/arch/alpha/mm/fault.c linux-2.6.27.10/arch/alpha/mm/fault.c
120 --- linux-2.6.27.10/arch/alpha/mm/fault.c       2008-11-07 12:55:34.000000000 -0500
121 +++ linux-2.6.27.10/arch/alpha/mm/fault.c       2008-11-18 03:38:43.000000000 -0500
122 @@ -54,6 +54,124 @@ __load_new_mm_context(struct mm_struct *
123         __reload_thread(pcb);
124  }
125  
126 +#ifdef CONFIG_PAX_PAGEEXEC
127 +/*
128 + * PaX: decide what to do with offenders (regs->pc = fault address)
129 + *
130 + * returns 1 when task should be killed
131 + *         2 when patched PLT trampoline was detected
132 + *         3 when unpatched PLT trampoline was detected
133 + */
134 +static int pax_handle_fetch_fault(struct pt_regs *regs)
135 +{
136 +
137 +#ifdef CONFIG_PAX_EMUPLT
138 +       int err;
139 +
140 +       do { /* PaX: patched PLT emulation #1 */
141 +               unsigned int ldah, ldq, jmp;
142 +
143 +               err = get_user(ldah, (unsigned int *)regs->pc);
144 +               err |= get_user(ldq, (unsigned int *)(regs->pc+4));
145 +               err |= get_user(jmp, (unsigned int *)(regs->pc+8));
146 +
147 +               if (err)
148 +                       break;
149 +
150 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
151 +                   (ldq & 0xFFFF0000U) == 0xA77B0000U &&
152 +                   jmp == 0x6BFB0000U)
153 +               {
154 +                       unsigned long r27, addr;
155 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
156 +                       unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL;
157 +
158 +                       addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
159 +                       err = get_user(r27, (unsigned long *)addr);
160 +                       if (err)
161 +                               break;
162 +
163 +                       regs->r27 = r27;
164 +                       regs->pc = r27;
165 +                       return 2;
166 +               }
167 +       } while (0);
168 +
169 +       do { /* PaX: patched PLT emulation #2 */
170 +               unsigned int ldah, lda, br;
171 +
172 +               err = get_user(ldah, (unsigned int *)regs->pc);
173 +               err |= get_user(lda, (unsigned int *)(regs->pc+4));
174 +               err |= get_user(br, (unsigned int *)(regs->pc+8));
175 +
176 +               if (err)
177 +                       break;
178 +
179 +               if ((ldah & 0xFFFF0000U) == 0x277B0000U &&
180 +                   (lda & 0xFFFF0000U) == 0xA77B0000U &&
181 +                   (br & 0xFFE00000U) == 0xC3E00000U)
182 +               {
183 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL;
184 +                       unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16;
185 +                       unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL;
186 +
187 +                       regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL);
188 +                       regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
189 +                       return 2;
190 +               }
191 +       } while (0);
192 +
193 +       do { /* PaX: unpatched PLT emulation */
194 +               unsigned int br;
195 +
196 +               err = get_user(br, (unsigned int *)regs->pc);
197 +
198 +               if (!err && (br & 0xFFE00000U) == 0xC3800000U) {
199 +                       unsigned int br2, ldq, nop, jmp;
200 +                       unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver;
201 +
202 +                       addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2);
203 +                       err = get_user(br2, (unsigned int *)addr);
204 +                       err |= get_user(ldq, (unsigned int *)(addr+4));
205 +                       err |= get_user(nop, (unsigned int *)(addr+8));
206 +                       err |= get_user(jmp, (unsigned int *)(addr+12));
207 +                       err |= get_user(resolver, (unsigned long *)(addr+16));
208 +
209 +                       if (err)
210 +                               break;
211 +
212 +                       if (br2 == 0xC3600000U &&
213 +                           ldq == 0xA77B000CU &&
214 +                           nop == 0x47FF041FU &&
215 +                           jmp == 0x6B7B0000U)
216 +                       {
217 +                               regs->r28 = regs->pc+4;
218 +                               regs->r27 = addr+16;
219 +                               regs->pc = resolver;
220 +                               return 3;
221 +                       }
222 +               }
223 +       } while (0);
224 +#endif
225 +
226 +       return 1;
227 +}
228 +
229 +void pax_report_insns(void *pc, void *sp)
230 +{
231 +       unsigned long i;
232 +
233 +       printk(KERN_ERR "PAX: bytes at PC: ");
234 +       for (i = 0; i < 5; i++) {
235 +               unsigned int c;
236 +               if (get_user(c, (unsigned int *)pc+i))
237 +                       printk(KERN_CONT "???????? ");
238 +               else
239 +                       printk(KERN_CONT "%08x ", c);
240 +       }
241 +       printk("\n");
242 +}
243 +#endif
244  
245  /*
246   * This routine handles page faults.  It determines the address,
247 @@ -131,8 +249,29 @@ do_page_fault(unsigned long address, uns
248   good_area:
249         si_code = SEGV_ACCERR;
250         if (cause < 0) {
251 -               if (!(vma->vm_flags & VM_EXEC))
252 +               if (!(vma->vm_flags & VM_EXEC)) {
253 +
254 +#ifdef CONFIG_PAX_PAGEEXEC
255 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc)
256 +                               goto bad_area;
257 +
258 +                       up_read(&mm->mmap_sem);
259 +                       switch (pax_handle_fetch_fault(regs)) {
260 +
261 +#ifdef CONFIG_PAX_EMUPLT
262 +                       case 2:
263 +                       case 3:
264 +                               return;
265 +#endif
266 +
267 +                       }
268 +                       pax_report_fault(regs, (void *)regs->pc, (void *)rdusp());
269 +                       do_group_exit(SIGKILL);
270 +#else
271                         goto bad_area;
272 +#endif
273 +
274 +               }
275         } else if (!cause) {
276                 /* Allow reads even for write-only mappings */
277                 if (!(vma->vm_flags & (VM_READ | VM_WRITE)))
278 diff -urNp linux-2.6.27.10/arch/arm/include/asm/elf.h linux-2.6.27.10/arch/arm/include/asm/elf.h
279 --- linux-2.6.27.10/arch/arm/include/asm/elf.h  2008-11-07 12:55:34.000000000 -0500
280 +++ linux-2.6.27.10/arch/arm/include/asm/elf.h  2008-11-18 03:39:50.000000000 -0500
281 @@ -87,7 +87,14 @@ extern char elf_platform[];
282     the loader.  We need to make sure that it is out of the way of the program
283     that it will "exec", and that there is sufficient room for the brk.  */
284  
285 -#define ELF_ET_DYN_BASE        (2 * TASK_SIZE / 3)
286 +#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
287 +
288 +#ifdef CONFIG_PAX_ASLR
289 +#define PAX_ELF_ET_DYN_BASE    0x00008000UL
290 +
291 +#define PAX_DELTA_MMAP_LEN     ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
292 +#define PAX_DELTA_STACK_LEN    ((current->personality == PER_LINUX_32BIT) ? 16 : 10)
293 +#endif
294  
295  /* When the program starts, a1 contains a pointer to a function to be 
296     registered with atexit, as per the SVR4 ABI.  A value of 0 means we 
297 diff -urNp linux-2.6.27.10/arch/arm/include/asm/kmap_types.h linux-2.6.27.10/arch/arm/include/asm/kmap_types.h
298 --- linux-2.6.27.10/arch/arm/include/asm/kmap_types.h   2008-11-07 12:55:34.000000000 -0500
299 +++ linux-2.6.27.10/arch/arm/include/asm/kmap_types.h   2008-11-18 03:39:50.000000000 -0500
300 @@ -18,6 +18,7 @@ enum km_type {
301         KM_IRQ1,
302         KM_SOFTIRQ0,
303         KM_SOFTIRQ1,
304 +       KM_CLEARPAGE,
305         KM_TYPE_NR
306  };
307  
308 diff -urNp linux-2.6.27.10/arch/arm/mm/mmap.c linux-2.6.27.10/arch/arm/mm/mmap.c
309 --- linux-2.6.27.10/arch/arm/mm/mmap.c  2008-11-07 12:55:34.000000000 -0500
310 +++ linux-2.6.27.10/arch/arm/mm/mmap.c  2008-11-18 03:38:43.000000000 -0500
311 @@ -60,6 +60,10 @@ arch_get_unmapped_area(struct file *filp
312         if (len > TASK_SIZE)
313                 return -ENOMEM;
314  
315 +#ifdef CONFIG_PAX_RANDMMAP
316 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
317 +#endif
318 +
319         if (addr) {
320                 if (do_align)
321                         addr = COLOUR_ALIGN(addr, pgoff);
322 @@ -72,10 +76,10 @@ arch_get_unmapped_area(struct file *filp
323                         return addr;
324         }
325         if (len > mm->cached_hole_size) {
326 -               start_addr = addr = mm->free_area_cache;
327 +               start_addr = addr = mm->free_area_cache;
328         } else {
329 -               start_addr = addr = TASK_UNMAPPED_BASE;
330 -               mm->cached_hole_size = 0;
331 +               start_addr = addr = mm->mmap_base;
332 +               mm->cached_hole_size = 0;
333         }
334  
335  full_search:
336 @@ -91,8 +95,8 @@ full_search:
337                          * Start a new search - just in case we missed
338                          * some holes.
339                          */
340 -                       if (start_addr != TASK_UNMAPPED_BASE) {
341 -                               start_addr = addr = TASK_UNMAPPED_BASE;
342 +                       if (start_addr != mm->mmap_base) {
343 +                               start_addr = addr = mm->mmap_base;
344                                 mm->cached_hole_size = 0;
345                                 goto full_search;
346                         }
347 diff -urNp linux-2.6.27.10/arch/avr32/include/asm/elf.h linux-2.6.27.10/arch/avr32/include/asm/elf.h
348 --- linux-2.6.27.10/arch/avr32/include/asm/elf.h        2008-11-07 12:55:34.000000000 -0500
349 +++ linux-2.6.27.10/arch/avr32/include/asm/elf.h        2008-11-18 03:39:50.000000000 -0500
350 @@ -85,8 +85,14 @@ typedef struct user_fpu_struct elf_fpreg
351     the loader.  We need to make sure that it is out of the way of the program
352     that it will "exec", and that there is sufficient room for the brk.  */
353  
354 -#define ELF_ET_DYN_BASE         (2 * TASK_SIZE / 3)
355 +#define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
356  
357 +#ifdef CONFIG_PAX_ASLR
358 +#define PAX_ELF_ET_DYN_BASE    0x00001000UL
359 +
360 +#define PAX_DELTA_MMAP_LEN     15
361 +#define PAX_DELTA_STACK_LEN    15
362 +#endif
363  
364  /* This yields a mask that user programs can use to figure out what
365     instruction set this CPU supports.  This could be done in user space,
366 diff -urNp linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h
367 --- linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
368 +++ linux-2.6.27.10/arch/avr32/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
369 @@ -22,7 +22,8 @@ D(10) KM_IRQ0,
370  D(11)  KM_IRQ1,
371  D(12)  KM_SOFTIRQ0,
372  D(13)  KM_SOFTIRQ1,
373 -D(14)  KM_TYPE_NR
374 +D(14)  KM_CLEARPAGE,
375 +D(15)  KM_TYPE_NR
376  };
377  
378  #undef D
379 diff -urNp linux-2.6.27.10/arch/avr32/mm/fault.c linux-2.6.27.10/arch/avr32/mm/fault.c
380 --- linux-2.6.27.10/arch/avr32/mm/fault.c       2008-11-07 12:55:34.000000000 -0500
381 +++ linux-2.6.27.10/arch/avr32/mm/fault.c       2008-11-18 03:38:43.000000000 -0500
382 @@ -41,6 +41,23 @@ static inline int notify_page_fault(stru
383  
384  int exception_trace = 1;
385  
386 +#ifdef CONFIG_PAX_PAGEEXEC
387 +void pax_report_insns(void *pc, void *sp)
388 +{
389 +       unsigned long i;
390 +
391 +       printk(KERN_ERR "PAX: bytes at PC: ");
392 +       for (i = 0; i < 20; i++) {
393 +               unsigned char c;
394 +               if (get_user(c, (unsigned char *)pc+i))
395 +                       printk(KERN_CONT "???????? ");
396 +               else
397 +                       printk(KERN_CONT "%02x ", c);
398 +       }
399 +       printk("\n");
400 +}
401 +#endif
402 +
403  /*
404   * This routine handles page faults. It determines the address and the
405   * problem, and then passes it off to one of the appropriate routines.
406 @@ -157,6 +174,16 @@ bad_area:
407         up_read(&mm->mmap_sem);
408  
409         if (user_mode(regs)) {
410 +
411 +#ifdef CONFIG_PAX_PAGEEXEC
412 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
413 +                       if (ecr == ECR_PROTECTION_X || ecr == ECR_TLB_MISS_X) {
414 +                               pax_report_fault(regs, (void *)regs->pc, (void *)regs->sp);
415 +                               do_group_exit(SIGKILL);
416 +                       }
417 +               }
418 +#endif
419 +
420                 if (exception_trace && printk_ratelimit())
421                         printk("%s%s[%d]: segfault at %08lx pc %08lx "
422                                "sp %08lx ecr %lu\n",
423 diff -urNp linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h
424 --- linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h      2008-11-07 12:55:34.000000000 -0500
425 +++ linux-2.6.27.10/arch/blackfin/include/asm/kmap_types.h      2008-11-18 03:39:50.000000000 -0500
426 @@ -15,6 +15,7 @@ enum km_type {
427         KM_IRQ1,
428         KM_SOFTIRQ0,
429         KM_SOFTIRQ1,
430 +       KM_CLEARPAGE,
431         KM_TYPE_NR
432  };
433  
434 diff -urNp linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h
435 --- linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
436 +++ linux-2.6.27.10/arch/h8300/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
437 @@ -15,6 +15,7 @@ enum km_type {
438         KM_IRQ1,
439         KM_SOFTIRQ0,
440         KM_SOFTIRQ1,
441 +       KM_CLEARPAGE,
442         KM_TYPE_NR
443  };
444  
445 diff -urNp linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c
446 --- linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c       2008-11-07 12:55:34.000000000 -0500
447 +++ linux-2.6.27.10/arch/ia64/ia32/binfmt_elf32.c       2008-11-18 03:38:43.000000000 -0500
448 @@ -45,6 +45,13 @@ randomize_stack_top(unsigned long stack_
449  
450  #define elf_read_implies_exec(ex, have_pt_gnu_stack)   (!(have_pt_gnu_stack))
451  
452 +#ifdef CONFIG_PAX_ASLR
453 +#define PAX_ELF_ET_DYN_BASE    (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
454 +
455 +#define PAX_DELTA_MMAP_LEN     (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
456 +#define PAX_DELTA_STACK_LEN    (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
457 +#endif
458 +
459  /* Ugly but avoids duplication */
460  #include "../../../fs/binfmt_elf.c"
461  
462 diff -urNp linux-2.6.27.10/arch/ia64/ia32/ia32priv.h linux-2.6.27.10/arch/ia64/ia32/ia32priv.h
463 --- linux-2.6.27.10/arch/ia64/ia32/ia32priv.h   2008-11-07 12:55:34.000000000 -0500
464 +++ linux-2.6.27.10/arch/ia64/ia32/ia32priv.h   2008-11-18 03:38:43.000000000 -0500
465 @@ -296,7 +296,14 @@ typedef struct compat_siginfo {
466  #define ELF_DATA       ELFDATA2LSB
467  #define ELF_ARCH       EM_386
468  
469 -#define IA32_STACK_TOP         IA32_PAGE_OFFSET
470 +#ifdef CONFIG_PAX_RANDUSTACK
471 +#define __IA32_DELTA_STACK     (current->mm->delta_stack)
472 +#else
473 +#define __IA32_DELTA_STACK     0UL
474 +#endif
475 +
476 +#define IA32_STACK_TOP         (IA32_PAGE_OFFSET - __IA32_DELTA_STACK)
477 +
478  #define IA32_GATE_OFFSET       IA32_PAGE_OFFSET
479  #define IA32_GATE_END          IA32_PAGE_OFFSET + PAGE_SIZE
480  
481 diff -urNp linux-2.6.27.10/arch/ia64/include/asm/elf.h linux-2.6.27.10/arch/ia64/include/asm/elf.h
482 --- linux-2.6.27.10/arch/ia64/include/asm/elf.h 2008-11-07 12:55:34.000000000 -0500
483 +++ linux-2.6.27.10/arch/ia64/include/asm/elf.h 2008-11-18 03:39:50.000000000 -0500
484 @@ -43,6 +43,13 @@
485   */
486  #define ELF_ET_DYN_BASE                (TASK_UNMAPPED_BASE + 0x800000000UL)
487  
488 +#ifdef CONFIG_PAX_ASLR
489 +#define PAX_ELF_ET_DYN_BASE    (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL)
490 +
491 +#define PAX_DELTA_MMAP_LEN     (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
492 +#define PAX_DELTA_STACK_LEN    (current->personality == PER_LINUX32 ? 16 : 3*PAGE_SHIFT - 13)
493 +#endif
494 +
495  #define PT_IA_64_UNWIND                0x70000001
496  
497  /* IA-64 relocations: */
498 diff -urNp linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h
499 --- linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h  2008-11-07 12:55:34.000000000 -0500
500 +++ linux-2.6.27.10/arch/ia64/include/asm/kmap_types.h  2008-11-18 03:39:50.000000000 -0500
501 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
502  D(10)  KM_IRQ1,
503  D(11)  KM_SOFTIRQ0,
504  D(12)  KM_SOFTIRQ1,
505 -D(13)  KM_TYPE_NR
506 +D(13)  KM_CLEARPAGE,
507 +D(14)  KM_TYPE_NR
508  };
509  
510  #undef D
511 diff -urNp linux-2.6.27.10/arch/ia64/include/asm/pgtable.h linux-2.6.27.10/arch/ia64/include/asm/pgtable.h
512 --- linux-2.6.27.10/arch/ia64/include/asm/pgtable.h     2008-11-07 12:55:34.000000000 -0500
513 +++ linux-2.6.27.10/arch/ia64/include/asm/pgtable.h     2008-11-18 03:39:50.000000000 -0500
514 @@ -143,6 +143,17 @@
515  #define PAGE_READONLY  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
516  #define PAGE_COPY      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
517  #define PAGE_COPY_EXEC __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RX)
518 +
519 +#ifdef CONFIG_PAX_PAGEEXEC
520 +# define PAGE_SHARED_NOEXEC    __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_RW)
521 +# define PAGE_READONLY_NOEXEC  __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
522 +# define PAGE_COPY_NOEXEC      __pgprot(__ACCESS_BITS | _PAGE_PL_3 | _PAGE_AR_R)
523 +#else
524 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
525 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
526 +# define PAGE_COPY_NOEXEC      PAGE_COPY
527 +#endif
528 +
529  #define PAGE_GATE      __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_X_RX)
530  #define PAGE_KERNEL    __pgprot(__DIRTY_BITS  | _PAGE_PL_0 | _PAGE_AR_RWX)
531  #define PAGE_KERNELRX  __pgprot(__ACCESS_BITS | _PAGE_PL_0 | _PAGE_AR_RX)
532 diff -urNp linux-2.6.27.10/arch/ia64/kernel/module.c linux-2.6.27.10/arch/ia64/kernel/module.c
533 --- linux-2.6.27.10/arch/ia64/kernel/module.c   2008-11-07 12:55:34.000000000 -0500
534 +++ linux-2.6.27.10/arch/ia64/kernel/module.c   2008-11-18 03:38:43.000000000 -0500
535 @@ -312,8 +312,7 @@ module_alloc (unsigned long size)
536  void
537  module_free (struct module *mod, void *module_region)
538  {
539 -       if (mod && mod->arch.init_unw_table &&
540 -           module_region == mod->module_init) {
541 +       if (mod && mod->arch.init_unw_table && module_region == mod->module_init_rx) {
542                 unw_remove_unwind_table(mod->arch.init_unw_table);
543                 mod->arch.init_unw_table = NULL;
544         }
545 @@ -491,15 +490,39 @@ module_frob_arch_sections (Elf_Ehdr *ehd
546  }
547  
548  static inline int
549 +in_init_rx (const struct module *mod, uint64_t addr)
550 +{
551 +       return addr - (uint64_t) mod->module_init_rx < mod->init_size_rx;
552 +}
553 +
554 +static inline int
555 +in_init_rw (const struct module *mod, uint64_t addr)
556 +{
557 +       return addr - (uint64_t) mod->module_init_rw < mod->init_size_rw;
558 +}
559 +
560 +static inline int
561  in_init (const struct module *mod, uint64_t addr)
562  {
563 -       return addr - (uint64_t) mod->module_init < mod->init_size;
564 +       return in_init_rx(mod, addr) || in_init_rw(mod, addr);
565 +}
566 +
567 +static inline int
568 +in_core_rx (const struct module *mod, uint64_t addr)
569 +{
570 +       return addr - (uint64_t) mod->module_core_rx < mod->core_size_rx;
571 +}
572 +
573 +static inline int
574 +in_core_rw (const struct module *mod, uint64_t addr)
575 +{
576 +       return addr - (uint64_t) mod->module_core_rw < mod->core_size_rw;
577  }
578  
579  static inline int
580  in_core (const struct module *mod, uint64_t addr)
581  {
582 -       return addr - (uint64_t) mod->module_core < mod->core_size;
583 +       return in_core_rx(mod, addr) || in_core_rw(mod, addr);
584  }
585  
586  static inline int
587 @@ -683,7 +706,14 @@ do_reloc (struct module *mod, uint8_t r_
588                 break;
589  
590               case RV_BDREL:
591 -               val -= (uint64_t) (in_init(mod, val) ? mod->module_init : mod->module_core);
592 +               if (in_init_rx(mod, val))
593 +                       val -= (uint64_t) mod->module_init_rx;
594 +               else if (in_init_rw(mod, val))
595 +                       val -= (uint64_t) mod->module_init_rw;
596 +               else if (in_core_rx(mod, val))
597 +                       val -= (uint64_t) mod->module_core_rx;
598 +               else if (in_core_rw(mod, val))
599 +                       val -= (uint64_t) mod->module_core_rw;
600                 break;
601  
602               case RV_LTV:
603 @@ -817,15 +847,15 @@ apply_relocate_add (Elf64_Shdr *sechdrs,
604                  *     addresses have been selected...
605                  */
606                 uint64_t gp;
607 -               if (mod->core_size > MAX_LTOFF)
608 +               if (mod->core_size_rx + mod->core_size_rw > MAX_LTOFF)
609                         /*
610                          * This takes advantage of fact that SHF_ARCH_SMALL gets allocated
611                          * at the end of the module.
612                          */
613 -                       gp = mod->core_size - MAX_LTOFF / 2;
614 +                       gp = mod->core_size_rx + mod->core_size_rw - MAX_LTOFF / 2;
615                 else
616 -                       gp = mod->core_size / 2;
617 -               gp = (uint64_t) mod->module_core + ((gp + 7) & -8);
618 +                       gp = (mod->core_size_rx + mod->core_size_rw) / 2;
619 +               gp = (uint64_t) mod->module_core_rx + ((gp + 7) & -8);
620                 mod->arch.gp = gp;
621                 DEBUGP("%s: placing gp at 0x%lx\n", __func__, gp);
622         }
623 diff -urNp linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c
624 --- linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c 2008-11-07 12:55:34.000000000 -0500
625 +++ linux-2.6.27.10/arch/ia64/kernel/sys_ia64.c 2008-11-18 03:38:43.000000000 -0500
626 @@ -43,6 +43,13 @@ arch_get_unmapped_area (struct file *fil
627         if (REGION_NUMBER(addr) == RGN_HPAGE)
628                 addr = 0;
629  #endif
630 +
631 +#ifdef CONFIG_PAX_RANDMMAP
632 +       if ((mm->pax_flags & MF_PAX_RANDMMAP) && addr && filp)
633 +               addr = mm->free_area_cache;
634 +       else
635 +#endif
636 +
637         if (!addr)
638                 addr = mm->free_area_cache;
639  
640 @@ -61,9 +68,9 @@ arch_get_unmapped_area (struct file *fil
641         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
642                 /* At this point:  (!vma || addr < vma->vm_end). */
643                 if (TASK_SIZE - len < addr || RGN_MAP_LIMIT - len < REGION_OFFSET(addr)) {
644 -                       if (start_addr != TASK_UNMAPPED_BASE) {
645 +                       if (start_addr != mm->mmap_base) {
646                                 /* Start a new search --- just in case we missed some holes.  */
647 -                               addr = TASK_UNMAPPED_BASE;
648 +                               addr = mm->mmap_base;
649                                 goto full_search;
650                         }
651                         return -ENOMEM;
652 diff -urNp linux-2.6.27.10/arch/ia64/mm/fault.c linux-2.6.27.10/arch/ia64/mm/fault.c
653 --- linux-2.6.27.10/arch/ia64/mm/fault.c        2008-11-07 12:55:34.000000000 -0500
654 +++ linux-2.6.27.10/arch/ia64/mm/fault.c        2008-11-18 03:38:43.000000000 -0500
655 @@ -72,6 +72,23 @@ mapped_kernel_page_is_present (unsigned 
656         return pte_present(pte);
657  }
658  
659 +#ifdef CONFIG_PAX_PAGEEXEC
660 +void pax_report_insns(void *pc, void *sp)
661 +{
662 +       unsigned long i;
663 +
664 +       printk(KERN_ERR "PAX: bytes at PC: ");
665 +       for (i = 0; i < 8; i++) {
666 +               unsigned int c;
667 +               if (get_user(c, (unsigned int *)pc+i))
668 +                       printk(KERN_CONT "???????? ");
669 +               else
670 +                       printk(KERN_CONT "%08x ", c);
671 +       }
672 +       printk("\n");
673 +}
674 +#endif
675 +
676  void __kprobes
677  ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
678  {
679 @@ -145,9 +162,23 @@ ia64_do_page_fault (unsigned long addres
680         mask = (  (((isr >> IA64_ISR_X_BIT) & 1UL) << VM_EXEC_BIT)
681                 | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT));
682  
683 -       if ((vma->vm_flags & mask) != mask)
684 +       if ((vma->vm_flags & mask) != mask) {
685 +
686 +#ifdef CONFIG_PAX_PAGEEXEC
687 +               if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) {
688 +                       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip)
689 +                               goto bad_area;
690 +
691 +                       up_read(&mm->mmap_sem);
692 +                       pax_report_fault(regs, (void *)regs->cr_iip, (void *)regs->r12);
693 +                       do_group_exit(SIGKILL);
694 +               }
695 +#endif
696 +
697                 goto bad_area;
698  
699 +       }
700 +
701    survive:
702         /*
703          * If for any reason at all we couldn't handle the fault, make
704 diff -urNp linux-2.6.27.10/arch/ia64/mm/init.c linux-2.6.27.10/arch/ia64/mm/init.c
705 --- linux-2.6.27.10/arch/ia64/mm/init.c 2008-11-07 12:55:34.000000000 -0500
706 +++ linux-2.6.27.10/arch/ia64/mm/init.c 2008-11-18 03:38:43.000000000 -0500
707 @@ -122,6 +122,19 @@ ia64_init_addr_space (void)
708                 vma->vm_start = current->thread.rbs_bot & PAGE_MASK;
709                 vma->vm_end = vma->vm_start + PAGE_SIZE;
710                 vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT;
711 +
712 +#ifdef CONFIG_PAX_PAGEEXEC
713 +               if (current->mm->pax_flags & MF_PAX_PAGEEXEC) {
714 +                       vma->vm_flags &= ~VM_EXEC;
715 +
716 +#ifdef CONFIG_PAX_MPROTECT
717 +                       if (current->mm->pax_flags & MF_PAX_MPROTECT)
718 +                               vma->vm_flags &= ~VM_MAYEXEC;
719 +#endif
720 +
721 +               }
722 +#endif
723 +
724                 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
725                 down_write(&current->mm->mmap_sem);
726                 if (insert_vm_struct(current->mm, vma)) {
727 diff -urNp linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h
728 --- linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h     2008-11-07 12:55:34.000000000 -0500
729 +++ linux-2.6.27.10/arch/m68knommu/include/asm/kmap_types.h     2008-11-18 03:39:50.000000000 -0500
730 @@ -15,6 +15,7 @@ enum km_type {
731         KM_IRQ1,
732         KM_SOFTIRQ0,
733         KM_SOFTIRQ1,
734 +       KM_CLEARPAGE,
735         KM_TYPE_NR
736  };
737  
738 diff -urNp linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c
739 --- linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c    2008-11-07 12:55:34.000000000 -0500
740 +++ linux-2.6.27.10/arch/mips/kernel/binfmt_elfn32.c    2008-11-18 03:38:43.000000000 -0500
741 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
742  #undef ELF_ET_DYN_BASE
743  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
744  
745 +#ifdef CONFIG_PAX_ASLR
746 +#define PAX_ELF_ET_DYN_BASE    (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
747 +
748 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
749 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
750 +#endif
751 +
752  #include <asm/processor.h>
753  #include <linux/module.h>
754  #include <linux/elfcore.h>
755 diff -urNp linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c
756 --- linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c    2008-11-07 12:55:34.000000000 -0500
757 +++ linux-2.6.27.10/arch/mips/kernel/binfmt_elfo32.c    2008-11-18 03:38:43.000000000 -0500
758 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N
759  #undef ELF_ET_DYN_BASE
760  #define ELF_ET_DYN_BASE         (TASK32_SIZE / 3 * 2)
761  
762 +#ifdef CONFIG_PAX_ASLR
763 +#define PAX_ELF_ET_DYN_BASE    (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
764 +
765 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
766 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
767 +#endif
768 +
769  #include <asm/processor.h>
770  #include <linux/module.h>
771  #include <linux/elfcore.h>
772 diff -urNp linux-2.6.27.10/arch/mips/kernel/process.c linux-2.6.27.10/arch/mips/kernel/process.c
773 --- linux-2.6.27.10/arch/mips/kernel/process.c  2008-11-07 12:55:34.000000000 -0500
774 +++ linux-2.6.27.10/arch/mips/kernel/process.c  2008-11-18 03:38:43.000000000 -0500
775 @@ -458,15 +458,3 @@ unsigned long get_wchan(struct task_stru
776  out:
777         return pc;
778  }
779 -
780 -/*
781 - * Don't forget that the stack pointer must be aligned on a 8 bytes
782 - * boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
783 - */
784 -unsigned long arch_align_stack(unsigned long sp)
785 -{
786 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
787 -               sp -= get_random_int() & ~PAGE_MASK;
788 -
789 -       return sp & ALMASK;
790 -}
791 diff -urNp linux-2.6.27.10/arch/mips/kernel/syscall.c linux-2.6.27.10/arch/mips/kernel/syscall.c
792 --- linux-2.6.27.10/arch/mips/kernel/syscall.c  2008-11-07 12:55:34.000000000 -0500
793 +++ linux-2.6.27.10/arch/mips/kernel/syscall.c  2008-11-18 03:38:43.000000000 -0500
794 @@ -100,6 +100,11 @@ unsigned long arch_get_unmapped_area(str
795         do_color_align = 0;
796         if (filp || (flags & MAP_SHARED))
797                 do_color_align = 1;
798 +
799 +#ifdef CONFIG_PAX_RANDMMAP
800 +       if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
801 +#endif
802 +
803         if (addr) {
804                 if (do_color_align)
805                         addr = COLOUR_ALIGN(addr, pgoff);
806 @@ -110,7 +115,7 @@ unsigned long arch_get_unmapped_area(str
807                     (!vmm || addr + len <= vmm->vm_start))
808                         return addr;
809         }
810 -       addr = TASK_UNMAPPED_BASE;
811 +       addr = current->mm->mmap_base;
812         if (do_color_align)
813                 addr = COLOUR_ALIGN(addr, pgoff);
814         else
815 diff -urNp linux-2.6.27.10/arch/mips/mm/fault.c linux-2.6.27.10/arch/mips/mm/fault.c
816 --- linux-2.6.27.10/arch/mips/mm/fault.c        2008-11-07 12:55:34.000000000 -0500
817 +++ linux-2.6.27.10/arch/mips/mm/fault.c        2008-11-18 03:38:43.000000000 -0500
818 @@ -26,6 +26,23 @@
819  #include <asm/ptrace.h>
820  #include <asm/highmem.h>               /* For VMALLOC_END */
821  
822 +#ifdef CONFIG_PAX_PAGEEXEC
823 +void pax_report_insns(void *pc)
824 +{
825 +       unsigned long i;
826 +
827 +       printk(KERN_ERR "PAX: bytes at PC: ");
828 +       for (i = 0; i < 5; i++) {
829 +               unsigned int c;
830 +               if (get_user(c, (unsigned int *)pc+i))
831 +                       printk(KERN_CONT "???????? ");
832 +               else
833 +                       printk(KERN_CONT "%08x ", c);
834 +       }
835 +       printk("\n");
836 +}
837 +#endif
838 +
839  /*
840   * This routine handles page faults.  It determines the address,
841   * and the problem, and then passes it off to one of the appropriate
842 diff -urNp linux-2.6.27.10/arch/parisc/kernel/module.c linux-2.6.27.10/arch/parisc/kernel/module.c
843 --- linux-2.6.27.10/arch/parisc/kernel/module.c 2008-11-07 12:55:34.000000000 -0500
844 +++ linux-2.6.27.10/arch/parisc/kernel/module.c 2008-11-18 03:38:43.000000000 -0500
845 @@ -75,16 +75,38 @@
846  
847  /* three functions to determine where in the module core
848   * or init pieces the location is */
849 +static inline int in_init_rx(struct module *me, void *loc)
850 +{
851 +       return (loc >= me->module_init_rx &&
852 +               loc < (me->module_init_rx + me->init_size_rx));
853 +}
854 +
855 +static inline int in_init_rw(struct module *me, void *loc)
856 +{
857 +       return (loc >= me->module_init_rw &&
858 +               loc < (me->module_init_rw + me->init_size_rw));
859 +}
860 +
861  static inline int in_init(struct module *me, void *loc)
862  {
863 -       return (loc >= me->module_init &&
864 -               loc <= (me->module_init + me->init_size));
865 +       return in_init_rx(me, loc) || in_init_rw(me, loc);
866 +}
867 +
868 +static inline int in_core_rx(struct module *me, void *loc)
869 +{
870 +       return (loc >= me->module_core_rx &&
871 +               loc < (me->module_core_rx + me->core_size_rx));
872 +}
873 +
874 +static inline int in_core_rw(struct module *me, void *loc)
875 +{
876 +       return (loc >= me->module_core_rw &&
877 +               loc < (me->module_core_rw + me->core_size_rw));
878  }
879  
880  static inline int in_core(struct module *me, void *loc)
881  {
882 -       return (loc >= me->module_core &&
883 -               loc <= (me->module_core + me->core_size));
884 +       return in_core_rx(me, loc) || in_core_rw(me, loc);
885  }
886  
887  static inline int in_local(struct module *me, void *loc)
888 @@ -298,21 +320,21 @@ int module_frob_arch_sections(CONST Elf_
889         }
890  
891         /* align things a bit */
892 -       me->core_size = ALIGN(me->core_size, 16);
893 -       me->arch.got_offset = me->core_size;
894 -       me->core_size += gots * sizeof(struct got_entry);
895 -
896 -       me->core_size = ALIGN(me->core_size, 16);
897 -       me->arch.fdesc_offset = me->core_size;
898 -       me->core_size += fdescs * sizeof(Elf_Fdesc);
899 -
900 -       me->core_size = ALIGN(me->core_size, 16);
901 -       me->arch.stub_offset = me->core_size;
902 -       me->core_size += stubs * sizeof(struct stub_entry);
903 -
904 -       me->init_size = ALIGN(me->init_size, 16);
905 -       me->arch.init_stub_offset = me->init_size;
906 -       me->init_size += init_stubs * sizeof(struct stub_entry);
907 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
908 +       me->arch.got_offset = me->core_size_rw;
909 +       me->core_size_rw += gots * sizeof(struct got_entry);
910 +
911 +       me->core_size_rw = ALIGN(me->core_size_rw, 16);
912 +       me->arch.fdesc_offset = me->core_size_rw;
913 +       me->core_size_rw += fdescs * sizeof(Elf_Fdesc);
914 +
915 +       me->core_size_rx = ALIGN(me->core_size_rx, 16);
916 +       me->arch.stub_offset = me->core_size_rx;
917 +       me->core_size_rx += stubs * sizeof(struct stub_entry);
918 +
919 +       me->init_size_rx = ALIGN(me->init_size_rx, 16);
920 +       me->arch.init_stub_offset = me->init_size_rx;
921 +       me->init_size_rx += init_stubs * sizeof(struct stub_entry);
922  
923         me->arch.got_max = gots;
924         me->arch.fdesc_max = fdescs;
925 @@ -332,7 +354,7 @@ static Elf64_Word get_got(struct module 
926  
927         BUG_ON(value == 0);
928  
929 -       got = me->module_core + me->arch.got_offset;
930 +       got = me->module_core_rw + me->arch.got_offset;
931         for (i = 0; got[i].addr; i++)
932                 if (got[i].addr == value)
933                         goto out;
934 @@ -350,7 +372,7 @@ static Elf64_Word get_got(struct module 
935  #ifdef CONFIG_64BIT
936  static Elf_Addr get_fdesc(struct module *me, unsigned long value)
937  {
938 -       Elf_Fdesc *fdesc = me->module_core + me->arch.fdesc_offset;
939 +       Elf_Fdesc *fdesc = me->module_core_rw + me->arch.fdesc_offset;
940  
941         if (!value) {
942                 printk(KERN_ERR "%s: zero OPD requested!\n", me->name);
943 @@ -368,7 +390,7 @@ static Elf_Addr get_fdesc(struct module 
944  
945         /* Create new one */
946         fdesc->addr = value;
947 -       fdesc->gp = (Elf_Addr)me->module_core + me->arch.got_offset;
948 +       fdesc->gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
949         return (Elf_Addr)fdesc;
950  }
951  #endif /* CONFIG_64BIT */
952 @@ -388,12 +410,12 @@ static Elf_Addr get_stub(struct module *
953         if(init_section) {
954                 i = me->arch.init_stub_count++;
955                 BUG_ON(me->arch.init_stub_count > me->arch.init_stub_max);
956 -               stub = me->module_init + me->arch.init_stub_offset + 
957 +               stub = me->module_init_rx + me->arch.init_stub_offset +
958                         i * sizeof(struct stub_entry);
959         } else {
960                 i = me->arch.stub_count++;
961                 BUG_ON(me->arch.stub_count > me->arch.stub_max);
962 -               stub = me->module_core + me->arch.stub_offset + 
963 +               stub = me->module_core_rx + me->arch.stub_offset +
964                         i * sizeof(struct stub_entry);
965         }
966  
967 @@ -761,7 +783,7 @@ register_unwind_table(struct module *me,
968  
969         table = (unsigned char *)sechdrs[me->arch.unwind_section].sh_addr;
970         end = table + sechdrs[me->arch.unwind_section].sh_size;
971 -       gp = (Elf_Addr)me->module_core + me->arch.got_offset;
972 +       gp = (Elf_Addr)me->module_core_rw + me->arch.got_offset;
973  
974         DEBUGP("register_unwind_table(), sect = %d at 0x%p - 0x%p (gp=0x%lx)\n",
975                me->arch.unwind_section, table, end, gp);
976 diff -urNp linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c
977 --- linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c     2008-11-07 12:55:34.000000000 -0500
978 +++ linux-2.6.27.10/arch/parisc/kernel/sys_parisc.c     2008-11-18 03:38:43.000000000 -0500
979 @@ -98,7 +98,7 @@ unsigned long arch_get_unmapped_area(str
980         if (flags & MAP_FIXED)
981                 return addr;
982         if (!addr)
983 -               addr = TASK_UNMAPPED_BASE;
984 +               addr = current->mm->mmap_base;
985  
986         if (filp) {
987                 addr = get_shared_area(filp->f_mapping, addr, len, pgoff);
988 diff -urNp linux-2.6.27.10/arch/parisc/kernel/traps.c linux-2.6.27.10/arch/parisc/kernel/traps.c
989 --- linux-2.6.27.10/arch/parisc/kernel/traps.c  2008-12-10 22:35:36.000000000 -0500
990 +++ linux-2.6.27.10/arch/parisc/kernel/traps.c  2008-12-10 22:35:46.000000000 -0500
991 @@ -731,9 +731,7 @@ void handle_interruption(int code, struc
992  
993                         down_read(&current->mm->mmap_sem);
994                         vma = find_vma(current->mm,regs->iaoq[0]);
995 -                       if (vma && (regs->iaoq[0] >= vma->vm_start)
996 -                               && (vma->vm_flags & VM_EXEC)) {
997 -
998 +                       if (vma && (regs->iaoq[0] >= vma->vm_start)) {
999                                 fault_address = regs->iaoq[0];
1000                                 fault_space = regs->iasq[0];
1001  
1002 diff -urNp linux-2.6.27.10/arch/parisc/mm/fault.c linux-2.6.27.10/arch/parisc/mm/fault.c
1003 --- linux-2.6.27.10/arch/parisc/mm/fault.c      2008-11-07 12:55:34.000000000 -0500
1004 +++ linux-2.6.27.10/arch/parisc/mm/fault.c      2008-11-18 03:38:43.000000000 -0500
1005 @@ -16,6 +16,7 @@
1006  #include <linux/sched.h>
1007  #include <linux/interrupt.h>
1008  #include <linux/module.h>
1009 +#include <linux/unistd.h>
1010  
1011  #include <asm/uaccess.h>
1012  #include <asm/traps.h>
1013 @@ -53,7 +54,7 @@ DEFINE_PER_CPU(struct exception_data, ex
1014  static unsigned long
1015  parisc_acctyp(unsigned long code, unsigned int inst)
1016  {
1017 -       if (code == 6 || code == 16)
1018 +       if (code == 6 || code == 7 || code == 16)
1019             return VM_EXEC;
1020  
1021         switch (inst & 0xf0000000) {
1022 @@ -139,6 +140,116 @@ parisc_acctyp(unsigned long code, unsign
1023                         }
1024  #endif
1025  
1026 +#ifdef CONFIG_PAX_PAGEEXEC
1027 +/*
1028 + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address)
1029 + *
1030 + * returns 1 when task should be killed
1031 + *         2 when rt_sigreturn trampoline was detected
1032 + *         3 when unpatched PLT trampoline was detected
1033 + */
1034 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1035 +{
1036 +
1037 +#ifdef CONFIG_PAX_EMUPLT
1038 +       int err;
1039 +
1040 +       do { /* PaX: unpatched PLT emulation */
1041 +               unsigned int bl, depwi;
1042 +
1043 +               err = get_user(bl, (unsigned int *)instruction_pointer(regs));
1044 +               err |= get_user(depwi, (unsigned int *)(instruction_pointer(regs)+4));
1045 +
1046 +               if (err)
1047 +                       break;
1048 +
1049 +               if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) {
1050 +                       unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12;
1051 +
1052 +                       err = get_user(ldw, (unsigned int *)addr);
1053 +                       err |= get_user(bv, (unsigned int *)(addr+4));
1054 +                       err |= get_user(ldw2, (unsigned int *)(addr+8));
1055 +
1056 +                       if (err)
1057 +                               break;
1058 +
1059 +                       if (ldw == 0x0E801096U &&
1060 +                           bv == 0xEAC0C000U &&
1061 +                           ldw2 == 0x0E881095U)
1062 +                       {
1063 +                               unsigned int resolver, map;
1064 +
1065 +                               err = get_user(resolver, (unsigned int *)(instruction_pointer(regs)+8));
1066 +                               err |= get_user(map, (unsigned int *)(instruction_pointer(regs)+12));
1067 +                               if (err)
1068 +                                       break;
1069 +
1070 +                               regs->gr[20] = instruction_pointer(regs)+8;
1071 +                               regs->gr[21] = map;
1072 +                               regs->gr[22] = resolver;
1073 +                               regs->iaoq[0] = resolver | 3UL;
1074 +                               regs->iaoq[1] = regs->iaoq[0] + 4;
1075 +                               return 3;
1076 +                       }
1077 +               }
1078 +       } while (0);
1079 +#endif
1080 +
1081 +#ifdef CONFIG_PAX_EMUTRAMP
1082 +
1083 +#ifndef CONFIG_PAX_EMUSIGRT
1084 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
1085 +               return 1;
1086 +#endif
1087 +
1088 +       do { /* PaX: rt_sigreturn emulation */
1089 +               unsigned int ldi1, ldi2, bel, nop;
1090 +
1091 +               err = get_user(ldi1, (unsigned int *)instruction_pointer(regs));
1092 +               err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4));
1093 +               err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8));
1094 +               err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12));
1095 +
1096 +               if (err)
1097 +                       break;
1098 +
1099 +               if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) &&
1100 +                   ldi2 == 0x3414015AU &&
1101 +                   bel == 0xE4008200U &&
1102 +                   nop == 0x08000240U)
1103 +               {
1104 +                       regs->gr[25] = (ldi1 & 2) >> 1;
1105 +                       regs->gr[20] = __NR_rt_sigreturn;
1106 +                       regs->gr[31] = regs->iaoq[1] + 16;
1107 +                       regs->sr[0] = regs->iasq[1];
1108 +                       regs->iaoq[0] = 0x100UL;
1109 +                       regs->iaoq[1] = regs->iaoq[0] + 4;
1110 +                       regs->iasq[0] = regs->sr[2];
1111 +                       regs->iasq[1] = regs->sr[2];
1112 +                       return 2;
1113 +               }
1114 +       } while (0);
1115 +#endif
1116 +
1117 +       return 1;
1118 +}
1119 +
1120 +void pax_report_insns(void *pc, void *sp)
1121 +{
1122 +       unsigned long i;
1123 +
1124 +       printk(KERN_ERR "PAX: bytes at PC: ");
1125 +       for (i = 0; i < 5; i++) {
1126 +               unsigned int c;
1127 +               if (get_user(c, (unsigned int *)pc+i))
1128 +                       printk(KERN_CONT "???????? ");
1129 +               else
1130 +                       printk(KERN_CONT "%08x ", c);
1131 +       }
1132 +       printk("\n");
1133 +}
1134 +#endif
1135 +
1136  void do_page_fault(struct pt_regs *regs, unsigned long code,
1137                               unsigned long address)
1138  {
1139 @@ -165,8 +276,33 @@ good_area:
1140  
1141         acc_type = parisc_acctyp(code,regs->iir);
1142  
1143 -       if ((vma->vm_flags & acc_type) != acc_type)
1144 +       if ((vma->vm_flags & acc_type) != acc_type) {
1145 +
1146 +#ifdef CONFIG_PAX_PAGEEXEC
1147 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) &&
1148 +                   (address & ~3UL) == instruction_pointer(regs))
1149 +               {
1150 +                       up_read(&mm->mmap_sem);
1151 +                       switch (pax_handle_fetch_fault(regs)) {
1152 +
1153 +#ifdef CONFIG_PAX_EMUPLT
1154 +                       case 3:
1155 +                               return;
1156 +#endif
1157 +
1158 +#ifdef CONFIG_PAX_EMUTRAMP
1159 +                       case 2:
1160 +                               return;
1161 +#endif
1162 +
1163 +                       }
1164 +                       pax_report_fault(regs, (void *)instruction_pointer(regs), (void *)regs->gr[30]);
1165 +                       do_group_exit(SIGKILL);
1166 +               }
1167 +#endif
1168 +
1169                 goto bad_area;
1170 +       }
1171  
1172         /*
1173          * If for any reason at all we couldn't handle the fault, make
1174 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/elf.h linux-2.6.27.10/arch/powerpc/include/asm/elf.h
1175 --- linux-2.6.27.10/arch/powerpc/include/asm/elf.h      2008-11-07 12:55:34.000000000 -0500
1176 +++ linux-2.6.27.10/arch/powerpc/include/asm/elf.h      2008-11-18 03:39:50.000000000 -0500
1177 @@ -180,6 +180,18 @@ typedef elf_fpreg_t elf_vsrreghalf_t32[E
1178  
1179  #define ELF_ET_DYN_BASE         (0x20000000)
1180  
1181 +#ifdef CONFIG_PAX_ASLR
1182 +#define PAX_ELF_ET_DYN_BASE    (0x10000000UL)
1183 +
1184 +#ifdef __powerpc64__
1185 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT) ? 16 : 28)
1186 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT) ? 16 : 28)
1187 +#else
1188 +#define PAX_DELTA_MMAP_LEN     15
1189 +#define PAX_DELTA_STACK_LEN    15
1190 +#endif
1191 +#endif
1192 +
1193  /*
1194   * Our registers are always unsigned longs, whether we're a 32 bit
1195   * process or 64 bit, on either a 64 bit or 32 bit kernel.
1196 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h
1197 --- linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h       2008-11-07 12:55:34.000000000 -0500
1198 +++ linux-2.6.27.10/arch/powerpc/include/asm/kmap_types.h       2008-11-18 03:39:50.000000000 -0500
1199 @@ -26,6 +26,7 @@ enum km_type {
1200         KM_SOFTIRQ1,
1201         KM_PPC_SYNC_PAGE,
1202         KM_PPC_SYNC_ICACHE,
1203 +       KM_CLEARPAGE,
1204         KM_TYPE_NR
1205  };
1206  
1207 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/page_64.h linux-2.6.27.10/arch/powerpc/include/asm/page_64.h
1208 --- linux-2.6.27.10/arch/powerpc/include/asm/page_64.h  2008-11-07 12:55:34.000000000 -0500
1209 +++ linux-2.6.27.10/arch/powerpc/include/asm/page_64.h  2008-11-18 03:39:50.000000000 -0500
1210 @@ -170,15 +170,18 @@ do {                                              \
1211   * stack by default, so in the absense of a PT_GNU_STACK program header
1212   * we turn execute permission off.
1213   */
1214 -#define VM_STACK_DEFAULT_FLAGS32       (VM_READ | VM_WRITE | VM_EXEC | \
1215 -                                        VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1216 +#define VM_STACK_DEFAULT_FLAGS32 \
1217 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1218 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1219  
1220  #define VM_STACK_DEFAULT_FLAGS64       (VM_READ | VM_WRITE | \
1221                                          VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1222  
1223 +#ifndef CONFIG_PAX_PAGEEXEC
1224  #define VM_STACK_DEFAULT_FLAGS \
1225         (test_thread_flag(TIF_32BIT) ? \
1226          VM_STACK_DEFAULT_FLAGS32 : VM_STACK_DEFAULT_FLAGS64)
1227 +#endif
1228  
1229  #include <asm-generic/page.h>
1230  
1231 diff -urNp linux-2.6.27.10/arch/powerpc/include/asm/page.h linux-2.6.27.10/arch/powerpc/include/asm/page.h
1232 --- linux-2.6.27.10/arch/powerpc/include/asm/page.h     2008-11-07 12:55:34.000000000 -0500
1233 +++ linux-2.6.27.10/arch/powerpc/include/asm/page.h     2008-11-18 03:39:50.000000000 -0500
1234 @@ -100,8 +100,9 @@ extern phys_addr_t kernstart_addr;
1235   * and needs to be executable.  This means the whole heap ends
1236   * up being executable.
1237   */
1238 -#define VM_DATA_DEFAULT_FLAGS32        (VM_READ | VM_WRITE | VM_EXEC | \
1239 -                                VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1240 +#define VM_DATA_DEFAULT_FLAGS32 \
1241 +       (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
1242 +        VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1243  
1244  #define VM_DATA_DEFAULT_FLAGS64        (VM_READ | VM_WRITE | \
1245                                  VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
1246 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/module_32.c linux-2.6.27.10/arch/powerpc/kernel/module_32.c
1247 --- linux-2.6.27.10/arch/powerpc/kernel/module_32.c     2008-11-07 12:55:34.000000000 -0500
1248 +++ linux-2.6.27.10/arch/powerpc/kernel/module_32.c     2008-11-18 03:38:43.000000000 -0500
1249 @@ -158,7 +158,7 @@ int module_frob_arch_sections(Elf32_Ehdr
1250                         me->arch.core_plt_section = i;
1251         }
1252         if (!me->arch.core_plt_section || !me->arch.init_plt_section) {
1253 -               printk("Module doesn't contain .plt or .init.plt sections.\n");
1254 +               printk("Module %s doesn't contain .plt or .init.plt sections.\n", me->name);
1255                 return -ENOEXEC;
1256         }
1257  
1258 @@ -199,11 +199,16 @@ static uint32_t do_plt_call(void *locati
1259  
1260         DEBUGP("Doing plt for call to 0x%x at 0x%x\n", val, (unsigned int)location);
1261         /* Init, or core PLT? */
1262 -       if (location >= mod->module_core
1263 -           && location < mod->module_core + mod->core_size)
1264 +       if ((location >= mod->module_core_rx && location < mod->module_core_rx + mod->core_size_rx) ||
1265 +           (location >= mod->module_core_rw && location < mod->module_core_rw + mod->core_size_rw))
1266                 entry = (void *)sechdrs[mod->arch.core_plt_section].sh_addr;
1267 -       else
1268 +       else if ((location >= mod->module_init_rx && location < mod->module_init_rx + mod->init_size_rx) ||
1269 +                (location >= mod->module_init_rw && location < mod->module_init_rw + mod->init_size_rw))
1270                 entry = (void *)sechdrs[mod->arch.init_plt_section].sh_addr;
1271 +       else {
1272 +               printk(KERN_ERR "%s: invalid R_PPC_REL24 entry found\n", mod->name);
1273 +               return ~0UL;
1274 +       }
1275  
1276         /* Find this entry, or if that fails, the next avail. entry */
1277         while (entry->jump[0]) {
1278 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/signal_32.c linux-2.6.27.10/arch/powerpc/kernel/signal_32.c
1279 --- linux-2.6.27.10/arch/powerpc/kernel/signal_32.c     2008-11-07 12:55:34.000000000 -0500
1280 +++ linux-2.6.27.10/arch/powerpc/kernel/signal_32.c     2008-11-18 03:38:43.000000000 -0500
1281 @@ -857,7 +857,7 @@ int handle_rt_signal32(unsigned long sig
1282         /* Save user registers on the stack */
1283         frame = &rt_sf->uc.uc_mcontext;
1284         addr = frame;
1285 -       if (vdso32_rt_sigtramp && current->mm->context.vdso_base) {
1286 +       if (vdso32_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1287                 if (save_user_regs(regs, frame, 0, 1))
1288                         goto badframe;
1289                 regs->link = current->mm->context.vdso_base + vdso32_rt_sigtramp;
1290 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/signal_64.c linux-2.6.27.10/arch/powerpc/kernel/signal_64.c
1291 --- linux-2.6.27.10/arch/powerpc/kernel/signal_64.c     2008-11-07 12:55:34.000000000 -0500
1292 +++ linux-2.6.27.10/arch/powerpc/kernel/signal_64.c     2008-11-18 03:38:43.000000000 -0500
1293 @@ -434,7 +434,7 @@ int handle_rt_signal64(int signr, struct
1294         current->thread.fpscr.val = 0;
1295  
1296         /* Set up to return from userspace. */
1297 -       if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
1298 +       if (vdso64_rt_sigtramp && current->mm->context.vdso_base != ~0UL) {
1299                 regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
1300         } else {
1301                 err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
1302 diff -urNp linux-2.6.27.10/arch/powerpc/kernel/vdso.c linux-2.6.27.10/arch/powerpc/kernel/vdso.c
1303 --- linux-2.6.27.10/arch/powerpc/kernel/vdso.c  2008-11-07 12:55:34.000000000 -0500
1304 +++ linux-2.6.27.10/arch/powerpc/kernel/vdso.c  2008-11-18 03:38:43.000000000 -0500
1305 @@ -212,7 +212,7 @@ int arch_setup_additional_pages(struct l
1306         vdso_base = VDSO32_MBASE;
1307  #endif
1308  
1309 -       current->mm->context.vdso_base = 0;
1310 +       current->mm->context.vdso_base = ~0UL;
1311  
1312         /* vDSO has a problem and was disabled, just don't "enable" it for the
1313          * process
1314 @@ -229,7 +229,7 @@ int arch_setup_additional_pages(struct l
1315          */
1316         down_write(&mm->mmap_sem);
1317         vdso_base = get_unmapped_area(NULL, vdso_base,
1318 -                                     vdso_pages << PAGE_SHIFT, 0, 0);
1319 +                                     vdso_pages << PAGE_SHIFT, 0, MAP_PRIVATE | MAP_EXECUTABLE);
1320         if (IS_ERR_VALUE(vdso_base)) {
1321                 rc = vdso_base;
1322                 goto fail_mmapsem;
1323 diff -urNp linux-2.6.27.10/arch/powerpc/mm/fault.c linux-2.6.27.10/arch/powerpc/mm/fault.c
1324 --- linux-2.6.27.10/arch/powerpc/mm/fault.c     2008-11-07 12:55:34.000000000 -0500
1325 +++ linux-2.6.27.10/arch/powerpc/mm/fault.c     2008-11-18 03:38:43.000000000 -0500
1326 @@ -29,6 +29,10 @@
1327  #include <linux/module.h>
1328  #include <linux/kprobes.h>
1329  #include <linux/kdebug.h>
1330 +#include <linux/slab.h>
1331 +#include <linux/pagemap.h>
1332 +#include <linux/compiler.h>
1333 +#include <linux/unistd.h>
1334  
1335  #include <asm/page.h>
1336  #include <asm/pgtable.h>
1337 @@ -62,6 +66,363 @@ static inline int notify_page_fault(stru
1338  }
1339  #endif
1340  
1341 +#ifdef CONFIG_PAX_EMUSIGRT
1342 +void pax_syscall_close(struct vm_area_struct *vma)
1343 +{
1344 +       vma->vm_mm->call_syscall = 0UL;
1345 +}
1346 +
1347 +static int pax_syscall_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1348 +{
1349 +       unsigned int *kaddr;
1350 +
1351 +       vmf->page = alloc_page(GFP_HIGHUSER);
1352 +       if (!vmf->page)
1353 +               return VM_FAULT_OOM;
1354 +
1355 +       kaddr = kmap(vmf->page);
1356 +       memset(kaddr, 0, PAGE_SIZE);
1357 +       kaddr[0] = 0x44000002U; /* sc */
1358 +       __flush_dcache_icache(kaddr);
1359 +       kunmap(vmf->page);
1360 +       return VM_FAULT_MAJOR;
1361 +}
1362 +
1363 +static struct vm_operations_struct pax_vm_ops = {
1364 +       .close = pax_syscall_close,
1365 +       .fault = pax_syscall_fault
1366 +};
1367 +
1368 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
1369 +{
1370 +       int ret;
1371 +
1372 +       vma->vm_mm = current->mm;
1373 +       vma->vm_start = addr;
1374 +       vma->vm_end = addr + PAGE_SIZE;
1375 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
1376 +       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
1377 +       vma->vm_ops = &pax_vm_ops;
1378 +
1379 +       ret = insert_vm_struct(current->mm, vma);
1380 +       if (ret)
1381 +               return ret;
1382 +
1383 +       ++current->mm->total_vm;
1384 +       return 0;
1385 +}
1386 +#endif
1387 +
1388 +#ifdef CONFIG_PAX_PAGEEXEC
1389 +/*
1390 + * PaX: decide what to do with offenders (regs->nip = fault address)
1391 + *
1392 + * returns 1 when task should be killed
1393 + *         2 when patched GOT trampoline was detected
1394 + *         3 when patched PLT trampoline was detected
1395 + *         4 when unpatched PLT trampoline was detected
1396 + *         5 when sigreturn trampoline was detected
1397 + *         6 when rt_sigreturn trampoline was detected
1398 + */
1399 +static int pax_handle_fetch_fault(struct pt_regs *regs)
1400 +{
1401 +
1402 +#if defined(CONFIG_PAX_EMUPLT) || defined(CONFIG_PAX_EMUSIGRT)
1403 +       int err;
1404 +#endif
1405 +
1406 +#ifdef CONFIG_PAX_EMUPLT
1407 +       do { /* PaX: patched GOT emulation */
1408 +               unsigned int blrl;
1409 +
1410 +               err = get_user(blrl, (unsigned int *)regs->nip);
1411 +
1412 +               if (!err && blrl == 0x4E800021U) {
1413 +                       unsigned long temp = regs->nip;
1414 +
1415 +                       regs->nip = regs->link & 0xFFFFFFFCUL;
1416 +                       regs->link = temp + 4UL;
1417 +                       return 2;
1418 +               }
1419 +       } while (0);
1420 +
1421 +       do { /* PaX: patched PLT emulation #1 */
1422 +               unsigned int b;
1423 +
1424 +               err = get_user(b, (unsigned int *)regs->nip);
1425 +
1426 +               if (!err && (b & 0xFC000003U) == 0x48000000U) {
1427 +                       regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL);
1428 +                       return 3;
1429 +               }
1430 +       } while (0);
1431 +
1432 +       do { /* PaX: unpatched PLT emulation #1 */
1433 +               unsigned int li, b;
1434 +
1435 +               err = get_user(li, (unsigned int *)regs->nip);
1436 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
1437 +
1438 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1439 +                       unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1440 +                       unsigned long addr = b | 0xFC000000UL;
1441 +
1442 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1443 +                       err = get_user(rlwinm, (unsigned int *)addr);
1444 +                       err |= get_user(add, (unsigned int *)(addr+4));
1445 +                       err |= get_user(li2, (unsigned int *)(addr+8));
1446 +                       err |= get_user(addis2, (unsigned int *)(addr+12));
1447 +                       err |= get_user(mtctr, (unsigned int *)(addr+16));
1448 +                       err |= get_user(li3, (unsigned int *)(addr+20));
1449 +                       err |= get_user(addis3, (unsigned int *)(addr+24));
1450 +                       err |= get_user(bctr, (unsigned int *)(addr+28));
1451 +
1452 +                       if (err)
1453 +                               break;
1454 +
1455 +                       if (rlwinm == 0x556C083CU &&
1456 +                           add == 0x7D6C5A14U &&
1457 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
1458 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1459 +                           mtctr == 0x7D8903A6U &&
1460 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
1461 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1462 +                           bctr == 0x4E800420U)
1463 +                       {
1464 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1465 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1466 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1467 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1468 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
1469 +                               regs->nip = regs->ctr;
1470 +                               return 4;
1471 +                       }
1472 +               }
1473 +       } while (0);
1474 +
1475 +#if 0
1476 +       do { /* PaX: unpatched PLT emulation #2 */
1477 +               unsigned int lis, lwzu, b, bctr;
1478 +
1479 +               err = get_user(lis, (unsigned int *)regs->nip);
1480 +               err |= get_user(lwzu, (unsigned int *)(regs->nip+4));
1481 +               err |= get_user(b, (unsigned int *)(regs->nip+8));
1482 +               err |= get_user(bctr, (unsigned int *)(regs->nip+12));
1483 +
1484 +               if (err)
1485 +                       break;
1486 +
1487 +               if ((lis & 0xFFFF0000U) == 0x39600000U &&
1488 +                   (lwzu & 0xU) == 0xU &&
1489 +                   (b & 0xFC000003U) == 0x48000000U &&
1490 +                   bctr == 0x4E800420U)
1491 +               {
1492 +                       unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr;
1493 +                       unsigned long addr = b | 0xFC000000UL;
1494 +
1495 +                       addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1496 +                       err = get_user(addis, (unsigned int *)addr);
1497 +                       err |= get_user(addi, (unsigned int *)(addr+4));
1498 +                       err |= get_user(rlwinm, (unsigned int *)(addr+8));
1499 +                       err |= get_user(add, (unsigned int *)(addr+12));
1500 +                       err |= get_user(li2, (unsigned int *)(addr+16));
1501 +                       err |= get_user(addis2, (unsigned int *)(addr+20));
1502 +                       err |= get_user(mtctr, (unsigned int *)(addr+24));
1503 +                       err |= get_user(li3, (unsigned int *)(addr+28));
1504 +                       err |= get_user(addis3, (unsigned int *)(addr+32));
1505 +                       err |= get_user(bctr, (unsigned int *)(addr+36));
1506 +
1507 +                       if (err)
1508 +                               break;
1509 +
1510 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1511 +                           (addi & 0xFFFF0000U) == 0x396B0000U &&
1512 +                           rlwinm == 0x556C083CU &&
1513 +                           add == 0x7D6C5A14U &&
1514 +                           (li2 & 0xFFFF0000U) == 0x39800000U &&
1515 +                           (addis2 & 0xFFFF0000U) == 0x3D8C0000U &&
1516 +                           mtctr == 0x7D8903A6U &&
1517 +                           (li3 & 0xFFFF0000U) == 0x39800000U &&
1518 +                           (addis3 & 0xFFFF0000U) == 0x3D8C0000U &&
1519 +                           bctr == 0x4E800420U)
1520 +                       {
1521 +                               regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1522 +                               regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1523 +                               regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16;
1524 +                               regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1525 +                               regs->ctr += (addis2 & 0xFFFFU) << 16;
1526 +                               regs->nip = regs->ctr;
1527 +                               return 4;
1528 +                       }
1529 +               }
1530 +       } while (0);
1531 +#endif
1532 +
1533 +       do { /* PaX: unpatched PLT emulation #3 */
1534 +               unsigned int li, b;
1535 +
1536 +               err = get_user(li, (unsigned int *)regs->nip);
1537 +               err |= get_user(b, (unsigned int *)(regs->nip+4));
1538 +
1539 +               if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) {
1540 +                       unsigned int addis, lwz, mtctr, bctr;
1541 +                       unsigned long addr = b | 0xFC000000UL;
1542 +
1543 +                       addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL);
1544 +                       err = get_user(addis, (unsigned int *)addr);
1545 +                       err |= get_user(lwz, (unsigned int *)(addr+4));
1546 +                       err |= get_user(mtctr, (unsigned int *)(addr+8));
1547 +                       err |= get_user(bctr, (unsigned int *)(addr+12));
1548 +
1549 +                       if (err)
1550 +                               break;
1551 +
1552 +                       if ((addis & 0xFFFF0000U) == 0x3D6B0000U &&
1553 +                           (lwz & 0xFFFF0000U) == 0x816B0000U &&
1554 +                           mtctr == 0x7D6903A6U &&
1555 +                           bctr == 0x4E800420U)
1556 +                       {
1557 +                               unsigned int r11;
1558 +
1559 +                               addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1560 +                               addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL);
1561 +
1562 +                               err = get_user(r11, (unsigned int *)addr);
1563 +                               if (err)
1564 +                                       break;
1565 +
1566 +                               regs->gpr[PT_R11] = r11;
1567 +                               regs->ctr = r11;
1568 +                               regs->nip = r11;
1569 +                               return 4;
1570 +                       }
1571 +               }
1572 +       } while (0);
1573 +#endif
1574 +
1575 +#ifdef CONFIG_PAX_EMUSIGRT
1576 +       do { /* PaX: sigreturn emulation */
1577 +               unsigned int li, sc;
1578 +
1579 +               err = get_user(li, (unsigned int *)regs->nip);
1580 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
1581 +
1582 +               if (!err && li == 0x38000000U + __NR_sigreturn && sc == 0x44000002U) {
1583 +                       struct vm_area_struct *vma;
1584 +                       unsigned long call_syscall;
1585 +
1586 +                       down_read(&current->mm->mmap_sem);
1587 +                       call_syscall = current->mm->call_syscall;
1588 +                       up_read(&current->mm->mmap_sem);
1589 +                       if (likely(call_syscall))
1590 +                               goto emulate;
1591 +
1592 +                       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1593 +
1594 +                       down_write(&current->mm->mmap_sem);
1595 +                       if (current->mm->call_syscall) {
1596 +                               call_syscall = current->mm->call_syscall;
1597 +                               up_write(&current->mm->mmap_sem);
1598 +                               if (vma)
1599 +                                       kmem_cache_free(vm_area_cachep, vma);
1600 +                               goto emulate;
1601 +                       }
1602 +
1603 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1604 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
1605 +                               up_write(&current->mm->mmap_sem);
1606 +                               if (vma)
1607 +                                       kmem_cache_free(vm_area_cachep, vma);
1608 +                               return 1;
1609 +                       }
1610 +
1611 +                       if (pax_insert_vma(vma, call_syscall)) {
1612 +                               up_write(&current->mm->mmap_sem);
1613 +                               kmem_cache_free(vm_area_cachep, vma);
1614 +                               return 1;
1615 +                       }
1616 +
1617 +                       current->mm->call_syscall = call_syscall;
1618 +                       up_write(&current->mm->mmap_sem);
1619 +
1620 +emulate:
1621 +                       regs->gpr[PT_R0] = __NR_sigreturn;
1622 +                       regs->nip = call_syscall;
1623 +                       return 5;
1624 +               }
1625 +       } while (0);
1626 +
1627 +       do { /* PaX: rt_sigreturn emulation */
1628 +               unsigned int li, sc;
1629 +
1630 +               err = get_user(li, (unsigned int *)regs->nip);
1631 +               err |= get_user(sc, (unsigned int *)(regs->nip+4));
1632 +
1633 +               if (!err && li == 0x38000000U + __NR_rt_sigreturn && sc == 0x44000002U) {
1634 +                       struct vm_area_struct *vma;
1635 +                       unsigned int call_syscall;
1636 +
1637 +                       down_read(&current->mm->mmap_sem);
1638 +                       call_syscall = current->mm->call_syscall;
1639 +                       up_read(&current->mm->mmap_sem);
1640 +                       if (likely(call_syscall))
1641 +                               goto rt_emulate;
1642 +
1643 +                       vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
1644 +
1645 +                       down_write(&current->mm->mmap_sem);
1646 +                       if (current->mm->call_syscall) {
1647 +                               call_syscall = current->mm->call_syscall;
1648 +                               up_write(&current->mm->mmap_sem);
1649 +                               if (vma)
1650 +                                       kmem_cache_free(vm_area_cachep, vma);
1651 +                               goto rt_emulate;
1652 +                       }
1653 +
1654 +                       call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
1655 +                       if (!vma || (call_syscall & ~PAGE_MASK)) {
1656 +                               up_write(&current->mm->mmap_sem);
1657 +                               if (vma)
1658 +                                       kmem_cache_free(vm_area_cachep, vma);
1659 +                               return 1;
1660 +                       }
1661 +
1662 +                       if (pax_insert_vma(vma, call_syscall)) {
1663 +                               up_write(&current->mm->mmap_sem);
1664 +                               kmem_cache_free(vm_area_cachep, vma);
1665 +                               return 1;
1666 +                       }
1667 +
1668 +                       current->mm->call_syscall = call_syscall;
1669 +                       up_write(&current->mm->mmap_sem);
1670 +
1671 +rt_emulate:
1672 +                       regs->gpr[PT_R0] = __NR_rt_sigreturn;
1673 +                       regs->nip = call_syscall;
1674 +                       return 6;
1675 +               }
1676 +       } while (0);
1677 +#endif
1678 +
1679 +       return 1;
1680 +}
1681 +
1682 +void pax_report_insns(void *pc, void *sp)
1683 +{
1684 +       unsigned long i;
1685 +
1686 +       printk(KERN_ERR "PAX: bytes at PC: ");
1687 +       for (i = 0; i < 5; i++) {
1688 +               unsigned int c;
1689 +               if (get_user(c, (unsigned int *)pc+i))
1690 +                       printk(KERN_CONT "???????? ");
1691 +               else
1692 +                       printk(KERN_CONT "%08x ", c);
1693 +       }
1694 +       printk("\n");
1695 +}
1696 +#endif
1697 +
1698  /*
1699   * Check whether the instruction at regs->nip is a store using
1700   * an update addressing form which will update r1.
1701 @@ -132,7 +493,7 @@ int __kprobes do_page_fault(struct pt_re
1702          * indicate errors in DSISR but can validly be set in SRR1.
1703          */
1704         if (trap == 0x400)
1705 -               error_code &= 0x48200000;
1706 +               error_code &= 0x58200000;
1707         else
1708                 is_write = error_code & DSISR_ISSTORE;
1709  #else
1710 @@ -331,6 +692,37 @@ bad_area:
1711  bad_area_nosemaphore:
1712         /* User mode accesses cause a SIGSEGV */
1713         if (user_mode(regs)) {
1714 +
1715 +#ifdef CONFIG_PAX_PAGEEXEC
1716 +               if (mm->pax_flags & MF_PAX_PAGEEXEC) {
1717 +#ifdef CONFIG_PPC64
1718 +                       if (is_exec && (error_code & DSISR_PROTFAULT)) {
1719 +#else
1720 +                       if (is_exec && regs->nip == address) {
1721 +#endif
1722 +                               switch (pax_handle_fetch_fault(regs)) {
1723 +
1724 +#ifdef CONFIG_PAX_EMUPLT
1725 +                               case 2:
1726 +                               case 3:
1727 +                               case 4:
1728 +                                       return 0;
1729 +#endif
1730 +
1731 +#ifdef CONFIG_PAX_EMUSIGRT
1732 +                               case 5:
1733 +                               case 6:
1734 +                                       return 0;
1735 +#endif
1736 +
1737 +                               }
1738 +
1739 +                               pax_report_fault(regs, (void *)regs->nip, (void *)regs->gpr[PT_R1]);
1740 +                               do_group_exit(SIGKILL);
1741 +                       }
1742 +               }
1743 +#endif
1744 +
1745                 _exception(SIGSEGV, regs, code, address);
1746                 return 0;
1747         }
1748 diff -urNp linux-2.6.27.10/arch/powerpc/mm/mmap.c linux-2.6.27.10/arch/powerpc/mm/mmap.c
1749 --- linux-2.6.27.10/arch/powerpc/mm/mmap.c      2008-11-07 12:55:34.000000000 -0500
1750 +++ linux-2.6.27.10/arch/powerpc/mm/mmap.c      2008-11-18 03:38:43.000000000 -0500
1751 @@ -75,10 +75,22 @@ void arch_pick_mmap_layout(struct mm_str
1752          */
1753         if (mmap_is_legacy()) {
1754                 mm->mmap_base = TASK_UNMAPPED_BASE;
1755 +
1756 +#ifdef CONFIG_PAX_RANDMMAP
1757 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
1758 +                       mm->mmap_base += mm->delta_mmap;
1759 +#endif
1760 +
1761                 mm->get_unmapped_area = arch_get_unmapped_area;
1762                 mm->unmap_area = arch_unmap_area;
1763         } else {
1764                 mm->mmap_base = mmap_base();
1765 +
1766 +#ifdef CONFIG_PAX_RANDMMAP
1767 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
1768 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
1769 +#endif
1770 +
1771                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
1772                 mm->unmap_area = arch_unmap_area_topdown;
1773         }
1774 diff -urNp linux-2.6.27.10/arch/s390/include/asm/kmap_types.h linux-2.6.27.10/arch/s390/include/asm/kmap_types.h
1775 --- linux-2.6.27.10/arch/s390/include/asm/kmap_types.h  2008-11-07 12:55:34.000000000 -0500
1776 +++ linux-2.6.27.10/arch/s390/include/asm/kmap_types.h  2008-11-18 03:39:50.000000000 -0500
1777 @@ -16,6 +16,7 @@ enum km_type {
1778         KM_IRQ1,
1779         KM_SOFTIRQ0,
1780         KM_SOFTIRQ1,    
1781 +       KM_CLEARPAGE,
1782         KM_TYPE_NR
1783  };
1784  
1785 diff -urNp linux-2.6.27.10/arch/s390/kernel/module.c linux-2.6.27.10/arch/s390/kernel/module.c
1786 --- linux-2.6.27.10/arch/s390/kernel/module.c   2008-11-07 12:55:34.000000000 -0500
1787 +++ linux-2.6.27.10/arch/s390/kernel/module.c   2008-11-18 03:38:43.000000000 -0500
1788 @@ -166,11 +166,11 @@ module_frob_arch_sections(Elf_Ehdr *hdr,
1789  
1790         /* Increase core size by size of got & plt and set start
1791            offsets for got and plt. */
1792 -       me->core_size = ALIGN(me->core_size, 4);
1793 -       me->arch.got_offset = me->core_size;
1794 -       me->core_size += me->arch.got_size;
1795 -       me->arch.plt_offset = me->core_size;
1796 -       me->core_size += me->arch.plt_size;
1797 +       me->core_size_rw = ALIGN(me->core_size_rw, 4);
1798 +       me->arch.got_offset = me->core_size_rw;
1799 +       me->core_size_rw += me->arch.got_size;
1800 +       me->arch.plt_offset = me->core_size_rx;
1801 +       me->core_size_rx += me->arch.plt_size;
1802         return 0;
1803  }
1804  
1805 @@ -256,7 +256,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1806                 if (info->got_initialized == 0) {
1807                         Elf_Addr *gotent;
1808  
1809 -                       gotent = me->module_core + me->arch.got_offset +
1810 +                       gotent = me->module_core_rw + me->arch.got_offset +
1811                                 info->got_offset;
1812                         *gotent = val;
1813                         info->got_initialized = 1;
1814 @@ -280,7 +280,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1815                 else if (r_type == R_390_GOTENT ||
1816                          r_type == R_390_GOTPLTENT)
1817                         *(unsigned int *) loc =
1818 -                               (val + (Elf_Addr) me->module_core - loc) >> 1;
1819 +                               (val + (Elf_Addr) me->module_core_rw - loc) >> 1;
1820                 else if (r_type == R_390_GOT64 ||
1821                          r_type == R_390_GOTPLT64)
1822                         *(unsigned long *) loc = val;
1823 @@ -294,7 +294,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1824         case R_390_PLTOFF64:    /* 16 bit offset from GOT to PLT. */
1825                 if (info->plt_initialized == 0) {
1826                         unsigned int *ip;
1827 -                       ip = me->module_core + me->arch.plt_offset +
1828 +                       ip = me->module_core_rx + me->arch.plt_offset +
1829                                 info->plt_offset;
1830  #ifndef CONFIG_64BIT
1831                         ip[0] = 0x0d105810; /* basr 1,0; l 1,6(1); br 1 */
1832 @@ -316,7 +316,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1833                         val = me->arch.plt_offset - me->arch.got_offset +
1834                                 info->plt_offset + rela->r_addend;
1835                 else
1836 -                       val =  (Elf_Addr) me->module_core +
1837 +                       val =  (Elf_Addr) me->module_core_rx +
1838                                 me->arch.plt_offset + info->plt_offset + 
1839                                 rela->r_addend - loc;
1840                 if (r_type == R_390_PLT16DBL)
1841 @@ -336,7 +336,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1842         case R_390_GOTOFF32:    /* 32 bit offset to GOT.  */
1843         case R_390_GOTOFF64:    /* 64 bit offset to GOT. */
1844                 val = val + rela->r_addend -
1845 -                       ((Elf_Addr) me->module_core + me->arch.got_offset);
1846 +                       ((Elf_Addr) me->module_core_rw + me->arch.got_offset);
1847                 if (r_type == R_390_GOTOFF16)
1848                         *(unsigned short *) loc = val;
1849                 else if (r_type == R_390_GOTOFF32)
1850 @@ -346,7 +346,7 @@ apply_rela(Elf_Rela *rela, Elf_Addr base
1851                 break;
1852         case R_390_GOTPC:       /* 32 bit PC relative offset to GOT. */
1853         case R_390_GOTPCDBL:    /* 32 bit PC rel. off. to GOT shifted by 1. */
1854 -               val = (Elf_Addr) me->module_core + me->arch.got_offset +
1855 +               val = (Elf_Addr) me->module_core_rw + me->arch.got_offset +
1856                         rela->r_addend - loc;
1857                 if (r_type == R_390_GOTPC)
1858                         *(unsigned int *) loc = val;
1859 diff -urNp linux-2.6.27.10/arch/sh/include/asm/kmap_types.h linux-2.6.27.10/arch/sh/include/asm/kmap_types.h
1860 --- linux-2.6.27.10/arch/sh/include/asm/kmap_types.h    2008-11-07 12:55:34.000000000 -0500
1861 +++ linux-2.6.27.10/arch/sh/include/asm/kmap_types.h    2008-11-18 03:39:50.000000000 -0500
1862 @@ -24,7 +24,8 @@ D(9)  KM_IRQ0,
1863  D(10)  KM_IRQ1,
1864  D(11)  KM_SOFTIRQ0,
1865  D(12)  KM_SOFTIRQ1,
1866 -D(13)  KM_TYPE_NR
1867 +D(13)  KM_CLEARPAGE,
1868 +D(14)  KM_TYPE_NR
1869  };
1870  
1871  #undef D
1872 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/elf_32.h linux-2.6.27.10/arch/sparc/include/asm/elf_32.h
1873 --- linux-2.6.27.10/arch/sparc/include/asm/elf_32.h     2008-11-07 12:55:34.000000000 -0500
1874 +++ linux-2.6.27.10/arch/sparc/include/asm/elf_32.h     2008-11-18 03:39:50.000000000 -0500
1875 @@ -119,6 +119,13 @@ typedef struct {
1876  
1877  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE)
1878  
1879 +#ifdef CONFIG_PAX_ASLR
1880 +#define PAX_ELF_ET_DYN_BASE    0x10000UL
1881 +
1882 +#define PAX_DELTA_MMAP_LEN     16
1883 +#define PAX_DELTA_STACK_LEN    16
1884 +#endif
1885 +
1886  /* This yields a mask that user programs can use to figure out what
1887     instruction set this cpu supports.  This can NOT be done in userspace
1888     on Sparc.  */
1889 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/elf_64.h linux-2.6.27.10/arch/sparc/include/asm/elf_64.h
1890 --- linux-2.6.27.10/arch/sparc/include/asm/elf_64.h     2008-11-07 12:55:34.000000000 -0500
1891 +++ linux-2.6.27.10/arch/sparc/include/asm/elf_64.h     2008-11-18 03:39:50.000000000 -0500
1892 @@ -163,6 +163,12 @@ typedef struct {
1893  #define ELF_ET_DYN_BASE                0x0000010000000000UL
1894  #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL
1895  
1896 +#ifdef CONFIG_PAX_ASLR
1897 +#define PAX_ELF_ET_DYN_BASE    (test_thread_flag(TIF_32BIT) ? 0x10000UL : 0x100000UL)
1898 +
1899 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT) ? 14 : 28 )
1900 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT) ? 15 : 29 )
1901 +#endif
1902  
1903  /* This yields a mask that user programs can use to figure out what
1904     instruction set this cpu supports.  */
1905 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h
1906 --- linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
1907 +++ linux-2.6.27.10/arch/sparc/include/asm/kmap_types.h 2008-11-18 03:39:50.000000000 -0500
1908 @@ -19,6 +19,7 @@ enum km_type {
1909         KM_IRQ1,
1910         KM_SOFTIRQ0,
1911         KM_SOFTIRQ1,
1912 +       KM_CLEARPAGE,
1913         KM_TYPE_NR
1914  };
1915  
1916 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h
1917 --- linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h 2008-11-07 12:55:34.000000000 -0500
1918 +++ linux-2.6.27.10/arch/sparc/include/asm/pgtable_32.h 2008-11-18 03:39:50.000000000 -0500
1919 @@ -47,6 +47,13 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd)
1920  BTFIXUPDEF_INT(page_none)
1921  BTFIXUPDEF_INT(page_copy)
1922  BTFIXUPDEF_INT(page_readonly)
1923 +
1924 +#ifdef CONFIG_PAX_PAGEEXEC
1925 +BTFIXUPDEF_INT(page_shared_noexec)
1926 +BTFIXUPDEF_INT(page_copy_noexec)
1927 +BTFIXUPDEF_INT(page_readonly_noexec)
1928 +#endif
1929 +
1930  BTFIXUPDEF_INT(page_kernel)
1931  
1932  #define PMD_SHIFT              SUN4C_PMD_SHIFT
1933 @@ -68,6 +75,16 @@ extern pgprot_t PAGE_SHARED;
1934  #define PAGE_COPY      __pgprot(BTFIXUP_INT(page_copy))
1935  #define PAGE_READONLY  __pgprot(BTFIXUP_INT(page_readonly))
1936  
1937 +#ifdef CONFIG_PAX_PAGEEXEC
1938 +extern pgprot_t PAGE_SHARED_NOEXEC;
1939 +# define PAGE_COPY_NOEXEC      __pgprot(BTFIXUP_INT(page_copy_noexec))
1940 +# define PAGE_READONLY_NOEXEC  __pgprot(BTFIXUP_INT(page_readonly_noexec))
1941 +#else
1942 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
1943 +# define PAGE_COPY_NOEXEC      PAGE_COPY
1944 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
1945 +#endif
1946 +
1947  extern unsigned long page_kernel;
1948  
1949  #ifdef MODULE
1950 diff -urNp linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h
1951 --- linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h   2008-11-07 12:55:34.000000000 -0500
1952 +++ linux-2.6.27.10/arch/sparc/include/asm/pgtsrmmu.h   2008-11-18 03:39:50.000000000 -0500
1953 @@ -115,6 +115,13 @@
1954                                     SRMMU_EXEC | SRMMU_REF)
1955  #define SRMMU_PAGE_RDONLY  __pgprot(SRMMU_VALID | SRMMU_CACHE | \
1956                                     SRMMU_EXEC | SRMMU_REF)
1957 +
1958 +#ifdef CONFIG_PAX_PAGEEXEC
1959 +#define SRMMU_PAGE_SHARED_NOEXEC       __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_WRITE | SRMMU_REF)
1960 +#define SRMMU_PAGE_COPY_NOEXEC __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
1961 +#define SRMMU_PAGE_RDONLY_NOEXEC       __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_REF)
1962 +#endif
1963 +
1964  #define SRMMU_PAGE_KERNEL  __pgprot(SRMMU_VALID | SRMMU_CACHE | SRMMU_PRIV | \
1965                                     SRMMU_DIRTY | SRMMU_REF)
1966  
1967 diff -urNp linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c
1968 --- linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c       2008-11-07 12:55:34.000000000 -0500
1969 +++ linux-2.6.27.10/arch/sparc/kernel/sys_sparc.c       2008-11-18 03:38:43.000000000 -0500
1970 @@ -56,7 +56,7 @@ unsigned long arch_get_unmapped_area(str
1971         if (ARCH_SUN4C_SUN4 && len > 0x20000000)
1972                 return -ENOMEM;
1973         if (!addr)
1974 -               addr = TASK_UNMAPPED_BASE;
1975 +               addr = current->mm->mmap_base;
1976  
1977         if (flags & MAP_SHARED)
1978                 addr = COLOUR_ALIGN(addr);
1979 diff -urNp linux-2.6.27.10/arch/sparc/Makefile linux-2.6.27.10/arch/sparc/Makefile
1980 --- linux-2.6.27.10/arch/sparc/Makefile 2008-11-07 12:55:34.000000000 -0500
1981 +++ linux-2.6.27.10/arch/sparc/Makefile 2008-11-18 03:38:43.000000000 -0500
1982 @@ -37,7 +37,7 @@ drivers-$(CONFIG_OPROFILE)    += arch/sparc
1983  # Renaming is done to avoid confusing pattern matching rules in 2.5.45 (multy-)
1984  INIT_Y         := $(patsubst %/, %/built-in.o, $(init-y))
1985  CORE_Y         := $(core-y)
1986 -CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
1987 +CORE_Y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
1988  CORE_Y         := $(patsubst %/, %/built-in.o, $(CORE_Y))
1989  DRIVERS_Y      := $(patsubst %/, %/built-in.o, $(drivers-y))
1990  NET_Y          := $(patsubst %/, %/built-in.o, $(net-y))
1991 diff -urNp linux-2.6.27.10/arch/sparc/mm/fault.c linux-2.6.27.10/arch/sparc/mm/fault.c
1992 --- linux-2.6.27.10/arch/sparc/mm/fault.c       2008-11-07 12:55:34.000000000 -0500
1993 +++ linux-2.6.27.10/arch/sparc/mm/fault.c       2008-11-18 03:38:43.000000000 -0500
1994 @@ -21,6 +21,9 @@
1995  #include <linux/interrupt.h>
1996  #include <linux/module.h>
1997  #include <linux/kdebug.h>
1998 +#include <linux/slab.h>
1999 +#include <linux/pagemap.h>
2000 +#include <linux/compiler.h>
2001  
2002  #include <asm/system.h>
2003  #include <asm/page.h>
2004 @@ -167,6 +170,249 @@ static unsigned long compute_si_addr(str
2005         return safe_compute_effective_address(regs, insn);
2006  }
2007  
2008 +#ifdef CONFIG_PAX_PAGEEXEC
2009 +void pax_emuplt_close(struct vm_area_struct *vma)
2010 +{
2011 +       vma->vm_mm->call_dl_resolve = 0UL;
2012 +}
2013 +
2014 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2015 +{
2016 +       unsigned int *kaddr;
2017 +
2018 +       vmf->page = alloc_page(GFP_HIGHUSER);
2019 +       if (!vmf->page)
2020 +               return VM_FAULT_OOM;
2021 +
2022 +       kaddr = kmap(vmf->page);
2023 +       memset(kaddr, 0, PAGE_SIZE);
2024 +       kaddr[0] = 0x9DE3BFA8U; /* save */
2025 +       flush_dcache_page(vmf->page);
2026 +       kunmap(vmf->page);
2027 +       return VM_FAULT_MAJOR;
2028 +}
2029 +
2030 +static struct vm_operations_struct pax_vm_ops = {
2031 +       .close = pax_emuplt_close,
2032 +       .fault = pax_emuplt_fault
2033 +};
2034 +
2035 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2036 +{
2037 +       int ret;
2038 +
2039 +       vma->vm_mm = current->mm;
2040 +       vma->vm_start = addr;
2041 +       vma->vm_end = addr + PAGE_SIZE;
2042 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2043 +       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2044 +       vma->vm_ops = &pax_vm_ops;
2045 +
2046 +       ret = insert_vm_struct(current->mm, vma);
2047 +       if (ret)
2048 +               return ret;
2049 +
2050 +       ++current->mm->total_vm;
2051 +       return 0;
2052 +}
2053 +
2054 +/*
2055 + * PaX: decide what to do with offenders (regs->pc = fault address)
2056 + *
2057 + * returns 1 when task should be killed
2058 + *         2 when patched PLT trampoline was detected
2059 + *         3 when unpatched PLT trampoline was detected
2060 + */
2061 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2062 +{
2063 +
2064 +#ifdef CONFIG_PAX_EMUPLT
2065 +       int err;
2066 +
2067 +       do { /* PaX: patched PLT emulation #1 */
2068 +               unsigned int sethi1, sethi2, jmpl;
2069 +
2070 +               err = get_user(sethi1, (unsigned int *)regs->pc);
2071 +               err |= get_user(sethi2, (unsigned int *)(regs->pc+4));
2072 +               err |= get_user(jmpl, (unsigned int *)(regs->pc+8));
2073 +
2074 +               if (err)
2075 +                       break;
2076 +
2077 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2078 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
2079 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
2080 +               {
2081 +                       unsigned int addr;
2082 +
2083 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2084 +                       addr = regs->u_regs[UREG_G1];
2085 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2086 +                       regs->pc = addr;
2087 +                       regs->npc = addr+4;
2088 +                       return 2;
2089 +               }
2090 +       } while (0);
2091 +
2092 +       { /* PaX: patched PLT emulation #2 */
2093 +               unsigned int ba;
2094 +
2095 +               err = get_user(ba, (unsigned int *)regs->pc);
2096 +
2097 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2098 +                       unsigned int addr;
2099 +
2100 +                       addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2101 +                       regs->pc = addr;
2102 +                       regs->npc = addr+4;
2103 +                       return 2;
2104 +               }
2105 +       }
2106 +
2107 +       do { /* PaX: patched PLT emulation #3 */
2108 +               unsigned int sethi, jmpl, nop;
2109 +
2110 +               err = get_user(sethi, (unsigned int *)regs->pc);
2111 +               err |= get_user(jmpl, (unsigned int *)(regs->pc+4));
2112 +               err |= get_user(nop, (unsigned int *)(regs->pc+8));
2113 +
2114 +               if (err)
2115 +                       break;
2116 +
2117 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2118 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2119 +                   nop == 0x01000000U)
2120 +               {
2121 +                       unsigned int addr;
2122 +
2123 +                       addr = (sethi & 0x003FFFFFU) << 10;
2124 +                       regs->u_regs[UREG_G1] = addr;
2125 +                       addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U);
2126 +                       regs->pc = addr;
2127 +                       regs->npc = addr+4;
2128 +                       return 2;
2129 +               }
2130 +       } while (0);
2131 +
2132 +       do { /* PaX: unpatched PLT emulation step 1 */
2133 +               unsigned int sethi, ba, nop;
2134 +
2135 +               err = get_user(sethi, (unsigned int *)regs->pc);
2136 +               err |= get_user(ba, (unsigned int *)(regs->pc+4));
2137 +               err |= get_user(nop, (unsigned int *)(regs->pc+8));
2138 +
2139 +               if (err)
2140 +                       break;
2141 +
2142 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2143 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2144 +                   nop == 0x01000000U)
2145 +               {
2146 +                       unsigned int addr, save, call;
2147 +
2148 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
2149 +                               addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2);
2150 +                       else
2151 +                               addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2);
2152 +
2153 +                       err = get_user(save, (unsigned int *)addr);
2154 +                       err |= get_user(call, (unsigned int *)(addr+4));
2155 +                       err |= get_user(nop, (unsigned int *)(addr+8));
2156 +                       if (err)
2157 +                               break;
2158 +
2159 +                       if (save == 0x9DE3BFA8U &&
2160 +                           (call & 0xC0000000U) == 0x40000000U &&
2161 +                           nop == 0x01000000U)
2162 +                       {
2163 +                               struct vm_area_struct *vma;
2164 +                               unsigned long call_dl_resolve;
2165 +
2166 +                               down_read(&current->mm->mmap_sem);
2167 +                               call_dl_resolve = current->mm->call_dl_resolve;
2168 +                               up_read(&current->mm->mmap_sem);
2169 +                               if (likely(call_dl_resolve))
2170 +                                       goto emulate;
2171 +
2172 +                               vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2173 +
2174 +                               down_write(&current->mm->mmap_sem);
2175 +                               if (current->mm->call_dl_resolve) {
2176 +                                       call_dl_resolve = current->mm->call_dl_resolve;
2177 +                                       up_write(&current->mm->mmap_sem);
2178 +                                       if (vma)
2179 +                                               kmem_cache_free(vm_area_cachep, vma);
2180 +                                       goto emulate;
2181 +                               }
2182 +
2183 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2184 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2185 +                                       up_write(&current->mm->mmap_sem);
2186 +                                       if (vma)
2187 +                                               kmem_cache_free(vm_area_cachep, vma);
2188 +                                       return 1;
2189 +                               }
2190 +
2191 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
2192 +                                       up_write(&current->mm->mmap_sem);
2193 +                                       kmem_cache_free(vm_area_cachep, vma);
2194 +                                       return 1;
2195 +                               }
2196 +
2197 +                               current->mm->call_dl_resolve = call_dl_resolve;
2198 +                               up_write(&current->mm->mmap_sem);
2199 +
2200 +emulate:
2201 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2202 +                               regs->pc = call_dl_resolve;
2203 +                               regs->npc = addr+4;
2204 +                               return 3;
2205 +                       }
2206 +               }
2207 +       } while (0);
2208 +
2209 +       do { /* PaX: unpatched PLT emulation step 2 */
2210 +               unsigned int save, call, nop;
2211 +
2212 +               err = get_user(save, (unsigned int *)(regs->pc-4));
2213 +               err |= get_user(call, (unsigned int *)regs->pc);
2214 +               err |= get_user(nop, (unsigned int *)(regs->pc+4));
2215 +               if (err)
2216 +                       break;
2217 +
2218 +               if (save == 0x9DE3BFA8U &&
2219 +                   (call & 0xC0000000U) == 0x40000000U &&
2220 +                   nop == 0x01000000U)
2221 +               {
2222 +                       unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2);
2223 +
2224 +                       regs->u_regs[UREG_RETPC] = regs->pc;
2225 +                       regs->pc = dl_resolve;
2226 +                       regs->npc = dl_resolve+4;
2227 +                       return 3;
2228 +               }
2229 +       } while (0);
2230 +#endif
2231 +
2232 +       return 1;
2233 +}
2234 +
2235 +void pax_report_insns(void *pc, void *sp)
2236 +{
2237 +       unsigned long i;
2238 +
2239 +       printk(KERN_ERR "PAX: bytes at PC: ");
2240 +       for (i = 0; i < 5; i++) {
2241 +               unsigned int c;
2242 +               if (get_user(c, (unsigned int *)pc+i))
2243 +                       printk(KERN_CONT "???????? ");
2244 +               else
2245 +                       printk(KERN_CONT "%08x ", c);
2246 +       }
2247 +       printk("\n");
2248 +}
2249 +#endif
2250 +
2251  asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write,
2252                                unsigned long address)
2253  {
2254 @@ -231,6 +477,24 @@ good_area:
2255                 if(!(vma->vm_flags & VM_WRITE))
2256                         goto bad_area;
2257         } else {
2258 +
2259 +#ifdef CONFIG_PAX_PAGEEXEC
2260 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) {
2261 +                       up_read(&mm->mmap_sem);
2262 +                       switch (pax_handle_fetch_fault(regs)) {
2263 +
2264 +#ifdef CONFIG_PAX_EMUPLT
2265 +                       case 2:
2266 +                       case 3:
2267 +                               return;
2268 +#endif
2269 +
2270 +                       }
2271 +                       pax_report_fault(regs, (void *)regs->pc, (void *)regs->u_regs[UREG_FP]);
2272 +                       do_group_exit(SIGKILL);
2273 +               }
2274 +#endif
2275 +
2276                 /* Allow reads even for write-only mappings */
2277                 if(!(vma->vm_flags & (VM_READ | VM_EXEC)))
2278                         goto bad_area;
2279 diff -urNp linux-2.6.27.10/arch/sparc/mm/init.c linux-2.6.27.10/arch/sparc/mm/init.c
2280 --- linux-2.6.27.10/arch/sparc/mm/init.c        2008-11-07 12:55:34.000000000 -0500
2281 +++ linux-2.6.27.10/arch/sparc/mm/init.c        2008-11-18 03:38:43.000000000 -0500
2282 @@ -312,6 +312,9 @@ extern void device_scan(void);
2283  pgprot_t PAGE_SHARED __read_mostly;
2284  EXPORT_SYMBOL(PAGE_SHARED);
2285  
2286 +pgprot_t PAGE_SHARED_NOEXEC __read_mostly;
2287 +EXPORT_SYMBOL(PAGE_SHARED_NOEXEC);
2288 +
2289  void __init paging_init(void)
2290  {
2291         switch(sparc_cpu_model) {
2292 @@ -337,17 +340,17 @@ void __init paging_init(void)
2293  
2294         /* Initialize the protection map with non-constant, MMU dependent values. */
2295         protection_map[0] = PAGE_NONE;
2296 -       protection_map[1] = PAGE_READONLY;
2297 -       protection_map[2] = PAGE_COPY;
2298 -       protection_map[3] = PAGE_COPY;
2299 +       protection_map[1] = PAGE_READONLY_NOEXEC;
2300 +       protection_map[2] = PAGE_COPY_NOEXEC;
2301 +       protection_map[3] = PAGE_COPY_NOEXEC;
2302         protection_map[4] = PAGE_READONLY;
2303         protection_map[5] = PAGE_READONLY;
2304         protection_map[6] = PAGE_COPY;
2305         protection_map[7] = PAGE_COPY;
2306         protection_map[8] = PAGE_NONE;
2307 -       protection_map[9] = PAGE_READONLY;
2308 -       protection_map[10] = PAGE_SHARED;
2309 -       protection_map[11] = PAGE_SHARED;
2310 +       protection_map[9] = PAGE_READONLY_NOEXEC;
2311 +       protection_map[10] = PAGE_SHARED_NOEXEC;
2312 +       protection_map[11] = PAGE_SHARED_NOEXEC;
2313         protection_map[12] = PAGE_READONLY;
2314         protection_map[13] = PAGE_READONLY;
2315         protection_map[14] = PAGE_SHARED;
2316 diff -urNp linux-2.6.27.10/arch/sparc/mm/srmmu.c linux-2.6.27.10/arch/sparc/mm/srmmu.c
2317 --- linux-2.6.27.10/arch/sparc/mm/srmmu.c       2008-11-07 12:55:34.000000000 -0500
2318 +++ linux-2.6.27.10/arch/sparc/mm/srmmu.c       2008-11-18 03:38:43.000000000 -0500
2319 @@ -2163,6 +2163,13 @@ void __init ld_mmu_srmmu(void)
2320         PAGE_SHARED = pgprot_val(SRMMU_PAGE_SHARED);
2321         BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY));
2322         BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY));
2323 +
2324 +#ifdef CONFIG_PAX_PAGEEXEC
2325 +       PAGE_SHARED_NOEXEC = pgprot_val(SRMMU_PAGE_SHARED_NOEXEC);
2326 +       BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC));
2327 +       BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC));
2328 +#endif
2329 +
2330         BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL));
2331         page_kernel = pgprot_val(SRMMU_PAGE_KERNEL);
2332  
2333 diff -urNp linux-2.6.27.10/arch/sparc64/kernel/Makefile linux-2.6.27.10/arch/sparc64/kernel/Makefile
2334 --- linux-2.6.27.10/arch/sparc64/kernel/Makefile        2008-11-07 12:55:34.000000000 -0500
2335 +++ linux-2.6.27.10/arch/sparc64/kernel/Makefile        2008-11-18 03:38:43.000000000 -0500
2336 @@ -3,7 +3,7 @@
2337  #
2338  
2339  EXTRA_AFLAGS := -ansi
2340 -EXTRA_CFLAGS := -Werror
2341 +#EXTRA_CFLAGS := -Werror
2342  
2343  extra-y                := head.o init_task.o vmlinux.lds
2344  
2345 diff -urNp linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c
2346 --- linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c     2008-11-07 12:55:34.000000000 -0500
2347 +++ linux-2.6.27.10/arch/sparc64/kernel/sys_sparc.c     2008-11-18 03:38:43.000000000 -0500
2348 @@ -124,7 +124,7 @@ unsigned long arch_get_unmapped_area(str
2349                 /* We do not accept a shared mapping if it would violate
2350                  * cache aliasing constraints.
2351                  */
2352 -               if ((flags & MAP_SHARED) &&
2353 +               if ((filp || (flags & MAP_SHARED)) &&
2354                     ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2355                         return -EINVAL;
2356                 return addr;
2357 @@ -139,6 +139,10 @@ unsigned long arch_get_unmapped_area(str
2358         if (filp || (flags & MAP_SHARED))
2359                 do_color_align = 1;
2360  
2361 +#ifdef CONFIG_PAX_RANDMMAP
2362 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
2363 +#endif
2364 +
2365         if (addr) {
2366                 if (do_color_align)
2367                         addr = COLOUR_ALIGN(addr, pgoff);
2368 @@ -152,9 +156,9 @@ unsigned long arch_get_unmapped_area(str
2369         }
2370  
2371         if (len > mm->cached_hole_size) {
2372 -               start_addr = addr = mm->free_area_cache;
2373 +               start_addr = addr = mm->free_area_cache;
2374         } else {
2375 -               start_addr = addr = TASK_UNMAPPED_BASE;
2376 +               start_addr = addr = mm->mmap_base;
2377                 mm->cached_hole_size = 0;
2378         }
2379  
2380 @@ -174,8 +178,8 @@ full_search:
2381                         vma = find_vma(mm, VA_EXCLUDE_END);
2382                 }
2383                 if (unlikely(task_size < addr)) {
2384 -                       if (start_addr != TASK_UNMAPPED_BASE) {
2385 -                               start_addr = addr = TASK_UNMAPPED_BASE;
2386 +                       if (start_addr != mm->mmap_base) {
2387 +                               start_addr = addr = mm->mmap_base;
2388                                 mm->cached_hole_size = 0;
2389                                 goto full_search;
2390                         }
2391 @@ -215,7 +219,7 @@ arch_get_unmapped_area_topdown(struct fi
2392                 /* We do not accept a shared mapping if it would violate
2393                  * cache aliasing constraints.
2394                  */
2395 -               if ((flags & MAP_SHARED) &&
2396 +               if ((filp || (flags & MAP_SHARED)) &&
2397                     ((addr - (pgoff << PAGE_SHIFT)) & (SHMLBA - 1)))
2398                         return -EINVAL;
2399                 return addr;
2400 @@ -378,6 +382,12 @@ void arch_pick_mmap_layout(struct mm_str
2401             current->signal->rlim[RLIMIT_STACK].rlim_cur == RLIM_INFINITY ||
2402             sysctl_legacy_va_layout) {
2403                 mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
2404 +
2405 +#ifdef CONFIG_PAX_RANDMMAP
2406 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2407 +                       mm->mmap_base += mm->delta_mmap;
2408 +#endif
2409 +
2410                 mm->get_unmapped_area = arch_get_unmapped_area;
2411                 mm->unmap_area = arch_unmap_area;
2412         } else {
2413 @@ -392,6 +402,12 @@ void arch_pick_mmap_layout(struct mm_str
2414                         gap = (task_size / 6 * 5);
2415  
2416                 mm->mmap_base = PAGE_ALIGN(task_size - gap - random_factor);
2417 +
2418 +#ifdef CONFIG_PAX_RANDMMAP
2419 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
2420 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
2421 +#endif
2422 +
2423                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
2424                 mm->unmap_area = arch_unmap_area_topdown;
2425         }
2426 diff -urNp linux-2.6.27.10/arch/sparc64/mm/fault.c linux-2.6.27.10/arch/sparc64/mm/fault.c
2427 --- linux-2.6.27.10/arch/sparc64/mm/fault.c     2008-11-07 12:55:34.000000000 -0500
2428 +++ linux-2.6.27.10/arch/sparc64/mm/fault.c     2008-11-18 03:38:43.000000000 -0500
2429 @@ -19,6 +19,9 @@
2430  #include <linux/interrupt.h>
2431  #include <linux/kprobes.h>
2432  #include <linux/kdebug.h>
2433 +#include <linux/slab.h>
2434 +#include <linux/pagemap.h>
2435 +#include <linux/compiler.h>
2436  
2437  #include <asm/page.h>
2438  #include <asm/pgtable.h>
2439 @@ -261,6 +264,367 @@ cannot_handle:
2440         unhandled_fault (address, current, regs);
2441  }
2442  
2443 +#ifdef CONFIG_PAX_PAGEEXEC
2444 +#ifdef CONFIG_PAX_EMUPLT
2445 +static void pax_emuplt_close(struct vm_area_struct *vma)
2446 +{
2447 +       vma->vm_mm->call_dl_resolve = 0UL;
2448 +}
2449 +
2450 +static int pax_emuplt_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
2451 +{
2452 +       unsigned int *kaddr;
2453 +
2454 +       vmf->page = alloc_page(GFP_HIGHUSER);
2455 +       if (!vmf->page)
2456 +               return VM_FAULT_OOM;
2457 +
2458 +       kaddr = kmap(vmf->page);
2459 +       memset(kaddr, 0, PAGE_SIZE);
2460 +       kaddr[0] = 0x9DE3BFA8U; /* save */
2461 +       flush_dcache_page(vmf->page);
2462 +       kunmap(vmf->page);
2463 +       return VM_FAULT_MAJOR;
2464 +}
2465 +
2466 +static struct vm_operations_struct pax_vm_ops = {
2467 +       .close = pax_emuplt_close,
2468 +       .fault = pax_emuplt_fault
2469 +};
2470 +
2471 +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr)
2472 +{
2473 +       int ret;
2474 +
2475 +       vma->vm_mm = current->mm;
2476 +       vma->vm_start = addr;
2477 +       vma->vm_end = addr + PAGE_SIZE;
2478 +       vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC;
2479 +       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
2480 +       vma->vm_ops = &pax_vm_ops;
2481 +
2482 +       ret = insert_vm_struct(current->mm, vma);
2483 +       if (ret)
2484 +               return ret;
2485 +
2486 +       ++current->mm->total_vm;
2487 +       return 0;
2488 +}
2489 +#endif
2490 +
2491 +/*
2492 + * PaX: decide what to do with offenders (regs->tpc = fault address)
2493 + *
2494 + * returns 1 when task should be killed
2495 + *         2 when patched PLT trampoline was detected
2496 + *         3 when unpatched PLT trampoline was detected
2497 + */
2498 +static int pax_handle_fetch_fault(struct pt_regs *regs)
2499 +{
2500 +
2501 +#ifdef CONFIG_PAX_EMUPLT
2502 +       int err;
2503 +
2504 +       do { /* PaX: patched PLT emulation #1 */
2505 +               unsigned int sethi1, sethi2, jmpl;
2506 +
2507 +               err = get_user(sethi1, (unsigned int *)regs->tpc);
2508 +               err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2509 +               err |= get_user(jmpl, (unsigned int *)(regs->tpc+8));
2510 +
2511 +               if (err)
2512 +                       break;
2513 +
2514 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2515 +                   (sethi2 & 0xFFC00000U) == 0x03000000U &&
2516 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U)
2517 +               {
2518 +                       unsigned long addr;
2519 +
2520 +                       regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10;
2521 +                       addr = regs->u_regs[UREG_G1];
2522 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2523 +                       regs->tpc = addr;
2524 +                       regs->tnpc = addr+4;
2525 +                       return 2;
2526 +               }
2527 +       } while (0);
2528 +
2529 +       { /* PaX: patched PLT emulation #2 */
2530 +               unsigned int ba;
2531 +
2532 +               err = get_user(ba, (unsigned int *)regs->tpc);
2533 +
2534 +               if (!err && (ba & 0xFFC00000U) == 0x30800000U) {
2535 +                       unsigned long addr;
2536 +
2537 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2538 +                       regs->tpc = addr;
2539 +                       regs->tnpc = addr+4;
2540 +                       return 2;
2541 +               }
2542 +       }
2543 +
2544 +       do { /* PaX: patched PLT emulation #3 */
2545 +               unsigned int sethi, jmpl, nop;
2546 +
2547 +               err = get_user(sethi, (unsigned int *)regs->tpc);
2548 +               err |= get_user(jmpl, (unsigned int *)(regs->tpc+4));
2549 +               err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2550 +
2551 +               if (err)
2552 +                       break;
2553 +
2554 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2555 +                   (jmpl & 0xFFFFE000U) == 0x81C06000U &&
2556 +                   nop == 0x01000000U)
2557 +               {
2558 +                       unsigned long addr;
2559 +
2560 +                       addr = (sethi & 0x003FFFFFU) << 10;
2561 +                       regs->u_regs[UREG_G1] = addr;
2562 +                       addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL);
2563 +                       regs->tpc = addr;
2564 +                       regs->tnpc = addr+4;
2565 +                       return 2;
2566 +               }
2567 +       } while (0);
2568 +
2569 +       do { /* PaX: patched PLT emulation #4 */
2570 +               unsigned int mov1, call, mov2;
2571 +
2572 +               err = get_user(mov1, (unsigned int *)regs->tpc);
2573 +               err |= get_user(call, (unsigned int *)(regs->tpc+4));
2574 +               err |= get_user(mov2, (unsigned int *)(regs->tpc+8));
2575 +
2576 +               if (err)
2577 +                       break;
2578 +
2579 +               if (mov1 == 0x8210000FU &&
2580 +                   (call & 0xC0000000U) == 0x40000000U &&
2581 +                   mov2 == 0x9E100001U)
2582 +               {
2583 +                       unsigned long addr;
2584 +
2585 +                       regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC];
2586 +                       addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2587 +                       regs->tpc = addr;
2588 +                       regs->tnpc = addr+4;
2589 +                       return 2;
2590 +               }
2591 +       } while (0);
2592 +
2593 +       do { /* PaX: patched PLT emulation #5 */
2594 +               unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop;
2595 +
2596 +               err = get_user(sethi1, (unsigned int *)regs->tpc);
2597 +               err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2598 +               err |= get_user(or1, (unsigned int *)(regs->tpc+8));
2599 +               err |= get_user(or2, (unsigned int *)(regs->tpc+12));
2600 +               err |= get_user(sllx, (unsigned int *)(regs->tpc+16));
2601 +               err |= get_user(jmpl, (unsigned int *)(regs->tpc+20));
2602 +               err |= get_user(nop, (unsigned int *)(regs->tpc+24));
2603 +
2604 +               if (err)
2605 +                       break;
2606 +
2607 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2608 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2609 +                   (or1 & 0xFFFFE000U) == 0x82106000U &&
2610 +                   (or2 & 0xFFFFE000U) == 0x8A116000U &&
2611 +                   sllx == 0x83287020 &&
2612 +                   jmpl == 0x81C04005U &&
2613 +                   nop == 0x01000000U)
2614 +               {
2615 +                       unsigned long addr;
2616 +
2617 +                       regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU);
2618 +                       regs->u_regs[UREG_G1] <<= 32;
2619 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU);
2620 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2621 +                       regs->tpc = addr;
2622 +                       regs->tnpc = addr+4;
2623 +                       return 2;
2624 +               }
2625 +       } while (0);
2626 +
2627 +       do { /* PaX: patched PLT emulation #6 */
2628 +               unsigned int sethi1, sethi2, sllx, or,  jmpl, nop;
2629 +
2630 +               err = get_user(sethi1, (unsigned int *)regs->tpc);
2631 +               err |= get_user(sethi2, (unsigned int *)(regs->tpc+4));
2632 +               err |= get_user(sllx, (unsigned int *)(regs->tpc+8));
2633 +               err |= get_user(or, (unsigned int *)(regs->tpc+12));
2634 +               err |= get_user(jmpl, (unsigned int *)(regs->tpc+16));
2635 +               err |= get_user(nop, (unsigned int *)(regs->tpc+20));
2636 +
2637 +               if (err)
2638 +                       break;
2639 +
2640 +               if ((sethi1 & 0xFFC00000U) == 0x03000000U &&
2641 +                   (sethi2 & 0xFFC00000U) == 0x0B000000U &&
2642 +                   sllx == 0x83287020 &&
2643 +                   (or & 0xFFFFE000U) == 0x8A116000U &&
2644 +                   jmpl == 0x81C04005U &&
2645 +                   nop == 0x01000000U)
2646 +               {
2647 +                       unsigned long addr;
2648 +
2649 +                       regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10;
2650 +                       regs->u_regs[UREG_G1] <<= 32;
2651 +                       regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU);
2652 +                       addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5];
2653 +                       regs->tpc = addr;
2654 +                       regs->tnpc = addr+4;
2655 +                       return 2;
2656 +               }
2657 +       } while (0);
2658 +
2659 +       do { /* PaX: patched PLT emulation #7 */
2660 +               unsigned int sethi, ba, nop;
2661 +
2662 +               err = get_user(sethi, (unsigned int *)regs->tpc);
2663 +               err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2664 +               err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2665 +
2666 +               if (err)
2667 +                       break;
2668 +
2669 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2670 +                   (ba & 0xFFF00000U) == 0x30600000U &&
2671 +                   nop == 0x01000000U)
2672 +               {
2673 +                       unsigned long addr;
2674 +
2675 +                       addr = (sethi & 0x003FFFFFU) << 10;
2676 +                       regs->u_regs[UREG_G1] = addr;
2677 +                       addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2678 +                       regs->tpc = addr;
2679 +                       regs->tnpc = addr+4;
2680 +                       return 2;
2681 +               }
2682 +       } while (0);
2683 +
2684 +       do { /* PaX: unpatched PLT emulation step 1 */
2685 +               unsigned int sethi, ba, nop;
2686 +
2687 +               err = get_user(sethi, (unsigned int *)regs->tpc);
2688 +               err |= get_user(ba, (unsigned int *)(regs->tpc+4));
2689 +               err |= get_user(nop, (unsigned int *)(regs->tpc+8));
2690 +
2691 +               if (err)
2692 +                       break;
2693 +
2694 +               if ((sethi & 0xFFC00000U) == 0x03000000U &&
2695 +                   ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) &&
2696 +                   nop == 0x01000000U)
2697 +               {
2698 +                       unsigned long addr;
2699 +                       unsigned int save, call;
2700 +
2701 +                       if ((ba & 0xFFC00000U) == 0x30800000U)
2702 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2);
2703 +                       else
2704 +                               addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2);
2705 +
2706 +                       err = get_user(save, (unsigned int *)addr);
2707 +                       err |= get_user(call, (unsigned int *)(addr+4));
2708 +                       err |= get_user(nop, (unsigned int *)(addr+8));
2709 +                       if (err)
2710 +                               break;
2711 +
2712 +                       if (save == 0x9DE3BFA8U &&
2713 +                           (call & 0xC0000000U) == 0x40000000U &&
2714 +                           nop == 0x01000000U)
2715 +                       {
2716 +                               struct vm_area_struct *vma;
2717 +                               unsigned long call_dl_resolve;
2718 +
2719 +                               down_read(&current->mm->mmap_sem);
2720 +                               call_dl_resolve = current->mm->call_dl_resolve;
2721 +                               up_read(&current->mm->mmap_sem);
2722 +                               if (likely(call_dl_resolve))
2723 +                                       goto emulate;
2724 +
2725 +                               vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
2726 +
2727 +                               down_write(&current->mm->mmap_sem);
2728 +                               if (current->mm->call_dl_resolve) {
2729 +                                       call_dl_resolve = current->mm->call_dl_resolve;
2730 +                                       up_write(&current->mm->mmap_sem);
2731 +                                       if (vma)
2732 +                                               kmem_cache_free(vm_area_cachep, vma);
2733 +                                       goto emulate;
2734 +                               }
2735 +
2736 +                               call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE);
2737 +                               if (!vma || (call_dl_resolve & ~PAGE_MASK)) {
2738 +                                       up_write(&current->mm->mmap_sem);
2739 +                                       if (vma)
2740 +                                               kmem_cache_free(vm_area_cachep, vma);
2741 +                                       return 1;
2742 +                               }
2743 +
2744 +                               if (pax_insert_vma(vma, call_dl_resolve)) {
2745 +                                       up_write(&current->mm->mmap_sem);
2746 +                                       kmem_cache_free(vm_area_cachep, vma);
2747 +                                       return 1;
2748 +                               }
2749 +
2750 +                               current->mm->call_dl_resolve = call_dl_resolve;
2751 +                               up_write(&current->mm->mmap_sem);
2752 +
2753 +emulate:
2754 +                               regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10;
2755 +                               regs->tpc = call_dl_resolve;
2756 +                               regs->tnpc = addr+4;
2757 +                               return 3;
2758 +                       }
2759 +               }
2760 +       } while (0);
2761 +
2762 +       do { /* PaX: unpatched PLT emulation step 2 */
2763 +               unsigned int save, call, nop;
2764 +
2765 +               err = get_user(save, (unsigned int *)(regs->tpc-4));
2766 +               err |= get_user(call, (unsigned int *)regs->tpc);
2767 +               err |= get_user(nop, (unsigned int *)(regs->tpc+4));
2768 +               if (err)
2769 +                       break;
2770 +
2771 +               if (save == 0x9DE3BFA8U &&
2772 +                   (call & 0xC0000000U) == 0x40000000U &&
2773 +                   nop == 0x01000000U)
2774 +               {
2775 +                       unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2);
2776 +
2777 +                       regs->u_regs[UREG_RETPC] = regs->tpc;
2778 +                       regs->tpc = dl_resolve;
2779 +                       regs->tnpc = dl_resolve+4;
2780 +                       return 3;
2781 +               }
2782 +       } while (0);
2783 +#endif
2784 +
2785 +       return 1;
2786 +}
2787 +
2788 +void pax_report_insns(void *pc, void *sp)
2789 +{
2790 +       unsigned long i;
2791 +
2792 +       printk(KERN_ERR "PAX: bytes at PC: ");
2793 +       for (i = 0; i < 5; i++) {
2794 +               unsigned int c;
2795 +               if (get_user(c, (unsigned int *)pc+i))
2796 +                       printk(KERN_CONT "???????? ");
2797 +               else
2798 +                       printk(KERN_CONT "%08x ", c);
2799 +       }
2800 +       printk("\n");
2801 +}
2802 +#endif
2803 +
2804  asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs)
2805  {
2806         struct mm_struct *mm = current->mm;
2807 @@ -302,8 +666,10 @@ asmlinkage void __kprobes do_sparc64_fau
2808                 goto intr_or_no_mm;
2809  
2810         if (test_thread_flag(TIF_32BIT)) {
2811 -               if (!(regs->tstate & TSTATE_PRIV))
2812 +               if (!(regs->tstate & TSTATE_PRIV)) {
2813                         regs->tpc &= 0xffffffff;
2814 +                       regs->tnpc &= 0xffffffff;
2815 +               }
2816                 address &= 0xffffffff;
2817         }
2818  
2819 @@ -320,6 +686,29 @@ asmlinkage void __kprobes do_sparc64_fau
2820         if (!vma)
2821                 goto bad_area;
2822  
2823 +#ifdef CONFIG_PAX_PAGEEXEC
2824 +       /* PaX: detect ITLB misses on non-exec pages */
2825 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address &&
2826 +           !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB))
2827 +       {
2828 +               if (address != regs->tpc)
2829 +                       goto good_area;
2830 +
2831 +               up_read(&mm->mmap_sem);
2832 +               switch (pax_handle_fetch_fault(regs)) {
2833 +
2834 +#ifdef CONFIG_PAX_EMUPLT
2835 +               case 2:
2836 +               case 3:
2837 +                       return;
2838 +#endif
2839 +
2840 +               }
2841 +               pax_report_fault(regs, (void *)regs->tpc, (void *)(regs->u_regs[UREG_FP] + STACK_BIAS));
2842 +               do_group_exit(SIGKILL);
2843 +       }
2844 +#endif
2845 +
2846         /* Pure DTLB misses do not tell us whether the fault causing
2847          * load/store/atomic was a write or not, it only says that there
2848          * was no match.  So in such a case we (carefully) read the
2849 diff -urNp linux-2.6.27.10/arch/sparc64/mm/Makefile linux-2.6.27.10/arch/sparc64/mm/Makefile
2850 --- linux-2.6.27.10/arch/sparc64/mm/Makefile    2008-11-07 12:55:34.000000000 -0500
2851 +++ linux-2.6.27.10/arch/sparc64/mm/Makefile    2008-11-18 03:38:43.000000000 -0500
2852 @@ -2,7 +2,7 @@
2853  #
2854  
2855  EXTRA_AFLAGS := -ansi
2856 -EXTRA_CFLAGS := -Werror
2857 +#EXTRA_CFLAGS := -Werror
2858  
2859  obj-y    := ultra.o tlb.o tsb.o fault.o init.o generic.o
2860  
2861 diff -urNp linux-2.6.27.10/arch/um/sys-i386/syscalls.c linux-2.6.27.10/arch/um/sys-i386/syscalls.c
2862 --- linux-2.6.27.10/arch/um/sys-i386/syscalls.c 2008-11-07 12:55:34.000000000 -0500
2863 +++ linux-2.6.27.10/arch/um/sys-i386/syscalls.c 2008-11-18 03:38:43.000000000 -0500
2864 @@ -10,6 +10,21 @@
2865  #include "asm/uaccess.h"
2866  #include "asm/unistd.h"
2867  
2868 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
2869 +{
2870 +       unsigned long pax_task_size = TASK_SIZE;
2871 +
2872 +#ifdef CONFIG_PAX_SEGMEXEC
2873 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
2874 +               pax_task_size = SEGMEXEC_TASK_SIZE;
2875 +#endif
2876 +
2877 +       if (len > pax_task_size || addr > pax_task_size - len)
2878 +               return -EINVAL;
2879 +
2880 +       return 0;
2881 +}
2882 +
2883  /*
2884   * Perform the select(nd, in, out, ex, tv) and mmap() system
2885   * calls. Linux/i386 didn't use to be able to handle more than
2886 diff -urNp linux-2.6.27.10/arch/x86/boot/bitops.h linux-2.6.27.10/arch/x86/boot/bitops.h
2887 --- linux-2.6.27.10/arch/x86/boot/bitops.h      2008-11-07 12:55:34.000000000 -0500
2888 +++ linux-2.6.27.10/arch/x86/boot/bitops.h      2008-11-18 03:38:44.000000000 -0500
2889 @@ -26,7 +26,7 @@ static inline int variable_test_bit(int 
2890         u8 v;
2891         const u32 *p = (const u32 *)addr;
2892  
2893 -       asm("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2894 +       asm volatile("btl %2,%1; setc %0" : "=qm" (v) : "m" (*p), "Ir" (nr));
2895         return v;
2896  }
2897  
2898 @@ -37,7 +37,7 @@ static inline int variable_test_bit(int 
2899  
2900  static inline void set_bit(int nr, void *addr)
2901  {
2902 -       asm("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2903 +       asm volatile("btsl %1,%0" : "+m" (*(u32 *)addr) : "Ir" (nr));
2904  }
2905  
2906  #endif /* BOOT_BITOPS_H */
2907 diff -urNp linux-2.6.27.10/arch/x86/boot/boot.h linux-2.6.27.10/arch/x86/boot/boot.h
2908 --- linux-2.6.27.10/arch/x86/boot/boot.h        2008-11-07 12:55:34.000000000 -0500
2909 +++ linux-2.6.27.10/arch/x86/boot/boot.h        2008-11-18 03:38:44.000000000 -0500
2910 @@ -80,7 +80,7 @@ static inline void io_delay(void)
2911  static inline u16 ds(void)
2912  {
2913         u16 seg;
2914 -       asm("movw %%ds,%0" : "=rm" (seg));
2915 +       asm volatile("movw %%ds,%0" : "=rm" (seg));
2916         return seg;
2917  }
2918  
2919 @@ -176,7 +176,7 @@ static inline void wrgs32(u32 v, addr_t 
2920  static inline int memcmp(const void *s1, const void *s2, size_t len)
2921  {
2922         u8 diff;
2923 -       asm("repe; cmpsb; setnz %0"
2924 +       asm volatile("repe; cmpsb; setnz %0"
2925             : "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
2926         return diff;
2927  }
2928 diff -urNp linux-2.6.27.10/arch/x86/boot/compressed/head_32.S linux-2.6.27.10/arch/x86/boot/compressed/head_32.S
2929 --- linux-2.6.27.10/arch/x86/boot/compressed/head_32.S  2008-11-07 12:55:34.000000000 -0500
2930 +++ linux-2.6.27.10/arch/x86/boot/compressed/head_32.S  2008-11-18 03:38:44.000000000 -0500
2931 @@ -70,7 +70,7 @@ startup_32:
2932         addl    $(CONFIG_PHYSICAL_ALIGN - 1), %ebx
2933         andl    $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebx
2934  #else
2935 -       movl $LOAD_PHYSICAL_ADDR, %ebx
2936 +       movl $____LOAD_PHYSICAL_ADDR, %ebx
2937  #endif
2938  
2939         /* Replace the compressed data size with the uncompressed size */
2940 @@ -105,7 +105,7 @@ startup_32:
2941         addl    $(CONFIG_PHYSICAL_ALIGN - 1), %ebp
2942         andl    $(~(CONFIG_PHYSICAL_ALIGN - 1)), %ebp
2943  #else
2944 -       movl    $LOAD_PHYSICAL_ADDR, %ebp
2945 +       movl    $____LOAD_PHYSICAL_ADDR, %ebp
2946  #endif
2947  
2948  /*
2949 @@ -159,16 +159,15 @@ relocated:
2950   * and where it was actually loaded.
2951   */
2952         movl %ebp, %ebx
2953 -       subl $LOAD_PHYSICAL_ADDR, %ebx
2954 +       subl $____LOAD_PHYSICAL_ADDR, %ebx
2955         jz   2f         /* Nothing to be done if loaded at compiled addr. */
2956  /*
2957   * Process relocations.
2958   */
2959  
2960  1:     subl $4, %edi
2961 -       movl 0(%edi), %ecx
2962 -       testl %ecx, %ecx
2963 -       jz 2f
2964 +       movl (%edi), %ecx
2965 +       jecxz 2f
2966         addl %ebx, -__PAGE_OFFSET(%ebx, %ecx)
2967         jmp 1b
2968  2:
2969 diff -urNp linux-2.6.27.10/arch/x86/boot/compressed/misc.c linux-2.6.27.10/arch/x86/boot/compressed/misc.c
2970 --- linux-2.6.27.10/arch/x86/boot/compressed/misc.c     2008-11-07 12:55:34.000000000 -0500
2971 +++ linux-2.6.27.10/arch/x86/boot/compressed/misc.c     2008-11-18 03:38:44.000000000 -0500
2972 @@ -371,7 +371,7 @@ static void parse_elf(void *output)
2973                 case PT_LOAD:
2974  #ifdef CONFIG_RELOCATABLE
2975                         dest = output;
2976 -                       dest += (phdr->p_paddr - LOAD_PHYSICAL_ADDR);
2977 +                       dest += (phdr->p_paddr - ____LOAD_PHYSICAL_ADDR);
2978  #else
2979                         dest = (void *)(phdr->p_paddr);
2980  #endif
2981 @@ -423,7 +423,7 @@ asmlinkage void decompress_kernel(void *
2982         if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff))
2983                 error("Destination address too large");
2984  #ifndef CONFIG_RELOCATABLE
2985 -       if ((u32)output != LOAD_PHYSICAL_ADDR)
2986 +       if ((u32)output != ____LOAD_PHYSICAL_ADDR)
2987                 error("Wrong destination address");
2988  #endif
2989  #endif
2990 diff -urNp linux-2.6.27.10/arch/x86/boot/compressed/relocs.c linux-2.6.27.10/arch/x86/boot/compressed/relocs.c
2991 --- linux-2.6.27.10/arch/x86/boot/compressed/relocs.c   2008-11-07 12:55:34.000000000 -0500
2992 +++ linux-2.6.27.10/arch/x86/boot/compressed/relocs.c   2008-11-18 03:38:44.000000000 -0500
2993 @@ -10,8 +10,11 @@
2994  #define USE_BSD
2995  #include <endian.h>
2996  
2997 +#include "../../../../include/linux/autoconf.h"
2998 +
2999  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
3000  static Elf32_Ehdr ehdr;
3001 +static Elf32_Phdr *phdr;
3002  static unsigned long reloc_count, reloc_idx;
3003  static unsigned long *relocs;
3004  
3005 @@ -245,6 +248,36 @@ static void read_ehdr(FILE *fp)
3006         }
3007  }
3008  
3009 +static void read_phdrs(FILE *fp)
3010 +{
3011 +       int i;
3012 +
3013 +       phdr = calloc(ehdr.e_phnum, sizeof(Elf32_Phdr));
3014 +       if (!phdr) {
3015 +               die("Unable to allocate %d program headers\n",
3016 +                   ehdr.e_phnum);
3017 +       }
3018 +       if (fseek(fp, ehdr.e_phoff, SEEK_SET) < 0) {
3019 +               die("Seek to %d failed: %s\n",
3020 +                       ehdr.e_phoff, strerror(errno));
3021 +       }
3022 +       if (fread(phdr, sizeof(*phdr), ehdr.e_phnum, fp) != ehdr.e_phnum) {
3023 +               die("Cannot read ELF program headers: %s\n",
3024 +                       strerror(errno));
3025 +       }
3026 +       for(i = 0; i < ehdr.e_phnum; i++) {
3027 +               phdr[i].p_type      = elf32_to_cpu(phdr[i].p_type);
3028 +               phdr[i].p_offset    = elf32_to_cpu(phdr[i].p_offset);
3029 +               phdr[i].p_vaddr     = elf32_to_cpu(phdr[i].p_vaddr);
3030 +               phdr[i].p_paddr     = elf32_to_cpu(phdr[i].p_paddr);
3031 +               phdr[i].p_filesz    = elf32_to_cpu(phdr[i].p_filesz);
3032 +               phdr[i].p_memsz     = elf32_to_cpu(phdr[i].p_memsz);
3033 +               phdr[i].p_flags     = elf32_to_cpu(phdr[i].p_flags);
3034 +               phdr[i].p_align     = elf32_to_cpu(phdr[i].p_align);
3035 +       }
3036 +
3037 +}
3038 +
3039  static void read_shdrs(FILE *fp)
3040  {
3041         int i;
3042 @@ -341,6 +374,8 @@ static void read_symtabs(FILE *fp)
3043  static void read_relocs(FILE *fp)
3044  {
3045         int i,j;
3046 +       uint32_t base;
3047 +
3048         for (i = 0; i < ehdr.e_shnum; i++) {
3049                 struct section *sec = &secs[i];
3050                 if (sec->shdr.sh_type != SHT_REL) {
3051 @@ -360,9 +395,18 @@ static void read_relocs(FILE *fp)
3052                         die("Cannot read symbol table: %s\n",
3053                                 strerror(errno));
3054                 }
3055 +               base = 0;
3056 +               for (j = 0; j < ehdr.e_phnum; j++) {
3057 +                       if (phdr[j].p_type != PT_LOAD )
3058 +                               continue;
3059 +                       if (secs[secs[i].shdr.sh_info].shdr.sh_offset < phdr[j].p_offset || secs[secs[i].shdr.sh_info].shdr.sh_offset > phdr[j].p_offset + phdr[j].p_filesz)
3060 +                               continue;
3061 +                       base = CONFIG_PAGE_OFFSET + phdr[j].p_paddr - phdr[j].p_vaddr;
3062 +                       break;
3063 +               }
3064                 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf32_Rel); j++) {
3065                         Elf32_Rel *rel = &sec->reltab[j];
3066 -                       rel->r_offset = elf32_to_cpu(rel->r_offset);
3067 +                       rel->r_offset = elf32_to_cpu(rel->r_offset) + base;
3068                         rel->r_info   = elf32_to_cpu(rel->r_info);
3069                 }
3070         }
3071 @@ -504,6 +548,23 @@ static void walk_relocs(void (*visit)(El
3072                         if (sym->st_shndx == SHN_ABS) {
3073                                 continue;
3074                         }
3075 +                       /* Don't relocate actual per-cpu variables, they are absolute indices, not addresses */
3076 +                       if (!strcmp(sec_name(sym->st_shndx), ".data.percpu") && strncmp(sym_name(sym_strtab, sym), "__per_cpu_", 10))
3077 +                               continue;
3078 +#if defined(CONFIG_PAX_KERNEXEC) && defined(CONFIG_X86_32)
3079 +                       /* Don't relocate actual code, they are relocated implicitly by the base address of KERNEL_CS */
3080 +                       if (!strcmp(sec_name(sym->st_shndx), ".init.text"))
3081 +                               continue;
3082 +                       if (!strcmp(sec_name(sym->st_shndx), ".exit.text"))
3083 +                               continue;
3084 +                       if (!strcmp(sec_name(sym->st_shndx), ".text.head")) {
3085 +                               if (strcmp(sym_name(sym_strtab, sym), "__init_end") &&
3086 +                                   strcmp(sym_name(sym_strtab, sym), "KERNEL_TEXT_OFFSET"))
3087 +                                       continue;
3088 +                       }
3089 +                       if (!strcmp(sec_name(sym->st_shndx), ".text"))
3090 +                               continue;
3091 +#endif
3092                         if (r_type == R_386_PC32) {
3093                                 /* PC relative relocations don't need to be adjusted */
3094                         }
3095 @@ -631,6 +692,7 @@ int main(int argc, char **argv)
3096                         fname, strerror(errno));
3097         }
3098         read_ehdr(fp);
3099 +       read_phdrs(fp);
3100         read_shdrs(fp);
3101         read_strtabs(fp);
3102         read_symtabs(fp);
3103 diff -urNp linux-2.6.27.10/arch/x86/boot/cpucheck.c linux-2.6.27.10/arch/x86/boot/cpucheck.c
3104 --- linux-2.6.27.10/arch/x86/boot/cpucheck.c    2008-11-07 12:55:34.000000000 -0500
3105 +++ linux-2.6.27.10/arch/x86/boot/cpucheck.c    2008-11-18 03:38:44.000000000 -0500
3106 @@ -74,7 +74,7 @@ static int has_fpu(void)
3107         u16 fcw = -1, fsw = -1;
3108         u32 cr0;
3109  
3110 -       asm("movl %%cr0,%0" : "=r" (cr0));
3111 +       asm volatile("movl %%cr0,%0" : "=r" (cr0));
3112         if (cr0 & (X86_CR0_EM|X86_CR0_TS)) {
3113                 cr0 &= ~(X86_CR0_EM|X86_CR0_TS);
3114                 asm volatile("movl %0,%%cr0" : : "r" (cr0));
3115 @@ -90,7 +90,7 @@ static int has_eflag(u32 mask)
3116  {
3117         u32 f0, f1;
3118  
3119 -       asm("pushfl ; "
3120 +       asm volatile("pushfl ; "
3121             "pushfl ; "
3122             "popl %0 ; "
3123             "movl %0,%1 ; "
3124 @@ -115,7 +115,7 @@ static void get_flags(void)
3125                 set_bit(X86_FEATURE_FPU, cpu.flags);
3126  
3127         if (has_eflag(X86_EFLAGS_ID)) {
3128 -               asm("cpuid"
3129 +               asm volatile("cpuid"
3130                     : "=a" (max_intel_level),
3131                       "=b" (cpu_vendor[0]),
3132                       "=d" (cpu_vendor[1]),
3133 @@ -124,7 +124,7 @@ static void get_flags(void)
3134  
3135                 if (max_intel_level >= 0x00000001 &&
3136                     max_intel_level <= 0x0000ffff) {
3137 -                       asm("cpuid"
3138 +                       asm volatile("cpuid"
3139                             : "=a" (tfms),
3140                               "=c" (cpu.flags[4]),
3141                               "=d" (cpu.flags[0])
3142 @@ -136,7 +136,7 @@ static void get_flags(void)
3143                                 cpu.model += ((tfms >> 16) & 0xf) << 4;
3144                 }
3145  
3146 -               asm("cpuid"
3147 +               asm volatile("cpuid"
3148                     : "=a" (max_amd_level)
3149                     : "a" (0x80000000)
3150                     : "ebx", "ecx", "edx");
3151 @@ -144,7 +144,7 @@ static void get_flags(void)
3152                 if (max_amd_level >= 0x80000001 &&
3153                     max_amd_level <= 0x8000ffff) {
3154                         u32 eax = 0x80000001;
3155 -                       asm("cpuid"
3156 +                       asm volatile("cpuid"
3157                             : "+a" (eax),
3158                               "=c" (cpu.flags[6]),
3159                               "=d" (cpu.flags[1])
3160 @@ -203,9 +203,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3161                 u32 ecx = MSR_K7_HWCR;
3162                 u32 eax, edx;
3163  
3164 -               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3165 +               asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3166                 eax &= ~(1 << 15);
3167 -               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3168 +               asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3169  
3170                 get_flags();    /* Make sure it really did something */
3171                 err = check_flags();
3172 @@ -218,9 +218,9 @@ int check_cpu(int *cpu_level_ptr, int *r
3173                 u32 ecx = MSR_VIA_FCR;
3174                 u32 eax, edx;
3175  
3176 -               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3177 +               asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3178                 eax |= (1<<1)|(1<<7);
3179 -               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3180 +               asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3181  
3182                 set_bit(X86_FEATURE_CX8, cpu.flags);
3183                 err = check_flags();
3184 @@ -231,12 +231,12 @@ int check_cpu(int *cpu_level_ptr, int *r
3185                 u32 eax, edx;
3186                 u32 level = 1;
3187  
3188 -               asm("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3189 -               asm("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3190 -               asm("cpuid"
3191 +               asm volatile("rdmsr" : "=a" (eax), "=d" (edx) : "c" (ecx));
3192 +               asm volatile("wrmsr" : : "a" (~0), "d" (edx), "c" (ecx));
3193 +               asm volatile("cpuid"
3194                     : "+a" (level), "=d" (cpu.flags[0])
3195                     : : "ecx", "ebx");
3196 -               asm("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3197 +               asm volatile("wrmsr" : : "a" (eax), "d" (edx), "c" (ecx));
3198  
3199                 err = check_flags();
3200         }
3201 diff -urNp linux-2.6.27.10/arch/x86/boot/edd.c linux-2.6.27.10/arch/x86/boot/edd.c
3202 --- linux-2.6.27.10/arch/x86/boot/edd.c 2008-11-07 12:55:34.000000000 -0500
3203 +++ linux-2.6.27.10/arch/x86/boot/edd.c 2008-11-18 03:38:44.000000000 -0500
3204 @@ -76,7 +76,7 @@ static int get_edd_info(u8 devno, struct
3205         ax = 0x4100;
3206         bx = EDDMAGIC1;
3207         dx = devno;
3208 -       asm("pushfl; stc; int $0x13; setc %%al; popfl"
3209 +       asm volatile("pushfl; stc; int $0x13; setc %%al; popfl"
3210             : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
3211             : : "esi", "edi");
3212  
3213 @@ -95,7 +95,7 @@ static int get_edd_info(u8 devno, struct
3214         ei->params.length = sizeof(ei->params);
3215         ax = 0x4800;
3216         dx = devno;
3217 -       asm("pushfl; int $0x13; popfl"
3218 +       asm volatile("pushfl; int $0x13; popfl"
3219             : "+a" (ax), "+d" (dx), "=m" (ei->params)
3220             : "S" (&ei->params)
3221             : "ebx", "ecx", "edi");
3222 @@ -106,7 +106,7 @@ static int get_edd_info(u8 devno, struct
3223         ax = 0x0800;
3224         dx = devno;
3225         di = 0;
3226 -       asm("pushw %%es; "
3227 +       asm volatile("pushw %%es; "
3228             "movw %%di,%%es; "
3229             "pushfl; stc; int $0x13; setc %%al; popfl; "
3230             "popw %%es"
3231 diff -urNp linux-2.6.27.10/arch/x86/boot/main.c linux-2.6.27.10/arch/x86/boot/main.c
3232 --- linux-2.6.27.10/arch/x86/boot/main.c        2008-11-07 12:55:34.000000000 -0500
3233 +++ linux-2.6.27.10/arch/x86/boot/main.c        2008-11-18 03:38:44.000000000 -0500
3234 @@ -78,7 +78,7 @@ static void query_ist(void)
3235         if (cpu.level < 6)
3236                 return;
3237  
3238 -       asm("int $0x15"
3239 +       asm volatile("int $0x15"
3240             : "=a" (boot_params.ist_info.signature),
3241               "=b" (boot_params.ist_info.command),
3242               "=c" (boot_params.ist_info.event),
3243 diff -urNp linux-2.6.27.10/arch/x86/boot/mca.c linux-2.6.27.10/arch/x86/boot/mca.c
3244 --- linux-2.6.27.10/arch/x86/boot/mca.c 2008-11-07 12:55:34.000000000 -0500
3245 +++ linux-2.6.27.10/arch/x86/boot/mca.c 2008-11-18 03:38:44.000000000 -0500
3246 @@ -19,7 +19,7 @@ int query_mca(void)
3247         u8 err;
3248         u16 es, bx, len;
3249  
3250 -       asm("pushw %%es ; "
3251 +       asm volatile("pushw %%es ; "
3252             "int $0x15 ; "
3253             "setc %0 ; "
3254             "movw %%es, %1 ; "
3255 diff -urNp linux-2.6.27.10/arch/x86/boot/memory.c linux-2.6.27.10/arch/x86/boot/memory.c
3256 --- linux-2.6.27.10/arch/x86/boot/memory.c      2008-11-07 12:55:34.000000000 -0500
3257 +++ linux-2.6.27.10/arch/x86/boot/memory.c      2008-11-18 03:38:44.000000000 -0500
3258 @@ -30,7 +30,7 @@ static int detect_memory_e820(void)
3259                 /* Important: %edx is clobbered by some BIOSes,
3260                    so it must be either used for the error output
3261                    or explicitly marked clobbered. */
3262 -               asm("int $0x15; setc %0"
3263 +               asm volatile("int $0x15; setc %0"
3264                     : "=d" (err), "+b" (next), "=a" (id), "+c" (size),
3265                       "=m" (*desc)
3266                     : "D" (desc), "d" (SMAP), "a" (0xe820));
3267 @@ -65,7 +65,7 @@ static int detect_memory_e801(void)
3268  
3269         bx = cx = dx = 0;
3270         ax = 0xe801;
3271 -       asm("stc; int $0x15; setc %0"
3272 +       asm volatile("stc; int $0x15; setc %0"
3273             : "=m" (err), "+a" (ax), "+b" (bx), "+c" (cx), "+d" (dx));
3274  
3275         if (err)
3276 @@ -95,7 +95,7 @@ static int detect_memory_88(void)
3277         u8 err;
3278  
3279         ax = 0x8800;
3280 -       asm("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3281 +       asm volatile("stc; int $0x15; setc %0" : "=bcdm" (err), "+a" (ax));
3282  
3283         boot_params.screen_info.ext_mem_k = ax;
3284  
3285 diff -urNp linux-2.6.27.10/arch/x86/boot/video.c linux-2.6.27.10/arch/x86/boot/video.c
3286 --- linux-2.6.27.10/arch/x86/boot/video.c       2008-11-07 12:55:34.000000000 -0500
3287 +++ linux-2.6.27.10/arch/x86/boot/video.c       2008-11-18 03:38:44.000000000 -0500
3288 @@ -23,7 +23,7 @@ static void store_cursor_position(void)
3289  
3290         ax = 0x0300;
3291         bx = 0;
3292 -       asm(INT10
3293 +       asm volatile(INT10
3294             : "=d" (curpos), "+a" (ax), "+b" (bx)
3295             : : "ecx", "esi", "edi");
3296  
3297 @@ -38,7 +38,7 @@ static void store_video_mode(void)
3298         /* N.B.: the saving of the video page here is a bit silly,
3299            since we pretty much assume page 0 everywhere. */
3300         ax = 0x0f00;
3301 -       asm(INT10
3302 +       asm volatile(INT10
3303             : "+a" (ax), "=b" (page)
3304             : : "ecx", "edx", "esi", "edi");
3305  
3306 diff -urNp linux-2.6.27.10/arch/x86/boot/video-vesa.c linux-2.6.27.10/arch/x86/boot/video-vesa.c
3307 --- linux-2.6.27.10/arch/x86/boot/video-vesa.c  2008-11-07 12:55:34.000000000 -0500
3308 +++ linux-2.6.27.10/arch/x86/boot/video-vesa.c  2008-11-18 03:38:44.000000000 -0500
3309 @@ -41,7 +41,7 @@ static int vesa_probe(void)
3310  
3311         ax = 0x4f00;
3312         di = (size_t)&vginfo;
3313 -       asm(INT10
3314 +       asm volatile(INT10
3315             : "+a" (ax), "+D" (di), "=m" (vginfo)
3316             : : "ebx", "ecx", "edx", "esi");
3317  
3318 @@ -68,7 +68,7 @@ static int vesa_probe(void)
3319                 ax = 0x4f01;
3320                 cx = mode;
3321                 di = (size_t)&vminfo;
3322 -               asm(INT10
3323 +               asm volatile(INT10
3324                     : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3325                     : : "ebx", "edx", "esi");
3326  
3327 @@ -123,7 +123,7 @@ static int vesa_set_mode(struct mode_inf
3328         ax = 0x4f01;
3329         cx = vesa_mode;
3330         di = (size_t)&vminfo;
3331 -       asm(INT10
3332 +       asm volatile(INT10
3333             : "+a" (ax), "+c" (cx), "+D" (di), "=m" (vminfo)
3334             : : "ebx", "edx", "esi");
3335  
3336 @@ -203,19 +203,20 @@ static void vesa_dac_set_8bits(void)
3337  /* Save the VESA protected mode info */
3338  static void vesa_store_pm_info(void)
3339  {
3340 -       u16 ax, bx, di, es;
3341 +       u16 ax, bx, cx, di, es;
3342  
3343         ax = 0x4f0a;
3344 -       bx = di = 0;
3345 -       asm("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3346 -           : "=d" (es), "+a" (ax), "+b" (bx), "+D" (di)
3347 -           : : "ecx", "esi");
3348 +       bx = cx = di = 0;
3349 +       asm volatile("pushw %%es; "INT10"; movw %%es,%0; popw %%es"
3350 +           : "=d" (es), "+a" (ax), "+b" (bx), "+c" (cx), "+D" (di)
3351 +           : : "esi");
3352  
3353         if (ax != 0x004f)
3354                 return;
3355  
3356         boot_params.screen_info.vesapm_seg = es;
3357         boot_params.screen_info.vesapm_off = di;
3358 +       boot_params.screen_info.vesapm_size = cx;
3359  }
3360  
3361  /*
3362 @@ -269,7 +270,7 @@ void vesa_store_edid(void)
3363         /* Note: The VBE DDC spec is different from the main VESA spec;
3364            we genuinely have to assume all registers are destroyed here. */
3365  
3366 -       asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3367 +       asm volatile("pushw %%es; movw %2,%%es; "INT10"; popw %%es"
3368             : "+a" (ax), "+b" (bx)
3369             :  "c" (cx), "D" (di)
3370             : "esi");
3371 @@ -285,7 +286,7 @@ void vesa_store_edid(void)
3372         cx = 0;                 /* Controller 0 */
3373         dx = 0;                 /* EDID block number */
3374         di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */
3375 -       asm(INT10
3376 +       asm volatile(INT10
3377             : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info)
3378             : "c" (cx), "D" (di)
3379             : "esi");
3380 diff -urNp linux-2.6.27.10/arch/x86/boot/video-vga.c linux-2.6.27.10/arch/x86/boot/video-vga.c
3381 --- linux-2.6.27.10/arch/x86/boot/video-vga.c   2008-11-07 12:55:34.000000000 -0500
3382 +++ linux-2.6.27.10/arch/x86/boot/video-vga.c   2008-11-18 03:38:44.000000000 -0500
3383 @@ -225,7 +225,7 @@ static int vga_probe(void)
3384         };
3385         u8 vga_flag;
3386  
3387 -       asm(INT10
3388 +       asm volatile(INT10
3389             : "=b" (ega_bx)
3390             : "a" (0x1200), "b" (0x10) /* Check EGA/VGA */
3391             : "ecx", "edx", "esi", "edi");
3392 @@ -237,7 +237,7 @@ static int vga_probe(void)
3393         /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
3394         if ((u8)ega_bx != 0x10) {
3395                 /* EGA/VGA */
3396 -               asm(INT10
3397 +               asm volatile(INT10
3398                     : "=a" (vga_flag)
3399                     : "a" (0x1a00)
3400                     : "ebx", "ecx", "edx", "esi", "edi");
3401 diff -urNp linux-2.6.27.10/arch/x86/boot/voyager.c linux-2.6.27.10/arch/x86/boot/voyager.c
3402 --- linux-2.6.27.10/arch/x86/boot/voyager.c     2008-11-07 12:55:34.000000000 -0500
3403 +++ linux-2.6.27.10/arch/x86/boot/voyager.c     2008-11-18 03:38:44.000000000 -0500
3404 @@ -23,7 +23,7 @@ int query_voyager(void)
3405  
3406         data_ptr[0] = 0xff;     /* Flag on config not found(?) */
3407  
3408 -       asm("pushw %%es ; "
3409 +       asm volatile("pushw %%es ; "
3410             "int $0x15 ; "
3411             "setc %0 ; "
3412             "movw %%es, %1 ; "
3413 diff -urNp linux-2.6.27.10/arch/x86/ia32/ia32_signal.c linux-2.6.27.10/arch/x86/ia32/ia32_signal.c
3414 --- linux-2.6.27.10/arch/x86/ia32/ia32_signal.c 2008-11-07 12:55:34.000000000 -0500
3415 +++ linux-2.6.27.10/arch/x86/ia32/ia32_signal.c 2008-11-18 03:38:44.000000000 -0500
3416 @@ -535,6 +535,7 @@ int ia32_setup_rt_frame(int sig, struct 
3417                 __NR_ia32_rt_sigreturn,
3418                 0x80cd,
3419                 0,
3420 +               0
3421         };
3422  
3423         frame = get_sigframe(ka, regs, sizeof(*frame));
3424 diff -urNp linux-2.6.27.10/arch/x86/Kconfig linux-2.6.27.10/arch/x86/Kconfig
3425 --- linux-2.6.27.10/arch/x86/Kconfig    2008-11-17 20:03:30.000000000 -0500
3426 +++ linux-2.6.27.10/arch/x86/Kconfig    2008-11-18 03:38:44.000000000 -0500
3427 @@ -912,7 +912,7 @@ config PAGE_OFFSET
3428         hex
3429         default 0xB0000000 if VMSPLIT_3G_OPT
3430         default 0x80000000 if VMSPLIT_2G
3431 -       default 0x78000000 if VMSPLIT_2G_OPT
3432 +       default 0x70000000 if VMSPLIT_2G_OPT
3433         default 0x40000000 if VMSPLIT_1G
3434         default 0xC0000000
3435         depends on X86_32
3436 @@ -1293,8 +1293,7 @@ config KEXEC_JUMP
3437  config PHYSICAL_START
3438         hex "Physical address where the kernel is loaded" if (EMBEDDED || CRASH_DUMP)
3439         default "0x1000000" if X86_NUMAQ
3440 -       default "0x200000" if X86_64
3441 -       default "0x100000"
3442 +       default "0x200000"
3443         help
3444           This gives the physical address where the kernel is loaded.
3445  
3446 @@ -1386,9 +1385,9 @@ config HOTPLUG_CPU
3447           suspend.
3448  
3449  config COMPAT_VDSO
3450 -       def_bool y
3451 +       def_bool n
3452         prompt "Compat VDSO support"
3453 -       depends on X86_32 || IA32_EMULATION
3454 +       depends on (X86_32 || IA32_EMULATION) && !PAX_NOEXEC
3455         help
3456           Map the 32-bit VDSO to the predictable old-style address too.
3457         ---help---
3458 diff -urNp linux-2.6.27.10/arch/x86/Kconfig.cpu linux-2.6.27.10/arch/x86/Kconfig.cpu
3459 --- linux-2.6.27.10/arch/x86/Kconfig.cpu        2008-11-07 12:55:34.000000000 -0500
3460 +++ linux-2.6.27.10/arch/x86/Kconfig.cpu        2008-11-18 03:38:44.000000000 -0500
3461 @@ -340,7 +340,7 @@ config X86_PPRO_FENCE
3462  
3463  config X86_F00F_BUG
3464         def_bool y
3465 -       depends on M586MMX || M586TSC || M586 || M486 || M386
3466 +       depends on (M586MMX || M586TSC || M586 || M486 || M386) && !PAX_KERNEXEC
3467  
3468  config X86_WP_WORKS_OK
3469         def_bool y
3470 @@ -360,7 +360,7 @@ config X86_POPAD_OK
3471  
3472  config X86_ALIGNMENT_16
3473         def_bool y
3474 -       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3475 +       depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK8 || MK7 || MK6 || MCORE2 || MPENTIUM4 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
3476  
3477  config X86_INTEL_USERCOPY
3478         def_bool y
3479 @@ -406,7 +406,7 @@ config X86_CMPXCHG64
3480  # generates cmov.
3481  config X86_CMOV
3482         def_bool y
3483 -       depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3484 +       depends on (MK8 || MK7 || MCORE2 || MPSC || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || X86_64)
3485  
3486  config X86_MINIMUM_CPU_FAMILY
3487         int
3488 diff -urNp linux-2.6.27.10/arch/x86/Kconfig.debug linux-2.6.27.10/arch/x86/Kconfig.debug
3489 --- linux-2.6.27.10/arch/x86/Kconfig.debug      2008-11-07 12:55:34.000000000 -0500
3490 +++ linux-2.6.27.10/arch/x86/Kconfig.debug      2008-11-18 03:38:44.000000000 -0500
3491 @@ -94,7 +94,7 @@ config X86_PTDUMP
3492  config DEBUG_RODATA
3493         bool "Write protect kernel read-only data structures"
3494         default y
3495 -       depends on DEBUG_KERNEL
3496 +       depends on DEBUG_KERNEL && BROKEN
3497         help
3498           Mark the kernel read-only data as write-protected in the pagetables,
3499           in order to catch accidental (and incorrect) writes to such const
3500 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/boot.c linux-2.6.27.10/arch/x86/kernel/acpi/boot.c
3501 --- linux-2.6.27.10/arch/x86/kernel/acpi/boot.c 2008-12-10 22:35:36.000000000 -0500
3502 +++ linux-2.6.27.10/arch/x86/kernel/acpi/boot.c 2008-12-10 22:35:46.000000000 -0500
3503 @@ -1640,7 +1640,7 @@ static struct dmi_system_id __initdata a
3504                      DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6715b"),
3505                      },
3506          },
3507 -       {}
3508 +       { NULL, NULL, {{0, NULL}}, NULL}
3509  };
3510  
3511  /*
3512 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S
3513 --- linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S      2008-11-07 12:55:34.000000000 -0500
3514 +++ linux-2.6.27.10/arch/x86/kernel/acpi/realmode/wakeup.S      2008-11-18 03:38:44.000000000 -0500
3515 @@ -104,7 +104,7 @@ _start:
3516         movl    %eax, %ecx
3517         orl     %edx, %ecx
3518         jz      1f
3519 -       movl    $0xc0000080, %ecx
3520 +       mov     $MSR_EFER, %ecx
3521         wrmsr
3522  1:
3523  
3524 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c
3525 --- linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c        2008-11-07 12:55:34.000000000 -0500
3526 +++ linux-2.6.27.10/arch/x86/kernel/acpi/sleep.c        2008-11-18 11:45:34.000000000 -0500
3527 @@ -37,6 +37,10 @@ int acpi_save_state_mem(void)
3528  {
3529         struct wakeup_header *header;
3530  
3531 +#if defined(CONFIG_64BIT) && defined(CONFIG_SMP) && defined(CONFIG_PAX_KERNEXEC)
3532 +       unsigned long cr0;
3533 +#endif
3534 +
3535         if (!acpi_realmode) {
3536                 printk(KERN_ERR "Could not allocate memory during boot, "
3537                        "S3 disabled\n");
3538 @@ -99,8 +103,18 @@ int acpi_save_state_mem(void)
3539         header->trampoline_segment = setup_trampoline() >> 4;
3540  #ifdef CONFIG_SMP
3541         stack_start.sp = temp_stack + 4096;
3542 +
3543 +#ifdef CONFIG_PAX_KERNEXEC
3544 +       pax_open_kernel(cr0);
3545 +#endif
3546 +
3547         early_gdt_descr.address =
3548                         (unsigned long)get_cpu_gdt_table(smp_processor_id());
3549 +
3550 +#ifdef CONFIG_PAX_KERNEXEC
3551 +       pax_close_kernel(cr0);
3552 +#endif
3553 +
3554  #endif
3555         initial_code = (unsigned long)wakeup_long64;
3556         saved_magic = 0x123456789abcdef0;
3557 diff -urNp linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S
3558 --- linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S    2008-11-07 12:55:34.000000000 -0500
3559 +++ linux-2.6.27.10/arch/x86/kernel/acpi/wakeup_32.S    2008-11-18 03:38:44.000000000 -0500
3560 @@ -30,13 +30,11 @@ wakeup_pmode_return:
3561         # and restore the stack ... but you need gdt for this to work
3562         movl    saved_context_esp, %esp
3563  
3564 -       movl    %cs:saved_magic, %eax
3565 -       cmpl    $0x12345678, %eax
3566 +       cmpl    $0x12345678, saved_magic
3567         jne     bogus_magic
3568  
3569         # jump to place where we left off
3570 -       movl    saved_eip, %eax
3571 -       jmp     *%eax
3572 +       jmp     *(saved_eip)
3573  
3574  bogus_magic:
3575         jmp     bogus_magic
3576 diff -urNp linux-2.6.27.10/arch/x86/kernel/alternative.c linux-2.6.27.10/arch/x86/kernel/alternative.c
3577 --- linux-2.6.27.10/arch/x86/kernel/alternative.c       2008-11-07 12:55:34.000000000 -0500
3578 +++ linux-2.6.27.10/arch/x86/kernel/alternative.c       2008-11-18 03:38:44.000000000 -0500
3579 @@ -393,7 +393,7 @@ void apply_paravirt(struct paravirt_patc
3580  
3581                 BUG_ON(p->len > MAX_PATCH_LEN);
3582                 /* prep the buffer with the original instructions */
3583 -               memcpy(insnbuf, p->instr, p->len);
3584 +               memcpy(insnbuf, ktla_ktva(p->instr), p->len);
3585                 used = pv_init_ops.patch(p->instrtype, p->clobbers, insnbuf,
3586                                          (unsigned long)p->instr, p->len);
3587  
3588 @@ -473,11 +473,26 @@ void __init alternative_instructions(voi
3589   * instructions. And on the local CPU you need to be protected again NMI or MCE
3590   * handlers seeing an inconsistent instruction while you patch.
3591   */
3592 -void *text_poke_early(void *addr, const void *opcode, size_t len)
3593 +void *__kprobes text_poke_early(void *addr, const void *opcode, size_t len)
3594  {
3595         unsigned long flags;
3596 +
3597 +#ifdef CONFIG_PAX_KERNEXEC
3598 +       unsigned long cr0;
3599 +#endif
3600 +
3601         local_irq_save(flags);
3602 -       memcpy(addr, opcode, len);
3603 +
3604 +#ifdef CONFIG_PAX_KERNEXEC
3605 +       pax_open_kernel(cr0);
3606 +#endif
3607 +
3608 +       memcpy(ktla_ktva(addr), opcode, len);
3609 +
3610 +#ifdef CONFIG_PAX_KERNEXEC
3611 +       pax_close_kernel(cr0);
3612 +#endif
3613 +
3614         local_irq_restore(flags);
3615         sync_core();
3616         /* Could also do a CLFLUSH here to speed up CPU recovery; but
3617 @@ -498,33 +513,27 @@ void *text_poke_early(void *addr, const 
3618   */
3619  void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
3620  {
3621 -       unsigned long flags;
3622 -       char *vaddr;
3623 -       int nr_pages = 2;
3624 +       unsigned char *vaddr = ktla_ktva(addr);
3625         struct page *pages[2];
3626 -       int i;
3627 +       size_t i;
3628 +
3629 +       if (!core_kernel_text((unsigned long)addr)
3630  
3631 -       if (!core_kernel_text((unsigned long)addr)) {
3632 -               pages[0] = vmalloc_to_page(addr);
3633 -               pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
3634 +#if defined(CONFIG_X86_32) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
3635 +           && (vaddr < MODULES_VADDR || MODULES_END < vaddr)
3636 +#endif
3637 +
3638 +          ) {
3639 +               pages[0] = vmalloc_to_page(vaddr);
3640 +               pages[1] = vmalloc_to_page(vaddr + PAGE_SIZE);
3641         } else {
3642 -               pages[0] = virt_to_page(addr);
3643 +               pages[0] = virt_to_page(vaddr);
3644                 WARN_ON(!PageReserved(pages[0]));
3645 -               pages[1] = virt_to_page(addr + PAGE_SIZE);
3646 +               pages[1] = virt_to_page(vaddr + PAGE_SIZE);
3647         }
3648         BUG_ON(!pages[0]);
3649 -       if (!pages[1])
3650 -               nr_pages = 1;
3651 -       vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
3652 -       BUG_ON(!vaddr);
3653 -       local_irq_save(flags);
3654 -       memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
3655 -       local_irq_restore(flags);
3656 -       vunmap(vaddr);
3657 -       sync_core();
3658 -       /* Could also do a CLFLUSH here to speed up CPU recovery; but
3659 -          that causes hangs on some VIA CPUs. */
3660 +       text_poke_early(addr, opcode, len);
3661         for (i = 0; i < len; i++)
3662 -               BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]);
3663 +               BUG_ON((vaddr)[i] != ((unsigned char *)opcode)[i]);
3664         return addr;
3665  }
3666 diff -urNp linux-2.6.27.10/arch/x86/kernel/apm_32.c linux-2.6.27.10/arch/x86/kernel/apm_32.c
3667 --- linux-2.6.27.10/arch/x86/kernel/apm_32.c    2008-11-07 12:55:34.000000000 -0500
3668 +++ linux-2.6.27.10/arch/x86/kernel/apm_32.c    2008-11-18 03:38:44.000000000 -0500
3669 @@ -408,7 +408,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
3670  static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
3671  static struct apm_user *user_list;
3672  static DEFINE_SPINLOCK(user_list_lock);
3673 -static const struct desc_struct        bad_bios_desc = { { { 0, 0x00409200 } } };
3674 +static const struct desc_struct        bad_bios_desc = { { { 0, 0x00409300 } } };
3675  
3676  static const char driver_version[] = "1.16ac"; /* no spaces */
3677  
3678 @@ -603,19 +603,42 @@ static u8 apm_bios_call(u32 func, u32 eb
3679         struct desc_struct      save_desc_40;
3680         struct desc_struct      *gdt;
3681  
3682 +#ifdef CONFIG_PAX_KERNEXEC
3683 +       unsigned long           cr0;
3684 +#endif
3685 +
3686         cpus = apm_save_cpus();
3687  
3688         cpu = get_cpu();
3689         gdt = get_cpu_gdt_table(cpu);
3690         save_desc_40 = gdt[0x40 / 8];
3691 +
3692 +#ifdef CONFIG_PAX_KERNEXEC
3693 +       pax_open_kernel(cr0);
3694 +#endif
3695 +
3696         gdt[0x40 / 8] = bad_bios_desc;
3697  
3698 +#ifdef CONFIG_PAX_KERNEXEC
3699 +       pax_close_kernel(cr0);
3700 +#endif
3701 +
3702         apm_irq_save(flags);
3703         APM_DO_SAVE_SEGS;
3704         apm_bios_call_asm(func, ebx_in, ecx_in, eax, ebx, ecx, edx, esi);
3705         APM_DO_RESTORE_SEGS;
3706         apm_irq_restore(flags);
3707 +
3708 +#ifdef CONFIG_PAX_KERNEXEC
3709 +       pax_open_kernel(cr0);
3710 +#endif
3711 +
3712         gdt[0x40 / 8] = save_desc_40;
3713 +
3714 +#ifdef CONFIG_PAX_KERNEXEC
3715 +       pax_close_kernel(cr0);
3716 +#endif
3717 +
3718         put_cpu();
3719         apm_restore_cpus(cpus);
3720  
3721 @@ -646,19 +669,42 @@ static u8 apm_bios_call_simple(u32 func,
3722         struct desc_struct      save_desc_40;
3723         struct desc_struct      *gdt;
3724  
3725 +#ifdef CONFIG_PAX_KERNEXEC
3726 +       unsigned long           cr0;
3727 +#endif
3728 +
3729         cpus = apm_save_cpus();
3730  
3731         cpu = get_cpu();
3732         gdt = get_cpu_gdt_table(cpu);
3733         save_desc_40 = gdt[0x40 / 8];
3734 +
3735 +#ifdef CONFIG_PAX_KERNEXEC
3736 +       pax_open_kernel(cr0);
3737 +#endif
3738 +
3739         gdt[0x40 / 8] = bad_bios_desc;
3740  
3741 +#ifdef CONFIG_PAX_KERNEXEC
3742 +       pax_close_kernel(cr0);
3743 +#endif
3744 +
3745         apm_irq_save(flags);
3746         APM_DO_SAVE_SEGS;
3747         error = apm_bios_call_simple_asm(func, ebx_in, ecx_in, eax);
3748         APM_DO_RESTORE_SEGS;
3749         apm_irq_restore(flags);
3750 +
3751 +#ifdef CONFIG_PAX_KERNEXEC
3752 +       pax_open_kernel(cr0);
3753 +#endif
3754 +
3755         gdt[0x40 / 8] = save_desc_40;
3756 +
3757 +#ifdef CONFIG_PAX_KERNEXEC
3758 +       pax_close_kernel(cr0);
3759 +#endif
3760 +
3761         put_cpu();
3762         apm_restore_cpus(cpus);
3763         return error;
3764 @@ -930,7 +976,7 @@ recalc:
3765  
3766  static void apm_power_off(void)
3767  {
3768 -       unsigned char po_bios_call[] = {
3769 +       const unsigned char po_bios_call[] = {
3770                 0xb8, 0x00, 0x10,       /* movw  $0x1000,ax  */
3771                 0x8e, 0xd0,             /* movw  ax,ss       */
3772                 0xbc, 0x00, 0xf0,       /* movw  $0xf000,sp  */
3773 @@ -1877,7 +1923,10 @@ static const struct file_operations apm_
3774  static struct miscdevice apm_device = {
3775         APM_MINOR_DEV,
3776         "apm_bios",
3777 -       &apm_bios_fops
3778 +       &apm_bios_fops,
3779 +       {NULL, NULL},
3780 +       NULL,
3781 +       NULL
3782  };
3783  
3784  
3785 @@ -2198,7 +2247,7 @@ static struct dmi_system_id __initdata a
3786                 {       DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
3787         },
3788  
3789 -       { }
3790 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
3791  };
3792  
3793  /*
3794 @@ -2216,6 +2265,10 @@ static int __init apm_init(void)
3795         struct desc_struct *gdt;
3796         int err;
3797  
3798 +#ifdef CONFIG_PAX_KERNEXEC
3799 +       unsigned long cr0;
3800 +#endif
3801 +
3802         dmi_check_system(apm_dmi_table);
3803  
3804         if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
3805 @@ -2289,9 +2342,18 @@ static int __init apm_init(void)
3806          * This is for buggy BIOS's that refer to (real mode) segment 0x40
3807          * even though they are called in protected mode.
3808          */
3809 +
3810 +#ifdef CONFIG_PAX_KERNEXEC
3811 +       pax_open_kernel(cr0);
3812 +#endif
3813 +
3814         set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
3815         _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
3816  
3817 +#ifdef CONFIG_PAX_KERNEXEC
3818 +       pax_close_kernel(cr0);
3819 +#endif
3820 +
3821         /*
3822          * Set up the long jump entry point to the APM BIOS, which is called
3823          * from inline assembly.
3824 @@ -2310,6 +2372,11 @@ static int __init apm_init(void)
3825          * code to that CPU.
3826          */
3827         gdt = get_cpu_gdt_table(0);
3828 +
3829 +#ifdef CONFIG_PAX_KERNEXEC
3830 +       pax_open_kernel(cr0);
3831 +#endif
3832 +
3833         set_base(gdt[APM_CS >> 3],
3834                  __va((unsigned long)apm_info.bios.cseg << 4));
3835         set_base(gdt[APM_CS_16 >> 3],
3836 @@ -2317,6 +2384,10 @@ static int __init apm_init(void)
3837         set_base(gdt[APM_DS >> 3],
3838                  __va((unsigned long)apm_info.bios.dseg << 4));
3839  
3840 +#ifdef CONFIG_PAX_KERNEXEC
3841 +       pax_close_kernel(cr0);
3842 +#endif
3843 +
3844         proc_create("apm", 0, NULL, &apm_file_ops);
3845  
3846         kapmd_task = kthread_create(apm, NULL, "kapmd");
3847 diff -urNp linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c
3848 --- linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c    2008-11-07 12:55:34.000000000 -0500
3849 +++ linux-2.6.27.10/arch/x86/kernel/asm-offsets_32.c    2008-11-18 03:38:44.000000000 -0500
3850 @@ -100,6 +100,7 @@ void foo(void)
3851         DEFINE(PTRS_PER_PTE, PTRS_PER_PTE);
3852         DEFINE(PTRS_PER_PMD, PTRS_PER_PMD);
3853         DEFINE(PTRS_PER_PGD, PTRS_PER_PGD);
3854 +       DEFINE(PERCPU_MODULE_RESERVE, PERCPU_MODULE_RESERVE);
3855  
3856         OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
3857  
3858 @@ -113,6 +114,7 @@ void foo(void)
3859         OFFSET(PV_CPU_iret, pv_cpu_ops, iret);
3860         OFFSET(PV_CPU_irq_enable_sysexit, pv_cpu_ops, irq_enable_sysexit);
3861         OFFSET(PV_CPU_read_cr0, pv_cpu_ops, read_cr0);
3862 +       OFFSET(PV_CPU_write_cr0, pv_cpu_ops, write_cr0);
3863  #endif
3864  
3865  #ifdef CONFIG_XEN
3866 diff -urNp linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c
3867 --- linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c    2008-11-07 12:55:34.000000000 -0500
3868 +++ linux-2.6.27.10/arch/x86/kernel/asm-offsets_64.c    2008-11-18 03:38:44.000000000 -0500
3869 @@ -122,6 +122,7 @@ int main(void)
3870         ENTRY(cr8);
3871         BLANK();
3872  #undef ENTRY
3873 +       DEFINE(TSS_size, sizeof(struct tss_struct));
3874         DEFINE(TSS_ist, offsetof(struct tss_struct, x86_tss.ist));
3875         BLANK();
3876         DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
3877 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c
3878 --- linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c     2008-11-07 12:55:34.000000000 -0500
3879 +++ linux-2.6.27.10/arch/x86/kernel/cpu/common_64.c     2008-11-18 03:38:44.000000000 -0500
3880 @@ -37,22 +37,6 @@
3881  
3882  #include "cpu.h"
3883  
3884 -/* We need valid kernel segments for data and code in long mode too
3885 - * IRET will check the segment types  kkeil 2000/10/28
3886 - * Also sysret mandates a special GDT layout
3887 - */
3888 -/* The TLS descriptors are currently at a different place compared to i386.
3889 -   Hopefully nobody expects them at a fixed place (Wine?) */
3890 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3891 -       [GDT_ENTRY_KERNEL32_CS] = { { { 0x0000ffff, 0x00cf9b00 } } },
3892 -       [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00af9b00 } } },
3893 -       [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9300 } } },
3894 -       [GDT_ENTRY_DEFAULT_USER32_CS] = { { { 0x0000ffff, 0x00cffb00 } } },
3895 -       [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff300 } } },
3896 -       [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00affb00 } } },
3897 -} };
3898 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3899 -
3900  __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
3901  
3902  /* Current gdt points %fs at the "master" per-cpu area: after this,
3903 @@ -457,15 +441,13 @@ cpumask_t cpu_initialized __cpuinitdata 
3904  struct x8664_pda **_cpu_pda __read_mostly;
3905  EXPORT_SYMBOL(_cpu_pda);
3906  
3907 -struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
3908 +struct desc_ptr idt_descr __read_only = { 256 * 16 - 1, (unsigned long) idt_table };
3909  
3910  char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
3911  
3912  unsigned long __supported_pte_mask __read_mostly = ~0UL;
3913  EXPORT_SYMBOL_GPL(__supported_pte_mask);
3914  
3915 -static int do_not_nx __cpuinitdata;
3916 -
3917  /* noexec=on|off
3918  Control non executable mappings for 64bit processes.
3919  
3920 @@ -478,9 +460,7 @@ static int __init nonx_setup(char *str)
3921                 return -EINVAL;
3922         if (!strncmp(str, "on", 2)) {
3923                 __supported_pte_mask |= _PAGE_NX;
3924 -               do_not_nx = 0;
3925         } else if (!strncmp(str, "off", 3)) {
3926 -               do_not_nx = 1;
3927                 __supported_pte_mask &= ~_PAGE_NX;
3928         }
3929         return 0;
3930 @@ -576,7 +556,7 @@ void __cpuinit check_efer(void)
3931         unsigned long efer;
3932  
3933         rdmsrl(MSR_EFER, efer);
3934 -       if (!(efer & EFER_NX) || do_not_nx)
3935 +       if (!(efer & EFER_NX))
3936                 __supported_pte_mask &= ~_PAGE_NX;
3937  }
3938  
3939 @@ -598,7 +578,7 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist
3940  void __cpuinit cpu_init(void)
3941  {
3942         int cpu = stack_smp_processor_id();
3943 -       struct tss_struct *t = &per_cpu(init_tss, cpu);
3944 +       struct tss_struct *t = init_tss + cpu;
3945         struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
3946         unsigned long v;
3947         char *estacks = NULL;
3948 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/common.c linux-2.6.27.10/arch/x86/kernel/cpu/common.c
3949 --- linux-2.6.27.10/arch/x86/kernel/cpu/common.c        2008-11-07 12:55:34.000000000 -0500
3950 +++ linux-2.6.27.10/arch/x86/kernel/cpu/common.c        2008-11-18 03:38:44.000000000 -0500
3951 @@ -4,7 +4,6 @@
3952  #include <linux/smp.h>
3953  #include <linux/module.h>
3954  #include <linux/percpu.h>
3955 -#include <linux/bootmem.h>
3956  #include <asm/processor.h>
3957  #include <asm/i387.h>
3958  #include <asm/msr.h>
3959 @@ -22,42 +21,6 @@
3960  
3961  #include "cpu.h"
3962  
3963 -DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = {
3964 -       [GDT_ENTRY_KERNEL_CS] = { { { 0x0000ffff, 0x00cf9a00 } } },
3965 -       [GDT_ENTRY_KERNEL_DS] = { { { 0x0000ffff, 0x00cf9200 } } },
3966 -       [GDT_ENTRY_DEFAULT_USER_CS] = { { { 0x0000ffff, 0x00cffa00 } } },
3967 -       [GDT_ENTRY_DEFAULT_USER_DS] = { { { 0x0000ffff, 0x00cff200 } } },
3968 -       /*
3969 -        * Segments used for calling PnP BIOS have byte granularity.
3970 -        * They code segments and data segments have fixed 64k limits,
3971 -        * the transfer segment sizes are set at run time.
3972 -        */
3973 -       /* 32-bit code */
3974 -       [GDT_ENTRY_PNPBIOS_CS32] = { { { 0x0000ffff, 0x00409a00 } } },
3975 -       /* 16-bit code */
3976 -       [GDT_ENTRY_PNPBIOS_CS16] = { { { 0x0000ffff, 0x00009a00 } } },
3977 -       /* 16-bit data */
3978 -       [GDT_ENTRY_PNPBIOS_DS] = { { { 0x0000ffff, 0x00009200 } } },
3979 -       /* 16-bit data */
3980 -       [GDT_ENTRY_PNPBIOS_TS1] = { { { 0x00000000, 0x00009200 } } },
3981 -       /* 16-bit data */
3982 -       [GDT_ENTRY_PNPBIOS_TS2] = { { { 0x00000000, 0x00009200 } } },
3983 -       /*
3984 -        * The APM segments have byte granularity and their bases
3985 -        * are set at run time.  All have 64k limits.
3986 -        */
3987 -       /* 32-bit code */
3988 -       [GDT_ENTRY_APMBIOS_BASE] = { { { 0x0000ffff, 0x00409a00 } } },
3989 -       /* 16-bit code */
3990 -       [GDT_ENTRY_APMBIOS_BASE+1] = { { { 0x0000ffff, 0x00009a00 } } },
3991 -       /* data */
3992 -       [GDT_ENTRY_APMBIOS_BASE+2] = { { { 0x0000ffff, 0x00409200 } } },
3993 -
3994 -       [GDT_ENTRY_ESPFIX_SS] = { { { 0x00000000, 0x00c09200 } } },
3995 -       [GDT_ENTRY_PERCPU] = { { { 0x00000000, 0x00000000 } } },
3996 -} };
3997 -EXPORT_PER_CPU_SYMBOL_GPL(gdt_page);
3998 -
3999  __u32 cleared_cpu_caps[NCAPINTS] __cpuinitdata;
4000  
4001  static int cachesize_override __cpuinitdata = -1;
4002 @@ -493,6 +456,10 @@ static void __cpuinit identify_cpu(struc
4003          * we do "generic changes."
4004          */
4005  
4006 +#if defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4007 +       setup_clear_cpu_cap(X86_FEATURE_SEP);
4008 +#endif
4009 +
4010         /* If the model name is still unset, do table lookup. */
4011         if (!c->x86_model_id[0]) {
4012                 char *p;
4013 @@ -629,7 +596,7 @@ static __init int setup_disablecpuid(cha
4014  }
4015  __setup("clearcpuid=", setup_disablecpuid);
4016  
4017 -cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
4018 +cpumask_t cpu_initialized = CPU_MASK_NONE;
4019  
4020  void __init early_cpu_init(void)
4021  {
4022 @@ -658,7 +625,7 @@ void switch_to_new_gdt(void)
4023  {
4024         struct desc_ptr gdt_descr;
4025  
4026 -       gdt_descr.address = (long)get_cpu_gdt_table(smp_processor_id());
4027 +       gdt_descr.address = (unsigned long)get_cpu_gdt_table(smp_processor_id());
4028         gdt_descr.size = GDT_SIZE - 1;
4029         load_gdt(&gdt_descr);
4030         asm("mov %0, %%fs" : : "r" (__KERNEL_PERCPU) : "memory");
4031 @@ -674,7 +641,7 @@ void __cpuinit cpu_init(void)
4032  {
4033         int cpu = smp_processor_id();
4034         struct task_struct *curr = current;
4035 -       struct tss_struct *t = &per_cpu(init_tss, cpu);
4036 +       struct tss_struct *t = init_tss + cpu;
4037         struct thread_struct *thread = &curr->thread;
4038  
4039         if (cpu_test_and_set(cpu, cpu_initialized)) {
4040 @@ -729,7 +696,7 @@ void __cpuinit cpu_init(void)
4041  }
4042  
4043  #ifdef CONFIG_HOTPLUG_CPU
4044 -void __cpuinit cpu_uninit(void)
4045 +void cpu_uninit(void)
4046  {
4047         int cpu = raw_smp_processor_id();
4048         cpu_clear(cpu, cpu_initialized);
4049 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
4050 --- linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c  2008-11-07 12:55:34.000000000 -0500
4051 +++ linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c  2008-11-18 03:38:44.000000000 -0500
4052 @@ -560,7 +560,7 @@ static const struct dmi_system_id sw_any
4053                         DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
4054                 },
4055         },
4056 -       { }
4057 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
4058  };
4059  #endif
4060  
4061 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
4062 --- linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c    2008-11-07 12:55:34.000000000 -0500
4063 +++ linux-2.6.27.10/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c    2008-11-18 03:38:44.000000000 -0500
4064 @@ -225,7 +225,7 @@ static struct cpu_model models[] =
4065         { &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
4066         { &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
4067  
4068 -       { NULL, }
4069 +       { NULL, NULL, 0, NULL}
4070  };
4071  #undef _BANIAS
4072  #undef BANIAS
4073 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/intel.c linux-2.6.27.10/arch/x86/kernel/cpu/intel.c
4074 --- linux-2.6.27.10/arch/x86/kernel/cpu/intel.c 2008-11-07 12:55:34.000000000 -0500
4075 +++ linux-2.6.27.10/arch/x86/kernel/cpu/intel.c 2008-11-18 03:38:44.000000000 -0500
4076 @@ -107,7 +107,7 @@ static void __cpuinit trap_init_f00f_bug
4077          * Update the IDT descriptor and reload the IDT so that
4078          * it uses the read-only mapped virtual address.
4079          */
4080 -       idt_descr.address = fix_to_virt(FIX_F00F_IDT);
4081 +       idt_descr.address = (struct desc_struct *)fix_to_virt(FIX_F00F_IDT);
4082         load_idt(&idt_descr);
4083  }
4084  #endif
4085 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c
4086 --- linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-07 12:55:34.000000000 -0500
4087 +++ linux-2.6.27.10/arch/x86/kernel/cpu/mcheck/mce_64.c 2008-11-18 03:38:44.000000000 -0500
4088 @@ -681,6 +681,7 @@ static struct miscdevice mce_log_device 
4089         MISC_MCELOG_MINOR,
4090         "mcelog",
4091         &mce_chrdev_ops,
4092 +       {NULL, NULL}, NULL, NULL
4093  };
4094  
4095  static unsigned long old_cr4 __initdata;
4096 diff -urNp linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c
4097 --- linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c  2008-11-07 12:55:34.000000000 -0500
4098 +++ linux-2.6.27.10/arch/x86/kernel/cpu/mtrr/generic.c  2008-11-18 03:38:44.000000000 -0500
4099 @@ -31,11 +31,11 @@ static struct fixed_range_block fixed_ra
4100         { MTRRfix64K_00000_MSR, 1 }, /* one  64k MTRR  */
4101         { MTRRfix16K_80000_MSR, 2 }, /* two  16k MTRRs */
4102         { MTRRfix4K_C0000_MSR,  8 }, /* eight 4k MTRRs */
4103 -       {}
4104 +       { 0, 0 }
4105  };
4106  
4107  static unsigned long smp_changes_mask;
4108 -static struct mtrr_state mtrr_state = {};
4109 +static struct mtrr_state mtrr_state;
4110  static int mtrr_state_set;
4111  u64 mtrr_tom2;
4112  
4113 diff -urNp linux-2.6.27.10/arch/x86/kernel/crash.c linux-2.6.27.10/arch/x86/kernel/crash.c
4114 --- linux-2.6.27.10/arch/x86/kernel/crash.c     2008-11-07 12:55:34.000000000 -0500
4115 +++ linux-2.6.27.10/arch/x86/kernel/crash.c     2008-11-18 03:38:44.000000000 -0500
4116 @@ -59,7 +59,7 @@ static int crash_nmi_callback(struct not
4117         local_irq_disable();
4118  
4119  #ifdef CONFIG_X86_32
4120 -       if (!user_mode_vm(regs)) {
4121 +       if (!user_mode(regs)) {
4122                 crash_fixup_ss_esp(&fixed_regs, regs);
4123                 regs = &fixed_regs;
4124         }
4125 diff -urNp linux-2.6.27.10/arch/x86/kernel/doublefault_32.c linux-2.6.27.10/arch/x86/kernel/doublefault_32.c
4126 --- linux-2.6.27.10/arch/x86/kernel/doublefault_32.c    2008-11-07 12:55:34.000000000 -0500
4127 +++ linux-2.6.27.10/arch/x86/kernel/doublefault_32.c    2008-11-18 03:38:44.000000000 -0500
4128 @@ -11,7 +11,7 @@
4129  
4130  #define DOUBLEFAULT_STACKSIZE (1024)
4131  static unsigned long doublefault_stack[DOUBLEFAULT_STACKSIZE];
4132 -#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE)
4133 +#define STACK_START (unsigned long)(doublefault_stack+DOUBLEFAULT_STACKSIZE-2)
4134  
4135  #define ptr_ok(x) ((x) > PAGE_OFFSET && (x) < PAGE_OFFSET + MAXMEM)
4136  
4137 @@ -21,7 +21,7 @@ static void doublefault_fn(void)
4138         unsigned long gdt, tss;
4139  
4140         store_gdt(&gdt_desc);
4141 -       gdt = gdt_desc.address;
4142 +       gdt = (unsigned long)gdt_desc.address;
4143  
4144         printk(KERN_EMERG "PANIC: double fault, gdt at %08lx [%d bytes]\n", gdt, gdt_desc.size);
4145  
4146 @@ -60,10 +60,10 @@ struct tss_struct doublefault_tss __cach
4147                 /* 0x2 bit is always set */
4148                 .flags          = X86_EFLAGS_SF | 0x2,
4149                 .sp             = STACK_START,
4150 -               .es             = __USER_DS,
4151 +               .es             = __KERNEL_DS,
4152                 .cs             = __KERNEL_CS,
4153                 .ss             = __KERNEL_DS,
4154 -               .ds             = __USER_DS,
4155 +               .ds             = __KERNEL_DS,
4156                 .fs             = __KERNEL_PERCPU,
4157  
4158                 .__cr3          = __pa(swapper_pg_dir)
4159 diff -urNp linux-2.6.27.10/arch/x86/kernel/efi_32.c linux-2.6.27.10/arch/x86/kernel/efi_32.c
4160 --- linux-2.6.27.10/arch/x86/kernel/efi_32.c    2008-11-07 12:55:34.000000000 -0500
4161 +++ linux-2.6.27.10/arch/x86/kernel/efi_32.c    2008-11-18 03:38:44.000000000 -0500
4162 @@ -38,70 +38,38 @@
4163   */
4164  
4165  static unsigned long efi_rt_eflags;
4166 -static pgd_t efi_bak_pg_dir_pointer[2];
4167 +static pgd_t __initdata efi_bak_pg_dir_pointer[KERNEL_PGD_PTRS];
4168  
4169 -void efi_call_phys_prelog(void)
4170 +void __init efi_call_phys_prelog(void)
4171  {
4172 -       unsigned long cr4;
4173 -       unsigned long temp;
4174         struct desc_ptr gdt_descr;
4175  
4176         local_irq_save(efi_rt_eflags);
4177  
4178 -       /*
4179 -        * If I don't have PAE, I should just duplicate two entries in page
4180 -        * directory. If I have PAE, I just need to duplicate one entry in
4181 -        * page directory.
4182 -        */
4183 -       cr4 = read_cr4_safe();
4184  
4185 -       if (cr4 & X86_CR4_PAE) {
4186 -               efi_bak_pg_dir_pointer[0].pgd =
4187 -                   swapper_pg_dir[pgd_index(0)].pgd;
4188 -               swapper_pg_dir[0].pgd =
4189 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4190 -       } else {
4191 -               efi_bak_pg_dir_pointer[0].pgd =
4192 -                   swapper_pg_dir[pgd_index(0)].pgd;
4193 -               efi_bak_pg_dir_pointer[1].pgd =
4194 -                   swapper_pg_dir[pgd_index(0x400000)].pgd;
4195 -               swapper_pg_dir[pgd_index(0)].pgd =
4196 -                   swapper_pg_dir[pgd_index(PAGE_OFFSET)].pgd;
4197 -               temp = PAGE_OFFSET + 0x400000;
4198 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
4199 -                   swapper_pg_dir[pgd_index(temp)].pgd;
4200 -       }
4201 +       clone_pgd_range(efi_bak_pg_dir_pointer, swapper_pg_dir, KERNEL_PGD_PTRS);
4202 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
4203 +                       min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
4204  
4205         /*
4206          * After the lock is released, the original page table is restored.
4207          */
4208         __flush_tlb_all();
4209  
4210 -       gdt_descr.address = __pa(get_cpu_gdt_table(0));
4211 +       gdt_descr.address = (struct desc_struct *)__pa(get_cpu_gdt_table(0));
4212         gdt_descr.size = GDT_SIZE - 1;
4213         load_gdt(&gdt_descr);
4214  }
4215  
4216 -void efi_call_phys_epilog(void)
4217 +void __init efi_call_phys_epilog(void)
4218  {
4219 -       unsigned long cr4;
4220         struct desc_ptr gdt_descr;
4221  
4222 -       gdt_descr.address = (unsigned long)get_cpu_gdt_table(0);
4223 +       gdt_descr.address = get_cpu_gdt_table(0);
4224         gdt_descr.size = GDT_SIZE - 1;
4225         load_gdt(&gdt_descr);
4226  
4227 -       cr4 = read_cr4_safe();
4228 -
4229 -       if (cr4 & X86_CR4_PAE) {
4230 -               swapper_pg_dir[pgd_index(0)].pgd =
4231 -                   efi_bak_pg_dir_pointer[0].pgd;
4232 -       } else {
4233 -               swapper_pg_dir[pgd_index(0)].pgd =
4234 -                   efi_bak_pg_dir_pointer[0].pgd;
4235 -               swapper_pg_dir[pgd_index(0x400000)].pgd =
4236 -                   efi_bak_pg_dir_pointer[1].pgd;
4237 -       }
4238 +       clone_pgd_range(swapper_pg_dir, efi_bak_pg_dir_pointer, KERNEL_PGD_PTRS);
4239  
4240         /*
4241          * After the lock is released, the original page table is restored.
4242 diff -urNp linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S
4243 --- linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S       2008-11-07 12:55:34.000000000 -0500
4244 +++ linux-2.6.27.10/arch/x86/kernel/efi_stub_32.S       2008-11-18 03:38:44.000000000 -0500
4245 @@ -6,6 +6,7 @@
4246   */
4247  
4248  #include <linux/linkage.h>
4249 +#include <linux/init.h>
4250  #include <asm/page.h>
4251  
4252  /*
4253 @@ -20,7 +21,7 @@
4254   * service functions will comply with gcc calling convention, too.
4255   */
4256  
4257 -.text
4258 +__INIT
4259  ENTRY(efi_call_phys)
4260         /*
4261          * 0. The function can only be called in Linux kernel. So CS has been
4262 @@ -36,9 +37,7 @@ ENTRY(efi_call_phys)
4263          * The mapping of lower virtual memory has been created in prelog and
4264          * epilog.
4265          */
4266 -       movl    $1f, %edx
4267 -       subl    $__PAGE_OFFSET, %edx
4268 -       jmp     *%edx
4269 +       jmp     1f-__PAGE_OFFSET
4270  1:
4271  
4272         /*
4273 @@ -47,14 +46,8 @@ ENTRY(efi_call_phys)
4274          * parameter 2, ..., param n. To make things easy, we save the return
4275          * address of efi_call_phys in a global variable.
4276          */
4277 -       popl    %edx
4278 -       movl    %edx, saved_return_addr
4279 -       /* get the function pointer into ECX*/
4280 -       popl    %ecx
4281 -       movl    %ecx, efi_rt_function_ptr
4282 -       movl    $2f, %edx
4283 -       subl    $__PAGE_OFFSET, %edx
4284 -       pushl   %edx
4285 +       popl    (saved_return_addr)
4286 +       popl    (efi_rt_function_ptr)
4287  
4288         /*
4289          * 3. Clear PG bit in %CR0.
4290 @@ -73,9 +66,8 @@ ENTRY(efi_call_phys)
4291         /*
4292          * 5. Call the physical function.
4293          */
4294 -       jmp     *%ecx
4295 +       call    *(efi_rt_function_ptr-__PAGE_OFFSET)
4296  
4297 -2:
4298         /*
4299          * 6. After EFI runtime service returns, control will return to
4300          * following instruction. We'd better readjust stack pointer first.
4301 @@ -88,34 +80,27 @@ ENTRY(efi_call_phys)
4302         movl    %cr0, %edx
4303         orl     $0x80000000, %edx
4304         movl    %edx, %cr0
4305 -       jmp     1f
4306 -1:
4307 +
4308         /*
4309          * 8. Now restore the virtual mode from flat mode by
4310          * adding EIP with PAGE_OFFSET.
4311          */
4312 -       movl    $1f, %edx
4313 -       jmp     *%edx
4314 +       jmp     1f+__PAGE_OFFSET
4315  1:
4316  
4317         /*
4318          * 9. Balance the stack. And because EAX contain the return value,
4319          * we'd better not clobber it.
4320          */
4321 -       leal    efi_rt_function_ptr, %edx
4322 -       movl    (%edx), %ecx
4323 -       pushl   %ecx
4324 +       pushl   (efi_rt_function_ptr)
4325  
4326         /*
4327 -        * 10. Push the saved return address onto the stack and return.
4328 +        * 10. Return to the saved return address.
4329          */
4330 -       leal    saved_return_addr, %edx
4331 -       movl    (%edx), %ecx
4332 -       pushl   %ecx
4333 -       ret
4334 +       jmpl    *(saved_return_addr)
4335  .previous
4336  
4337 -.data
4338 +__INITDATA
4339  saved_return_addr:
4340         .long 0
4341  efi_rt_function_ptr:
4342 diff -urNp linux-2.6.27.10/arch/x86/kernel/entry_32.S linux-2.6.27.10/arch/x86/kernel/entry_32.S
4343 --- linux-2.6.27.10/arch/x86/kernel/entry_32.S  2008-11-07 12:55:34.000000000 -0500
4344 +++ linux-2.6.27.10/arch/x86/kernel/entry_32.S  2008-11-18 03:38:44.000000000 -0500
4345 @@ -101,7 +101,7 @@
4346  #define resume_userspace_sig   resume_userspace
4347  #endif
4348  
4349 -#define SAVE_ALL \
4350 +#define __SAVE_ALL(_DS) \
4351         cld; \
4352         pushl %fs; \
4353         CFI_ADJUST_CFA_OFFSET 4;\
4354 @@ -133,12 +133,26 @@
4355         pushl %ebx; \
4356         CFI_ADJUST_CFA_OFFSET 4;\
4357         CFI_REL_OFFSET ebx, 0;\
4358 -       movl $(__USER_DS), %edx; \
4359 +       movl $(_DS), %edx; \
4360         movl %edx, %ds; \
4361         movl %edx, %es; \
4362         movl $(__KERNEL_PERCPU), %edx; \
4363         movl %edx, %fs
4364  
4365 +#ifdef CONFIG_PAX_KERNEXEC
4366 +#define SAVE_ALL \
4367 +       __SAVE_ALL(__KERNEL_DS); \
4368 +       GET_CR0_INTO_EDX; \
4369 +       movl %edx, %esi; \
4370 +       orl $X86_CR0_WP, %edx; \
4371 +       xorl %edx, %esi; \
4372 +       SET_CR0_FROM_EDX
4373 +#elif defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
4374 +#define SAVE_ALL __SAVE_ALL(__KERNEL_DS)
4375 +#else
4376 +#define SAVE_ALL __SAVE_ALL(__USER_DS)
4377 +#endif
4378 +
4379  #define RESTORE_INT_REGS \
4380         popl %ebx;      \
4381         CFI_ADJUST_CFA_OFFSET -4;\
4382 @@ -229,6 +243,11 @@ ENTRY(ret_from_fork)
4383         CFI_ADJUST_CFA_OFFSET 4
4384         popfl
4385         CFI_ADJUST_CFA_OFFSET -4
4386 +
4387 +#ifdef CONFIG_PAX_KERNEXEC
4388 +       xorl %esi, %esi
4389 +#endif
4390 +
4391         jmp syscall_exit
4392         CFI_ENDPROC
4393  END(ret_from_fork)
4394 @@ -252,7 +271,17 @@ check_userspace:
4395         movb PT_CS(%esp), %al
4396         andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
4397         cmpl $USER_RPL, %eax
4398 +
4399 +#ifdef CONFIG_PAX_KERNEXEC
4400 +       jae resume_userspace
4401 +       
4402 +       GET_CR0_INTO_EDX
4403 +       xorl %esi, %edx
4404 +       SET_CR0_FROM_EDX
4405 +       jmp resume_kernel
4406 +#else
4407         jb resume_kernel                # not returning to v8086 or userspace
4408 +#endif
4409  
4410  ENTRY(resume_userspace)
4411         LOCKDEP_SYS_EXIT
4412 @@ -314,10 +343,9 @@ sysenter_past_esp:
4413         /*CFI_REL_OFFSET cs, 0*/
4414         /*
4415          * Push current_thread_info()->sysenter_return to the stack.
4416 -        * A tiny bit of offset fixup is necessary - 4*4 means the 4 words
4417 -        * pushed above; +8 corresponds to copy_thread's esp0 setting.
4418          */
4419 -       pushl (TI_sysenter_return-THREAD_SIZE+8+4*4)(%esp)
4420 +       GET_THREAD_INFO(%ebp)
4421 +       pushl TI_sysenter_return(%ebp)
4422         CFI_ADJUST_CFA_OFFSET 4
4423         CFI_REL_OFFSET eip, 0
4424  
4425 @@ -330,9 +358,17 @@ sysenter_past_esp:
4426   * Load the potential sixth argument from user stack.
4427   * Careful about security.
4428   */
4429 +       movl PT_OLDESP(%esp),%ebp
4430 +
4431 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4432 +       mov PT_OLDSS(%esp),%ds
4433 +1:     movl %ds:(%ebp),%ebp
4434 +#else
4435         cmpl $__PAGE_OFFSET-3,%ebp
4436         jae syscall_fault
4437  1:     movl (%ebp),%ebp
4438 +#endif
4439 +
4440         movl %ebp,PT_EBP(%esp)
4441  .section __ex_table,"a"
4442         .align 4
4443 @@ -356,12 +392,23 @@ sysenter_do_call:
4444         testw $_TIF_ALLWORK_MASK, %cx
4445         jne sysexit_audit
4446  sysenter_exit:
4447 +
4448 +#ifdef CONFIG_PAX_RANDKSTACK
4449 +       pushl %eax
4450 +       CFI_ADJUST_CFA_OFFSET 4
4451 +       call pax_randomize_kstack
4452 +       popl %eax
4453 +       CFI_ADJUST_CFA_OFFSET -4
4454 +#endif
4455 +
4456  /* if something modifies registers it must also disable sysexit */
4457         movl PT_EIP(%esp), %edx
4458         movl PT_OLDESP(%esp), %ecx
4459         xorl %ebp,%ebp
4460         TRACE_IRQS_ON
4461  1:     mov  PT_FS(%esp), %fs
4462 +2:     mov  PT_DS(%esp), %ds
4463 +3:     mov  PT_ES(%esp), %es
4464         ENABLE_INTERRUPTS_SYSEXIT
4465  
4466  #ifdef CONFIG_AUDITSYSCALL
4467 @@ -404,11 +451,17 @@ sysexit_audit:
4468  
4469         CFI_ENDPROC
4470  .pushsection .fixup,"ax"
4471 -2:     movl $0,PT_FS(%esp)
4472 +4:     movl $0,PT_FS(%esp)
4473 +       jmp 1b
4474 +5:     movl $0,PT_DS(%esp)
4475 +       jmp 1b
4476 +6:     movl $0,PT_ES(%esp)
4477         jmp 1b
4478  .section __ex_table,"a"
4479         .align 4
4480 -       .long 1b,2b
4481 +       .long 1b,4b
4482 +       .long 2b,5b
4483 +       .long 3b,6b
4484  .popsection
4485  ENDPROC(ia32_sysenter_target)
4486  
4487 @@ -438,6 +491,10 @@ syscall_exit:
4488         testw $_TIF_ALLWORK_MASK, %cx   # current->work
4489         jne syscall_exit_work
4490  
4491 +#ifdef CONFIG_PAX_RANDKSTACK
4492 +       call pax_randomize_kstack
4493 +#endif
4494 +
4495  restore_all:
4496         movl PT_EFLAGS(%esp), %eax      # mix EFLAGS, SS and CS
4497         # Warning: PT_OLDSS(%esp) contains the wrong/random values if we
4498 @@ -531,25 +588,19 @@ work_resched:
4499  
4500  work_notifysig:                                # deal with pending signals and
4501                                         # notify-resume requests
4502 +       movl %esp, %eax
4503  #ifdef CONFIG_VM86
4504         testl $X86_EFLAGS_VM, PT_EFLAGS(%esp)
4505 -       movl %esp, %eax
4506 -       jne work_notifysig_v86          # returning to kernel-space or
4507 +       jz 1f                           # returning to kernel-space or
4508                                         # vm86-space
4509 -       xorl %edx, %edx
4510 -       call do_notify_resume
4511 -       jmp resume_userspace_sig
4512  
4513 -       ALIGN
4514 -work_notifysig_v86:
4515         pushl %ecx                      # save ti_flags for do_notify_resume
4516         CFI_ADJUST_CFA_OFFSET 4
4517         call save_v86_state             # %eax contains pt_regs pointer
4518         popl %ecx
4519         CFI_ADJUST_CFA_OFFSET -4
4520         movl %eax, %esp
4521 -#else
4522 -       movl %esp, %eax
4523 +1:
4524  #endif
4525         xorl %edx, %edx
4526         call do_notify_resume
4527 @@ -595,17 +646,24 @@ syscall_badsys:
4528  END(syscall_badsys)
4529         CFI_ENDPROC
4530  
4531 -#define FIXUP_ESPFIX_STACK \
4532 -       /* since we are on a wrong stack, we cant make it a C code :( */ \
4533 -       PER_CPU(gdt_page, %ebx); \
4534 -       GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah); \
4535 -       addl %esp, %eax; \
4536 -       pushl $__KERNEL_DS; \
4537 -       CFI_ADJUST_CFA_OFFSET 4; \
4538 -       pushl %eax; \
4539 -       CFI_ADJUST_CFA_OFFSET 4; \
4540 -       lss (%esp), %esp; \
4541 +.macro FIXUP_ESPFIX_STACK
4542 +       /* since we are on a wrong stack, we cant make it a C code :( */
4543 +#ifdef CONFIG_SMP
4544 +       movl PER_CPU_VAR(cpu_number), %ebx;
4545 +       shll $PAGE_SHIFT_asm, %ebx;
4546 +       addl $cpu_gdt_table, %ebx;
4547 +#else
4548 +       movl $cpu_gdt_table, %ebx;
4549 +#endif
4550 +       GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah);
4551 +       addl %esp, %eax;
4552 +       pushl $__KERNEL_DS;
4553 +       CFI_ADJUST_CFA_OFFSET 4;
4554 +       pushl %eax;
4555 +       CFI_ADJUST_CFA_OFFSET 4;
4556 +       lss (%esp), %esp;
4557         CFI_ADJUST_CFA_OFFSET -8;
4558 +.endm
4559  #define UNWIND_ESPFIX_STACK \
4560         movl %ss, %eax; \
4561         /* see if on espfix stack */ \
4562 @@ -622,7 +680,7 @@ END(syscall_badsys)
4563   * Build the entry stubs and pointer table with
4564   * some assembler magic.
4565   */
4566 -.section .rodata,"a"
4567 +.section .rodata,"a",@progbits
4568  ENTRY(interrupt)
4569  .text
4570  
4571 @@ -722,12 +780,21 @@ error_code:
4572         popl %ecx
4573         CFI_ADJUST_CFA_OFFSET -4
4574         /*CFI_REGISTER es, ecx*/
4575 +
4576 +#ifdef CONFIG_PAX_KERNEXEC
4577 +       GET_CR0_INTO_EDX
4578 +       movl %edx, %esi
4579 +       orl $X86_CR0_WP, %edx
4580 +       xorl %edx, %esi
4581 +       SET_CR0_FROM_EDX
4582 +#endif
4583 +
4584         movl PT_FS(%esp), %edi          # get the function address
4585         movl PT_ORIG_EAX(%esp), %edx    # get the error code
4586         movl $-1, PT_ORIG_EAX(%esp)     # no syscall to restart
4587         mov  %ecx, PT_FS(%esp)
4588         /*CFI_REL_OFFSET fs, ES*/
4589 -       movl $(__USER_DS), %ecx
4590 +       movl $(__KERNEL_DS), %ecx
4591         movl %ecx, %ds
4592         movl %ecx, %es
4593         movl %esp,%eax                  # pt_regs pointer
4594 @@ -861,6 +928,13 @@ nmi_stack_correct:
4595         xorl %edx,%edx          # zero error code
4596         movl %esp,%eax          # pt_regs pointer
4597         call do_nmi
4598 +
4599 +#ifdef CONFIG_PAX_KERNEXEC
4600 +       GET_CR0_INTO_EDX
4601 +       xorl %esi, %edx
4602 +       SET_CR0_FROM_EDX
4603 +#endif
4604 +
4605         jmp restore_nocheck_notrace
4606         CFI_ENDPROC
4607  
4608 @@ -901,6 +975,13 @@ nmi_espfix_stack:
4609         FIXUP_ESPFIX_STACK              # %eax == %esp
4610         xorl %edx,%edx                  # zero error code
4611         call do_nmi
4612 +
4613 +#ifdef CONFIG_PAX_KERNEXEC
4614 +       GET_CR0_INTO_EDX
4615 +       xorl %esi, %edx
4616 +       SET_CR0_FROM_EDX
4617 +#endif
4618 +
4619         RESTORE_REGS
4620         lss 12+4(%esp), %esp            # back to espfix stack
4621         CFI_ADJUST_CFA_OFFSET -24
4622 @@ -1226,7 +1307,6 @@ END(mcount)
4623  #endif /* CONFIG_DYNAMIC_FTRACE */
4624  #endif /* CONFIG_FTRACE */
4625  
4626 -.section .rodata,"a"
4627  #include "syscall_table_32.S"
4628  
4629  syscall_table_size=(.-sys_call_table)
4630 diff -urNp linux-2.6.27.10/arch/x86/kernel/entry_64.S linux-2.6.27.10/arch/x86/kernel/entry_64.S
4631 --- linux-2.6.27.10/arch/x86/kernel/entry_64.S  2008-11-07 12:55:34.000000000 -0500
4632 +++ linux-2.6.27.10/arch/x86/kernel/entry_64.S  2008-11-18 03:38:44.000000000 -0500
4633 @@ -930,17 +930,18 @@ END(spurious_interrupt)
4634         xorl  %ebx,%ebx
4635  1:
4636         .if \ist
4637 -       movq    %gs:pda_data_offset, %rbp
4638 +       imul    $TSS_size, %gs:pda_cpunumber, %ebp
4639 +       lea     init_tss(%rbp), %rbp
4640         .endif
4641         movq %rsp,%rdi
4642         movq ORIG_RAX(%rsp),%rsi
4643         movq $-1,ORIG_RAX(%rsp)
4644         .if \ist
4645 -       subq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4646 +       subq    $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4647         .endif
4648         call \sym
4649         .if \ist
4650 -       addq    $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
4651 +       addq    $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
4652         .endif
4653         DISABLE_INTERRUPTS(CLBR_NONE)
4654         .if \irqtrace
4655 diff -urNp linux-2.6.27.10/arch/x86/kernel/ftrace.c linux-2.6.27.10/arch/x86/kernel/ftrace.c
4656 --- linux-2.6.27.10/arch/x86/kernel/ftrace.c    2008-11-07 12:55:34.000000000 -0500
4657 +++ linux-2.6.27.10/arch/x86/kernel/ftrace.c    2008-12-10 22:28:27.000000000 -0500
4658 @@ -103,9 +103,9 @@ notrace int ftrace_update_ftrace_func(ft
4659         unsigned char old[MCOUNT_INSN_SIZE], *new;
4660         int ret;
4661  
4662 -       memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
4663 +       memcpy(old, (void *)ktla_ktva((unsigned long)ftrace_call), MCOUNT_INSN_SIZE);
4664         new = ftrace_call_replace(ip, (unsigned long)func);
4665 -       ret = ftrace_modify_code(ip, old, new);
4666 +       ret = ftrace_modify_code(ktla_ktva(ip), old, new);
4667  
4668         return ret;
4669  }
4670 @@ -120,9 +120,9 @@ notrace int ftrace_mcount_set(unsigned l
4671          * Replace the mcount stub with a pointer to the
4672          * ip recorder function.
4673          */
4674 -       memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
4675 +       memcpy(old, ktla_ktva(mcount_call), MCOUNT_INSN_SIZE);
4676         new = ftrace_call_replace(ip, *addr);
4677 -       *addr = ftrace_modify_code(ip, old, new);
4678 +       *addr = ftrace_modify_code(ktla_ktva(ip), old, new);
4679  
4680         return 0;
4681  }
4682 diff -urNp linux-2.6.27.10/arch/x86/kernel/head32.c linux-2.6.27.10/arch/x86/kernel/head32.c
4683 --- linux-2.6.27.10/arch/x86/kernel/head32.c    2008-11-07 12:55:34.000000000 -0500
4684 +++ linux-2.6.27.10/arch/x86/kernel/head32.c    2008-11-18 03:38:44.000000000 -0500
4685 @@ -12,10 +12,11 @@
4686  #include <asm/sections.h>
4687  #include <asm/e820.h>
4688  #include <asm/bios_ebda.h>
4689 +#include <asm/boot.h>
4690  
4691  void __init i386_start_kernel(void)
4692  {
4693 -       reserve_early(__pa_symbol(&_text), __pa_symbol(&_end), "TEXT DATA BSS");
4694 +       reserve_early(LOAD_PHYSICAL_ADDR, __pa_symbol(&_end), "TEXT DATA BSS");
4695  
4696  #ifdef CONFIG_BLK_DEV_INITRD
4697         /* Reserve INITRD */
4698 diff -urNp linux-2.6.27.10/arch/x86/kernel/head_32.S linux-2.6.27.10/arch/x86/kernel/head_32.S
4699 --- linux-2.6.27.10/arch/x86/kernel/head_32.S   2008-11-07 12:55:34.000000000 -0500
4700 +++ linux-2.6.27.10/arch/x86/kernel/head_32.S   2008-11-18 03:38:44.000000000 -0500
4701 @@ -19,6 +19,7 @@
4702  #include <asm/asm-offsets.h>
4703  #include <asm/setup.h>
4704  #include <asm/processor-flags.h>
4705 +#include <asm/msr-index.h>
4706  
4707  /* Physical address */
4708  #define pa(X) ((X) - __PAGE_OFFSET)
4709 @@ -64,17 +65,22 @@ LOW_PAGES = 1<<(32-PAGE_SHIFT_asm)
4710  LOW_PAGES = LOW_PAGES + 0x1000000
4711  #endif
4712  
4713 -#if PTRS_PER_PMD > 1
4714 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PMD) + PTRS_PER_PGD
4715 -#else
4716 -PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PGD)
4717 -#endif
4718 +PAGE_TABLE_SIZE = (LOW_PAGES / PTRS_PER_PTE)
4719  BOOTBITMAP_SIZE = LOW_PAGES / 8
4720  ALLOCATOR_SLOP = 4
4721  
4722  INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + (PAGE_TABLE_SIZE + ALLOCATOR_SLOP)*PAGE_SIZE_asm
4723  
4724  /*
4725 + * Real beginning of normal "text" segment
4726 + */
4727 +ENTRY(stext)
4728 +ENTRY(_stext)
4729 +
4730 +.section .text.startup,"ax",@progbits
4731 +       ljmp $(__BOOT_CS),$phys_startup_32
4732 +
4733 +/*
4734   * 32-bit kernel entrypoint; only used by the boot CPU.  On entry,
4735   * %esi points to the real-mode code as a 32-bit pointer.
4736   * CS and DS must be 4 GB flat segments, but we don't depend on
4737 @@ -82,6 +88,12 @@ INIT_MAP_BEYOND_END = BOOTBITMAP_SIZE + 
4738   * can.
4739   */
4740  .section .text.head,"ax",@progbits
4741 +
4742 +#ifdef CONFIG_PAX_KERNEXEC
4743 +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */
4744 +.fill 4096,1,0xcc
4745 +#endif
4746 +
4747  ENTRY(startup_32)
4748         /* test KEEP_SEGMENTS flag to see if the bootloader is asking
4749                 us to not reload segments */
4750 @@ -99,6 +111,56 @@ ENTRY(startup_32)
4751         movl %eax,%gs
4752  2:
4753  
4754 +       movl $pa(cpu_gdt_table),%edi
4755 +       movl $__per_cpu_start,%eax
4756 +       movw %ax,__KERNEL_PERCPU + 2(%edi)
4757 +       rorl $16,%eax
4758 +       movb %al,__KERNEL_PERCPU + 4(%edi)
4759 +       movb %ah,__KERNEL_PERCPU + 7(%edi)
4760 +       movl $__per_cpu_end + PERCPU_MODULE_RESERVE - 1,%eax
4761 +       subl $__per_cpu_start,%eax
4762 +       movw %ax,__KERNEL_PERCPU + 0(%edi)
4763 +
4764 +#ifdef CONFIG_PAX_MEMORY_UDEREF
4765 +       /* check for VMware */
4766 +       movl $0x564d5868,%eax
4767 +       xorl %ebx,%ebx
4768 +       movl $0xa,%ecx
4769 +       movl $0x5658,%edx
4770 +       in (%dx),%eax
4771 +       cmpl $0x564d5868,%ebx
4772 +       jz 2f
4773 +
4774 +       movl $NR_CPUS,%ecx
4775 +       movl $pa(cpu_gdt_table),%edi
4776 +1:
4777 +       movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),GDT_ENTRY_KERNEL_DS * 8 + 4(%edi)
4778 +       addl $PAGE_SIZE_asm,%edi
4779 +       loop 1b
4780 +2:
4781 +#endif
4782 +
4783 +#ifdef CONFIG_PAX_KERNEXEC
4784 +       movl $pa(boot_gdt),%edi
4785 +       movl $KERNEL_TEXT_OFFSET,%eax
4786 +       movw %ax,__BOOT_CS + 2(%edi)
4787 +       rorl $16,%eax
4788 +       movb %al,__BOOT_CS + 4(%edi)
4789 +       movb %ah,__BOOT_CS + 7(%edi)
4790 +       rorl $16,%eax
4791 +
4792 +       movl $NR_CPUS,%ecx
4793 +       movl $pa(cpu_gdt_table),%edi
4794 +1:
4795 +       movw %ax,__KERNEL_CS + 2(%edi)
4796 +       rorl $16,%eax
4797 +       movb %al,__KERNEL_CS + 4(%edi)
4798 +       movb %ah,__KERNEL_CS + 7(%edi)
4799 +       rorl $16,%eax
4800 +       addl $PAGE_SIZE_asm,%edi
4801 +       loop 1b
4802 +#endif
4803 +
4804  /*
4805   * Clear BSS first so that there are no surprises...
4806   */
4807 @@ -142,9 +204,7 @@ ENTRY(startup_32)
4808         cmpl $num_subarch_entries, %eax
4809         jae bad_subarch
4810  
4811 -       movl pa(subarch_entries)(,%eax,4), %eax
4812 -       subl $__PAGE_OFFSET, %eax
4813 -       jmp *%eax
4814 +       jmp *pa(subarch_entries)(,%eax,4)
4815  
4816  bad_subarch:
4817  WEAK(lguest_entry)
4818 @@ -156,9 +216,9 @@ WEAK(xen_entry)
4819         __INITDATA
4820  
4821  subarch_entries:
4822 -       .long default_entry             /* normal x86/PC */
4823 -       .long lguest_entry              /* lguest hypervisor */
4824 -       .long xen_entry                 /* Xen hypervisor */
4825 +       .long pa(default_entry)         /* normal x86/PC */
4826 +       .long pa(lguest_entry)          /* lguest hypervisor */
4827 +       .long pa(xen_entry)             /* Xen hypervisor */
4828  num_subarch_entries = (. - subarch_entries) / 4
4829  .previous
4830  #endif /* CONFIG_PARAVIRT */
4831 @@ -172,7 +232,7 @@ num_subarch_entries = (. - subarch_entri
4832   *
4833   * Note that the stack is not yet set up!
4834   */
4835 -#define PTE_ATTR       0x007           /* PRESENT+RW+USER */
4836 +#define PTE_ATTR       0x067           /* PRESENT+RW+USER+DIRTY+ACCESSED */
4837  #define PDE_ATTR       0x067           /* PRESENT+RW+USER+DIRTY+ACCESSED */
4838  #define PGD_ATTR       0x001           /* PRESENT (no other attributes) */
4839  
4840 @@ -224,8 +284,7 @@ default_entry:
4841         movl %eax, pa(max_pfn_mapped)
4842  
4843         /* Do early initialization of the fixmap area */
4844 -       movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4845 -       movl %eax,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4846 +       movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_pmd+0x1000*KPMDS-8)
4847  #else  /* Not PAE */
4848  
4849  page_pde_offset = (__PAGE_OFFSET >> 20);
4850 @@ -257,8 +316,7 @@ page_pde_offset = (__PAGE_OFFSET >> 20);
4851         movl %eax, pa(max_pfn_mapped)
4852  
4853         /* Do early initialization of the fixmap area */
4854 -       movl $pa(swapper_pg_fixmap)+PDE_ATTR,%eax
4855 -       movl %eax,pa(swapper_pg_dir+0xffc)
4856 +       movl $pa(swapper_pg_fixmap)+PDE_ATTR,pa(swapper_pg_dir+0xffc)
4857  #endif
4858         jmp 3f
4859  /*
4860 @@ -322,13 +380,16 @@ ENTRY(startup_32_smp)
4861         jnc 6f
4862  
4863         /* Setup EFER (Extended Feature Enable Register) */
4864 -       movl $0xc0000080, %ecx
4865 +       movl $MSR_EFER, %ecx
4866         rdmsr
4867  
4868         btsl $11, %eax
4869         /* Make changes effective */
4870         wrmsr
4871  
4872 +       btsl $63-32,pa(__supported_pte_mask+4)
4873 +       movl $1,pa(nx_enabled)
4874 +
4875  6:
4876  
4877  /*
4878 @@ -354,9 +415,7 @@ ENTRY(startup_32_smp)
4879  
4880  #ifdef CONFIG_SMP
4881         cmpb $0, ready
4882 -       jz  1f                          /* Initial CPU cleans BSS */
4883 -       jmp checkCPUtype
4884 -1:
4885 +       jnz checkCPUtype                /* Initial CPU cleans BSS */
4886  #endif /* CONFIG_SMP */
4887  
4888  /*
4889 @@ -433,12 +492,12 @@ is386:    movl $2,%ecx            # set MP
4890         ljmp $(__KERNEL_CS),$1f
4891  1:     movl $(__KERNEL_DS),%eax        # reload all the segment registers
4892         movl %eax,%ss                   # after changing gdt.
4893 -       movl %eax,%fs                   # gets reset once there's real percpu
4894 -
4895 -       movl $(__USER_DS),%eax          # DS/ES contains default USER segment
4896         movl %eax,%ds
4897         movl %eax,%es
4898  
4899 +       movl $(__KERNEL_PERCPU), %eax
4900 +       movl %eax,%fs                   # set this cpu's percpu
4901 +
4902         xorl %eax,%eax                  # Clear GS and LDT
4903         movl %eax,%gs
4904         lldt %ax
4905 @@ -448,12 +507,6 @@ is386:     movl $2,%ecx            # set MP
4906  #ifdef CONFIG_SMP
4907         movb ready, %cl
4908         movb $1, ready
4909 -       cmpb $0,%cl             # the first CPU calls start_kernel
4910 -       je   1f
4911 -       movl $(__KERNEL_PERCPU), %eax
4912 -       movl %eax,%fs           # set this cpu's percpu
4913 -       movl (stack_start), %esp
4914 -1:
4915  #endif /* CONFIG_SMP */
4916         jmp *(initial_code)
4917  
4918 @@ -539,15 +592,15 @@ early_page_fault:
4919         jmp early_fault
4920  
4921  early_fault:
4922 -       cld
4923  #ifdef CONFIG_PRINTK
4924 +       cmpl $2,%ss:early_recursion_flag
4925 +       je hlt_loop
4926 +       incl %ss:early_recursion_flag
4927 +       cld
4928         pusha
4929         movl $(__KERNEL_DS),%eax
4930         movl %eax,%ds
4931         movl %eax,%es
4932 -       cmpl $2,early_recursion_flag
4933 -       je hlt_loop
4934 -       incl early_recursion_flag
4935         movl %cr2,%eax
4936         pushl %eax
4937         pushl %edx              /* trapno */
4938 @@ -557,8 +610,8 @@ early_fault:
4939  #else
4940         call printk
4941  #endif
4942 -#endif
4943         call dump_stack
4944 +#endif
4945  hlt_loop:
4946         hlt
4947         jmp hlt_loop
4948 @@ -566,8 +619,11 @@ hlt_loop:
4949  /* This is the default interrupt "handler" :-) */
4950         ALIGN
4951  ignore_int:
4952 -       cld
4953  #ifdef CONFIG_PRINTK
4954 +       cmpl $2,%ss:early_recursion_flag
4955 +       je hlt_loop
4956 +       incl %ss:early_recursion_flag
4957 +       cld
4958         pushl %eax
4959         pushl %ecx
4960         pushl %edx
4961 @@ -576,9 +632,6 @@ ignore_int:
4962         movl $(__KERNEL_DS),%eax
4963         movl %eax,%ds
4964         movl %eax,%es
4965 -       cmpl $2,early_recursion_flag
4966 -       je hlt_loop
4967 -       incl early_recursion_flag
4968         pushl 16(%esp)
4969         pushl 24(%esp)
4970         pushl 32(%esp)
4971 @@ -603,36 +656,41 @@ ignore_int:
4972  ENTRY(initial_code)
4973         .long i386_start_kernel
4974  
4975 -.section .text
4976 -/*
4977 - * Real beginning of normal "text" segment
4978 - */
4979 -ENTRY(stext)
4980 -ENTRY(_stext)
4981 -
4982  /*
4983   * BSS section
4984   */
4985 -.section ".bss.page_aligned","wa"
4986 -       .align PAGE_SIZE_asm
4987  #ifdef CONFIG_X86_PAE
4988 +.section .swapper_pg_pmd,"a",@progbits
4989  swapper_pg_pmd:
4990         .fill 1024*KPMDS,4,0
4991  #else
4992 +.section .swapper_pg_dir,"a",@progbits
4993  ENTRY(swapper_pg_dir)
4994         .fill 1024,4,0
4995  #endif
4996  swapper_pg_fixmap:
4997         .fill 1024,4,0
4998 +
4999 +.section .empty_zero_page,"a",@progbits
5000  ENTRY(empty_zero_page)
5001         .fill 4096,1,0
5002 +
5003 +/*
5004 + * The IDT has to be page-aligned to simplify the Pentium
5005 + * F0 0F bug workaround.. We have a special link segment
5006 + * for this.
5007 + */
5008 +.section .idt,"a",@progbits
5009 +ENTRY(idt_table)
5010 +       .fill 256,8,0
5011 +
5012  /*
5013   * This starts the data section.
5014   */
5015 +.data
5016 +
5017  #ifdef CONFIG_X86_PAE
5018 -.section ".data.page_aligned","wa"
5019 -       /* Page-aligned for the benefit of paravirt? */
5020 -       .align PAGE_SIZE_asm
5021 +.section .swapper_pg_dir,"a",@progbits
5022  ENTRY(swapper_pg_dir)
5023         .long   pa(swapper_pg_pmd+PGD_ATTR),0           /* low identity map */
5024  # if KPMDS == 3
5025 @@ -655,11 +713,12 @@ ENTRY(swapper_pg_dir)
5026  
5027  .data
5028  ENTRY(stack_start)
5029 -       .long init_thread_union+THREAD_SIZE
5030 +       .long init_thread_union+THREAD_SIZE-8
5031         .long __BOOT_DS
5032  
5033  ready: .byte 0
5034  
5035 +.section .rodata,"a",@progbits
5036  early_recursion_flag:
5037         .long 0
5038  
5039 @@ -695,7 +754,7 @@ fault_msg:
5040         .word 0                         # 32 bit align gdt_desc.address
5041  boot_gdt_descr:
5042         .word __BOOT_DS+7
5043 -       .long boot_gdt - __PAGE_OFFSET
5044 +       .long pa(boot_gdt)
5045  
5046         .word 0                         # 32-bit align idt_desc.address
5047  idt_descr:
5048 @@ -706,7 +765,7 @@ idt_descr:
5049         .word 0                         # 32 bit align gdt_desc.address
5050  ENTRY(early_gdt_descr)
5051         .word GDT_ENTRIES*8-1
5052 -       .long per_cpu__gdt_page         /* Overwritten for secondary CPUs */
5053 +       .long cpu_gdt_table             /* Overwritten for secondary CPUs */
5054  
5055  /*
5056   * The boot_gdt must mirror the equivalent in setup.S and is
5057 @@ -715,5 +774,59 @@ ENTRY(early_gdt_descr)
5058         .align L1_CACHE_BYTES
5059  ENTRY(boot_gdt)
5060         .fill GDT_ENTRY_BOOT_CS,8,0
5061 -       .quad 0x00cf9a000000ffff        /* kernel 4GB code at 0x00000000 */
5062 -       .quad 0x00cf92000000ffff        /* kernel 4GB data at 0x00000000 */
5063 +       .quad 0x00cf9b000000ffff        /* kernel 4GB code at 0x00000000 */
5064 +       .quad 0x00cf93000000ffff        /* kernel 4GB data at 0x00000000 */
5065 +
5066 +       .align PAGE_SIZE_asm
5067 +ENTRY(cpu_gdt_table)
5068 +       .rept NR_CPUS
5069 +       .quad 0x0000000000000000        /* NULL descriptor */
5070 +       .quad 0x0000000000000000        /* 0x0b reserved */
5071 +       .quad 0x0000000000000000        /* 0x13 reserved */
5072 +       .quad 0x0000000000000000        /* 0x1b reserved */
5073 +       .quad 0x0000000000000000        /* 0x20 unused */
5074 +       .quad 0x0000000000000000        /* 0x28 unused */
5075 +       .quad 0x0000000000000000        /* 0x33 TLS entry 1 */
5076 +       .quad 0x0000000000000000        /* 0x3b TLS entry 2 */
5077 +       .quad 0x0000000000000000        /* 0x43 TLS entry 3 */
5078 +       .quad 0x0000000000000000        /* 0x4b reserved */
5079 +       .quad 0x0000000000000000        /* 0x53 reserved */
5080 +       .quad 0x0000000000000000        /* 0x5b reserved */
5081 +
5082 +       .quad 0x00cf9b000000ffff        /* 0x60 kernel 4GB code at 0x00000000 */
5083 +       .quad 0x00cf93000000ffff        /* 0x68 kernel 4GB data at 0x00000000 */
5084 +       .quad 0x00cffb000000ffff        /* 0x73 user 4GB code at 0x00000000 */
5085 +       .quad 0x00cff3000000ffff        /* 0x7b user 4GB data at 0x00000000 */
5086 +
5087 +       .quad 0x0000000000000000        /* 0x80 TSS descriptor */
5088 +       .quad 0x0000000000000000        /* 0x88 LDT descriptor */
5089 +
5090 +       /*
5091 +        * Segments used for calling PnP BIOS have byte granularity.
5092 +        * The code segments and data segments have fixed 64k limits,
5093 +        * the transfer segment sizes are set at run time.
5094 +        */
5095 +       .quad 0x00409b000000ffff        /* 0x90 32-bit code */
5096 +       .quad 0x00009b000000ffff        /* 0x98 16-bit code */
5097 +       .quad 0x000093000000ffff        /* 0xa0 16-bit data */
5098 +       .quad 0x0000930000000000        /* 0xa8 16-bit data */
5099 +       .quad 0x0000930000000000        /* 0xb0 16-bit data */
5100 +
5101 +       /*
5102 +        * The APM segments have byte granularity and their bases
5103 +        * are set at run time.  All have 64k limits.
5104 +        */
5105 +       .quad 0x00409b000000ffff        /* 0xb8 APM CS    code */
5106 +       .quad 0x00009b000000ffff        /* 0xc0 APM CS 16 code (16 bit) */
5107 +       .quad 0x004093000000ffff        /* 0xc8 APM DS    data */
5108 +
5109 +       .quad 0x00c0930000000000        /* 0xd0 - ESPFIX SS */
5110 +       .quad 0x0040930000000000        /* 0xd8 - PERCPU */
5111 +       .quad 0x0000000000000000        /* 0xe0 - PCIBIOS_CS */
5112 +       .quad 0x0000000000000000        /* 0xe8 - PCIBIOS_DS */
5113 +       .quad 0x0000000000000000        /* 0xf0 - unused */
5114 +       .quad 0x0000000000000000        /* 0xf8 - GDT entry 31: double-fault TSS */
5115 +
5116 +       /* Be sure this is zeroed to avoid false validations in Xen */
5117 +       .fill PAGE_SIZE_asm - GDT_SIZE,1,0
5118 +       .endr
5119 diff -urNp linux-2.6.27.10/arch/x86/kernel/head64.c linux-2.6.27.10/arch/x86/kernel/head64.c
5120 --- linux-2.6.27.10/arch/x86/kernel/head64.c    2008-11-07 12:55:34.000000000 -0500
5121 +++ linux-2.6.27.10/arch/x86/kernel/head64.c    2008-11-18 03:38:44.000000000 -0500
5122 @@ -93,6 +93,8 @@ void __init x86_64_start_kernel(char * r
5123         /* clear bss before set_intr_gate with early_idt_handler */
5124         clear_bss();
5125  
5126 +       x86_64_init_pda();
5127 +
5128         /* Make NULL pointers segfault */
5129         zap_identity_mappings();
5130  
5131 @@ -110,8 +112,6 @@ void __init x86_64_start_kernel(char * r
5132  
5133         early_printk("Kernel alive\n");
5134  
5135 -       x86_64_init_pda();
5136 -
5137         early_printk("Kernel really alive\n");
5138  
5139         x86_64_start_reservations(real_mode_data);
5140 diff -urNp linux-2.6.27.10/arch/x86/kernel/head_64.S linux-2.6.27.10/arch/x86/kernel/head_64.S
5141 --- linux-2.6.27.10/arch/x86/kernel/head_64.S   2008-11-07 12:55:34.000000000 -0500
5142 +++ linux-2.6.27.10/arch/x86/kernel/head_64.S   2008-11-18 03:38:44.000000000 -0500
5143 @@ -38,6 +38,10 @@ L4_PAGE_OFFSET = pgd_index(__PAGE_OFFSET
5144  L3_PAGE_OFFSET = pud_index(__PAGE_OFFSET)
5145  L4_START_KERNEL = pgd_index(__START_KERNEL_map)
5146  L3_START_KERNEL = pud_index(__START_KERNEL_map)
5147 +L4_VMALLOC_START = pgd_index(VMALLOC_START)
5148 +L3_VMALLOC_START = pud_index(VMALLOC_START)
5149 +L4_VMEMMAP_START = pgd_index(VMEMMAP_START)
5150 +L3_VMEMMAP_START = pud_index(VMEMMAP_START)
5151  
5152         .text
5153         .section .text.head
5154 @@ -85,14 +89,17 @@ startup_64:
5155          */
5156         addq    %rbp, init_level4_pgt + 0(%rip)
5157         addq    %rbp, init_level4_pgt + (L4_PAGE_OFFSET*8)(%rip)
5158 +       addq    %rbp, init_level4_pgt + (L4_VMALLOC_START*8)(%rip)
5159 +       addq    %rbp, init_level4_pgt + (L4_VMEMMAP_START*8)(%rip)
5160         addq    %rbp, init_level4_pgt + (L4_START_KERNEL*8)(%rip)
5161  
5162         addq    %rbp, level3_ident_pgt + 0(%rip)
5163  
5164 -       addq    %rbp, level3_kernel_pgt + (510*8)(%rip)
5165 -       addq    %rbp, level3_kernel_pgt + (511*8)(%rip)
5166 +       addq    %rbp, level3_kernel_pgt + (L3_START_KERNEL*8)(%rip)
5167 +       addq    %rbp, level3_kernel_pgt + (L3_START_KERNEL*8+8)(%rip)
5168  
5169         addq    %rbp, level2_fixmap_pgt + (506*8)(%rip)
5170 +       addq    %rbp, level2_fixmap_pgt + (507*8)(%rip)
5171  
5172         /* Add an Identity mapping if I am above 1G */
5173         leaq    _text(%rip), %rdi
5174 @@ -187,6 +194,10 @@ ENTRY(secondary_startup_64)
5175         btl     $20,%edi                /* No Execute supported? */
5176         jnc     1f
5177         btsl    $_EFER_NX, %eax
5178 +       leaq    init_level4_pgt(%rip), %rdi
5179 +       btsq    $_PAGE_BIT_NX, 8*L4_PAGE_OFFSET(%rdi)
5180 +       btsq    $_PAGE_BIT_NX, 8*L4_VMALLOC_START(%rdi)
5181 +       btsq    $_PAGE_BIT_NX, 8*L4_VMEMMAP_START(%rdi)
5182  1:     wrmsr                           /* Make changes effective */
5183  
5184         /* Setup cr0 */
5185 @@ -257,16 +268,16 @@ ENTRY(secondary_startup_64)
5186         .align  8
5187         ENTRY(initial_code)
5188         .quad   x86_64_start_kernel
5189 -       __FINITDATA
5190  
5191         ENTRY(stack_start)
5192         .quad  init_thread_union+THREAD_SIZE-8
5193         .word  0
5194 +       __FINITDATA
5195  
5196  bad_address:
5197         jmp bad_address
5198  
5199 -       .section ".init.text","ax"
5200 +       __INIT
5201  #ifdef CONFIG_EARLY_PRINTK
5202         .globl early_idt_handlers
5203  early_idt_handlers:
5204 @@ -311,18 +322,23 @@ ENTRY(early_idt_handler)
5205  #endif /* EARLY_PRINTK */
5206  1:     hlt
5207         jmp 1b
5208 +       .previous
5209  
5210  #ifdef CONFIG_EARLY_PRINTK
5211 +       __INITDATA
5212  early_recursion_flag:
5213         .long 0
5214 +       .previous
5215  
5216 +       .section .rodata,"a",@progbits
5217  early_idt_msg:
5218         .asciz "PANIC: early exception %02lx rip %lx:%lx error %lx cr2 %lx\n"
5219  early_idt_ripmsg:
5220         .asciz "RIP %s\n"
5221 -#endif /* CONFIG_EARLY_PRINTK */
5222         .previous
5223 +#endif /* CONFIG_EARLY_PRINTK */
5224  
5225 +       .section .rodata,"a",@progbits
5226  .balign PAGE_SIZE
5227  
5228  #define NEXT_PAGE(name) \
5229 @@ -347,6 +363,10 @@ NEXT_PAGE(init_level4_pgt)
5230         .quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5231         .org    init_level4_pgt + L4_PAGE_OFFSET*8, 0
5232         .quad   level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5233 +       .org    init_level4_pgt + L4_VMALLOC_START*8, 0
5234 +       .quad   level3_vmalloc_pgt - __START_KERNEL_map + _KERNPG_TABLE
5235 +       .org    init_level4_pgt + L4_VMEMMAP_START*8, 0
5236 +       .quad   level3_vmemmap_pgt - __START_KERNEL_map + _KERNPG_TABLE
5237         .org    init_level4_pgt + L4_START_KERNEL*8, 0
5238         /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */
5239         .quad   level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE
5240 @@ -355,6 +375,12 @@ NEXT_PAGE(level3_ident_pgt)
5241         .quad   level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE
5242         .fill   511,8,0
5243  
5244 +NEXT_PAGE(level3_vmalloc_pgt)
5245 +       .fill   512,8,0
5246 +
5247 +NEXT_PAGE(level3_vmemmap_pgt)
5248 +       .fill   512,8,0
5249 +
5250  NEXT_PAGE(level3_kernel_pgt)
5251         .fill   L3_START_KERNEL,8,0
5252         /* (2^48-(2*1024*1024*1024)-((2^39)*511))/(2^30) = 510 */
5253 @@ -364,12 +390,16 @@ NEXT_PAGE(level3_kernel_pgt)
5254  NEXT_PAGE(level2_fixmap_pgt)
5255         .fill   506,8,0
5256         .quad   level1_fixmap_pgt - __START_KERNEL_map + _PAGE_TABLE
5257 -       /* 8MB reserved for vsyscalls + a 2MB hole = 4 + 1 entries */
5258 -       .fill   5,8,0
5259 +       .quad   level1_vsyscall_pgt - __START_KERNEL_map + _PAGE_TABLE
5260 +       /* 6MB reserved for vsyscalls + a 2MB hole = 3 + 1 entries */
5261 +       .fill   4,8,0
5262  
5263  NEXT_PAGE(level1_fixmap_pgt)
5264         .fill   512,8,0
5265  
5266 +NEXT_PAGE(level1_vsyscall_pgt)
5267 +       .fill   512,8,0
5268 +
5269  NEXT_PAGE(level2_ident_pgt)
5270         /* Since I easily can, map the first 1G.
5271          * Don't set NX because code runs from these pages.
5272 @@ -396,19 +426,39 @@ NEXT_PAGE(level2_spare_pgt)
5273  #undef PMDS
5274  #undef NEXT_PAGE
5275  
5276 -       .data
5277 +       .align PAGE_SIZE
5278 +ENTRY(cpu_gdt_table)
5279 +       .rept NR_CPUS
5280 +       .quad   0x0000000000000000      /* NULL descriptor */
5281 +       .quad   0x00cf9b000000ffff      /* __KERNEL32_CS */
5282 +       .quad   0x00af9b000000ffff      /* __KERNEL_CS */
5283 +       .quad   0x00cf93000000ffff      /* __KERNEL_DS */
5284 +       .quad   0x00cffb000000ffff      /* __USER32_CS */
5285 +       .quad   0x00cff3000000ffff      /* __USER_DS, __USER32_DS  */
5286 +       .quad   0x00affb000000ffff      /* __USER_CS */
5287 +       .quad   0x0                     /* unused */
5288 +       .quad   0,0                     /* TSS */
5289 +       .quad   0,0                     /* LDT */
5290 +       .quad   0,0,0                   /* three TLS descriptors */
5291 +       .quad   0x0000f40000000000      /* node/CPU stored in limit */
5292 +       /* asm/segment.h:GDT_ENTRIES must match this */
5293 +
5294 +       /* zero the remaining page */
5295 +       .fill PAGE_SIZE / 8 - GDT_ENTRIES,8,0
5296 +       .endr
5297 +
5298         .align 16
5299         .globl early_gdt_descr
5300  early_gdt_descr:
5301         .word   GDT_ENTRIES*8-1
5302 -       .quad   per_cpu__gdt_page
5303 +       .quad   cpu_gdt_table
5304  
5305  ENTRY(phys_base)
5306         /* This must match the first entry in level2_kernel_pgt */
5307         .quad   0x0000000000000000
5308  
5309  #include "../../x86/xen/xen-head.S"
5310 -       
5311 +
5312         .section .bss, "aw", @nobits
5313         .align L1_CACHE_BYTES
5314  ENTRY(idt_table)
5315 diff -urNp linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c
5316 --- linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c     2008-11-07 12:55:34.000000000 -0500
5317 +++ linux-2.6.27.10/arch/x86/kernel/i386_ksyms_32.c     2008-11-18 03:38:44.000000000 -0500
5318 @@ -10,8 +10,12 @@
5319  EXPORT_SYMBOL(mcount);
5320  #endif
5321  
5322 +EXPORT_SYMBOL_GPL(cpu_gdt_table);
5323 +
5324  /* Networking helper routines. */
5325  EXPORT_SYMBOL(csum_partial_copy_generic);
5326 +EXPORT_SYMBOL(csum_partial_copy_generic_to_user);
5327 +EXPORT_SYMBOL(csum_partial_copy_generic_from_user);
5328  
5329  EXPORT_SYMBOL(__get_user_1);
5330  EXPORT_SYMBOL(__get_user_2);
5331 @@ -26,3 +30,7 @@ EXPORT_SYMBOL(strstr);
5332  
5333  EXPORT_SYMBOL(csum_partial);
5334  EXPORT_SYMBOL(empty_zero_page);
5335 +
5336 +#ifdef CONFIG_PAX_KERNEXEC
5337 +EXPORT_SYMBOL(KERNEL_TEXT_OFFSET);
5338 +#endif
5339 diff -urNp linux-2.6.27.10/arch/x86/kernel/init_task.c linux-2.6.27.10/arch/x86/kernel/init_task.c
5340 --- linux-2.6.27.10/arch/x86/kernel/init_task.c 2008-11-07 12:55:34.000000000 -0500
5341 +++ linux-2.6.27.10/arch/x86/kernel/init_task.c 2008-11-18 03:38:44.000000000 -0500
5342 @@ -42,5 +42,5 @@ EXPORT_SYMBOL(init_task);
5343   * section. Since TSS's are completely CPU-local, we want them
5344   * on exact cacheline boundaries, to eliminate cacheline ping-pong.
5345   */
5346 -DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, init_tss) = INIT_TSS;
5347 -
5348 +struct tss_struct init_tss[NR_CPUS] ____cacheline_internodealigned_in_smp = { [0 ... NR_CPUS-1] = INIT_TSS };
5349 +EXPORT_SYMBOL(init_tss);
5350 diff -urNp linux-2.6.27.10/arch/x86/kernel/ioport.c linux-2.6.27.10/arch/x86/kernel/ioport.c
5351 --- linux-2.6.27.10/arch/x86/kernel/ioport.c    2008-11-07 12:55:34.000000000 -0500
5352 +++ linux-2.6.27.10/arch/x86/kernel/ioport.c    2008-11-18 03:38:44.000000000 -0500
5353 @@ -14,6 +14,7 @@
5354  #include <linux/slab.h>
5355  #include <linux/thread_info.h>
5356  #include <linux/syscalls.h>
5357 +#include <linux/grsecurity.h>
5358  
5359  /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */
5360  static void set_bitmap(unsigned long *bitmap, unsigned int base,
5361 @@ -40,6 +41,12 @@ asmlinkage long sys_ioperm(unsigned long
5362  
5363         if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
5364                 return -EINVAL;
5365 +#ifdef CONFIG_GRKERNSEC_IO
5366 +       if (turn_on) {
5367 +               gr_handle_ioperm();
5368 +               return -EPERM;
5369 +       }
5370 +#endif
5371         if (turn_on && !capable(CAP_SYS_RAWIO))
5372                 return -EPERM;
5373  
5374 @@ -66,7 +73,7 @@ asmlinkage long sys_ioperm(unsigned long
5375          * because the ->io_bitmap_max value must match the bitmap
5376          * contents:
5377          */
5378 -       tss = &per_cpu(init_tss, get_cpu());
5379 +       tss = init_tss + get_cpu();
5380  
5381         set_bitmap(t->io_bitmap_ptr, from, num, !turn_on);
5382  
5383 @@ -121,8 +128,13 @@ static int do_iopl(unsigned int level, s
5384                 return -EINVAL;
5385         /* Trying to gain more privileges? */
5386         if (level > old) {
5387 +#ifdef CONFIG_GRKERNSEC_IO
5388 +               gr_handle_iopl();
5389 +               return -EPERM;
5390 +#else
5391                 if (!capable(CAP_SYS_RAWIO))
5392                         return -EPERM;
5393 +#endif
5394         }
5395         regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
5396  
5397 diff -urNp linux-2.6.27.10/arch/x86/kernel/irq_32.c linux-2.6.27.10/arch/x86/kernel/irq_32.c
5398 --- linux-2.6.27.10/arch/x86/kernel/irq_32.c    2008-11-07 12:55:34.000000000 -0500
5399 +++ linux-2.6.27.10/arch/x86/kernel/irq_32.c    2008-11-18 03:38:44.000000000 -0500
5400 @@ -116,7 +116,7 @@ execute_on_irq_stack(int overflow, struc
5401                 return 0;
5402  
5403         /* build the stack frame on the IRQ stack */
5404 -       isp = (u32 *) ((char*)irqctx + sizeof(*irqctx));
5405 +       isp = (u32 *) ((char*)irqctx + sizeof(*irqctx) - 8);
5406         irqctx->tinfo.task = curctx->tinfo.task;
5407         irqctx->tinfo.previous_esp = current_stack_pointer;
5408  
5409 @@ -197,7 +197,7 @@ asmlinkage void do_softirq(void)
5410                 irqctx->tinfo.previous_esp = current_stack_pointer;
5411  
5412                 /* build the stack frame on the softirq stack */
5413 -               isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
5414 +               isp = (u32*) ((char*)irqctx + sizeof(*irqctx) - 8);
5415  
5416                 call_on_stack(__do_softirq, isp);
5417                 /*
5418 diff -urNp linux-2.6.27.10/arch/x86/kernel/kprobes.c linux-2.6.27.10/arch/x86/kernel/kprobes.c
5419 --- linux-2.6.27.10/arch/x86/kernel/kprobes.c   2008-11-07 12:55:34.000000000 -0500
5420 +++ linux-2.6.27.10/arch/x86/kernel/kprobes.c   2008-11-18 04:48:35.000000000 -0500
5421 @@ -166,9 +166,24 @@ static void __kprobes set_jmp_op(void *f
5422                 char op;
5423                 s32 raddr;
5424         } __attribute__((packed)) * jop;
5425 -       jop = (struct __arch_jmp_op *)from;
5426 +
5427 +#ifdef CONFIG_PAX_KERNEXEC
5428 +       unsigned long cr0;
5429 +#endif
5430 +
5431 +       jop = (struct __arch_jmp_op *)(ktla_ktva(from));
5432 +
5433 +#ifdef CONFIG_PAX_KERNEXEC
5434 +       pax_open_kernel(cr0);
5435 +#endif
5436 +
5437         jop->raddr = (s32)((long)(to) - ((long)(from) + 5));
5438         jop->op = RELATIVEJUMP_INSTRUCTION;
5439 +
5440 +#ifdef CONFIG_PAX_KERNEXEC
5441 +       pax_close_kernel(cr0);
5442 +#endif
5443 +
5444  }
5445  
5446  /*
5447 @@ -342,16 +357,29 @@ static void __kprobes fix_riprel(struct 
5448  
5449  static void __kprobes arch_copy_kprobe(struct kprobe *p)
5450  {
5451 -       memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5452 +
5453 +#ifdef CONFIG_PAX_KERNEXEC
5454 +       unsigned long cr0;
5455 +#endif
5456 +
5457 +#ifdef CONFIG_PAX_KERNEXEC
5458 +       pax_open_kernel(cr0);
5459 +#endif
5460 +
5461 +       memcpy(p->ainsn.insn, ktla_ktva(p->addr), MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
5462 +
5463 +#ifdef CONFIG_PAX_KERNEXEC
5464 +       pax_close_kernel(cr0);
5465 +#endif
5466  
5467         fix_riprel(p);
5468  
5469 -       if (can_boost(p->addr))
5470 +       if (can_boost(ktla_ktva(p->addr)))
5471                 p->ainsn.boostable = 0;
5472         else
5473                 p->ainsn.boostable = -1;
5474  
5475 -       p->opcode = *p->addr;
5476 +       p->opcode = *(ktla_ktva(p->addr));
5477  }
5478  
5479  int __kprobes arch_prepare_kprobe(struct kprobe *p)
5480 @@ -428,7 +456,7 @@ static void __kprobes prepare_singlestep
5481         if (p->opcode == BREAKPOINT_INSTRUCTION)
5482                 regs->ip = (unsigned long)p->addr;
5483         else
5484 -               regs->ip = (unsigned long)p->ainsn.insn;
5485 +               regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5486  }
5487  
5488  void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
5489 @@ -449,7 +477,7 @@ static void __kprobes setup_singlestep(s
5490         if (p->ainsn.boostable == 1 && !p->post_handler) {
5491                 /* Boost up -- we can execute copied instructions directly */
5492                 reset_current_kprobe();
5493 -               regs->ip = (unsigned long)p->ainsn.insn;
5494 +               regs->ip = ktva_ktla((unsigned long)p->ainsn.insn);
5495                 preempt_enable_no_resched();
5496                 return;
5497         }
5498 @@ -519,7 +547,7 @@ static int __kprobes kprobe_handler(stru
5499         struct kprobe_ctlblk *kcb;
5500  
5501         addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
5502 -       if (*addr != BREAKPOINT_INSTRUCTION) {
5503 +       if (*(kprobe_opcode_t *)ktla_ktva((unsigned long)addr) != BREAKPOINT_INSTRUCTION) {
5504                 /*
5505                  * The breakpoint instruction was removed right
5506                  * after we hit it.  Another cpu has removed
5507 @@ -770,7 +798,7 @@ static void __kprobes resume_execution(s
5508                 struct pt_regs *regs, struct kprobe_ctlblk *kcb)
5509  {
5510         unsigned long *tos = stack_addr(regs);
5511 -       unsigned long copy_ip = (unsigned long)p->ainsn.insn;
5512 +       unsigned long copy_ip = ktva_ktla((unsigned long)p->ainsn.insn);
5513         unsigned long orig_ip = (unsigned long)p->addr;
5514         kprobe_opcode_t *insn = p->ainsn.insn;
5515  
5516 @@ -953,7 +981,7 @@ int __kprobes kprobe_exceptions_notify(s
5517         struct die_args *args = data;
5518         int ret = NOTIFY_DONE;
5519  
5520 -       if (args->regs && user_mode_vm(args->regs))
5521 +       if (args->regs && user_mode(args->regs))
5522                 return ret;
5523  
5524         switch (val) {
5525 diff -urNp linux-2.6.27.10/arch/x86/kernel/ldt.c linux-2.6.27.10/arch/x86/kernel/ldt.c
5526 --- linux-2.6.27.10/arch/x86/kernel/ldt.c       2008-11-07 12:55:34.000000000 -0500
5527 +++ linux-2.6.27.10/arch/x86/kernel/ldt.c       2008-11-18 03:38:44.000000000 -0500
5528 @@ -63,13 +63,13 @@ static int alloc_ldt(mm_context_t *pc, i
5529         if (reload) {
5530  #ifdef CONFIG_SMP
5531                 preempt_disable();
5532 -               load_LDT(pc);
5533 +               load_LDT_nolock(pc);
5534                 if (!cpus_equal(current->mm->cpu_vm_mask,
5535                                 cpumask_of_cpu(smp_processor_id())))
5536                         smp_call_function(flush_ldt, current->mm, 1);
5537                 preempt_enable();
5538  #else
5539 -               load_LDT(pc);
5540 +               load_LDT_nolock(pc);
5541  #endif
5542         }
5543         if (oldsize) {
5544 @@ -108,6 +108,24 @@ int init_new_context(struct task_struct 
5545                 retval = copy_ldt(&mm->context, &old_mm->context);
5546                 mutex_unlock(&old_mm->context.lock);
5547         }
5548 +
5549 +       if (tsk == current) {
5550 +               mm->context.vdso = ~0UL;
5551 +
5552 +#ifdef CONFIG_X86_32
5553 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
5554 +               mm->context.user_cs_base = 0UL;
5555 +               mm->context.user_cs_limit = ~0UL;
5556 +
5557 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
5558 +               cpus_clear(mm->context.cpu_user_cs_mask);
5559 +#endif
5560 +
5561 +#endif
5562 +#endif
5563 +
5564 +       }
5565 +
5566         return retval;
5567  }
5568  
5569 @@ -221,6 +239,13 @@ static int write_ldt(void __user *ptr, u
5570                 }
5571         }
5572  
5573 +#ifdef CONFIG_PAX_SEGMEXEC
5574 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & MODIFY_LDT_CONTENTS_CODE)) {
5575 +               error = -EINVAL;
5576 +               goto out_unlock;
5577 +       }
5578 +#endif
5579 +
5580         fill_ldt(&ldt, &ldt_info);
5581         if (oldmode)
5582                 ldt.avl = 0;
5583 diff -urNp linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c
5584 --- linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c  2008-11-07 12:55:34.000000000 -0500
5585 +++ linux-2.6.27.10/arch/x86/kernel/machine_kexec_32.c  2008-11-18 03:38:44.000000000 -0500
5586 @@ -34,7 +34,7 @@ static u32 kexec_pmd1[1024] PAGE_ALIGNED
5587  static u32 kexec_pte0[1024] PAGE_ALIGNED;
5588  static u32 kexec_pte1[1024] PAGE_ALIGNED;
5589  
5590 -static void set_idt(void *newidt, __u16 limit)
5591 +static void set_idt(struct desc_struct *newidt, __u16 limit)
5592  {
5593         struct desc_ptr curidt;
5594  
5595 @@ -46,7 +46,7 @@ static void set_idt(void *newidt, __u16 
5596  }
5597  
5598  
5599 -static void set_gdt(void *newgdt, __u16 limit)
5600 +static void set_gdt(struct desc_struct *newgdt, __u16 limit)
5601  {
5602         struct desc_ptr curgdt;
5603  
5604 @@ -145,7 +145,7 @@ void machine_kexec(struct kimage *image)
5605         }
5606  
5607         control_page = page_address(image->control_code_page);
5608 -       memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE);
5609 +       memcpy(control_page, (void *)ktla_ktva((unsigned long)relocate_kernel), KEXEC_CONTROL_CODE_MAX_SIZE);
5610  
5611         relocate_kernel_ptr = control_page;
5612         page_list[PA_CONTROL_PAGE] = __pa(control_page);
5613 diff -urNp linux-2.6.27.10/arch/x86/kernel/module_32.c linux-2.6.27.10/arch/x86/kernel/module_32.c
5614 --- linux-2.6.27.10/arch/x86/kernel/module_32.c 2008-11-07 12:55:34.000000000 -0500
5615 +++ linux-2.6.27.10/arch/x86/kernel/module_32.c 2008-11-18 03:38:44.000000000 -0500
5616 @@ -23,6 +23,9 @@
5617  #include <linux/kernel.h>
5618  #include <linux/bug.h>
5619  
5620 +#include <asm/desc.h>
5621 +#include <asm/pgtable.h>
5622 +
5623  #if 0
5624  #define DEBUGP printk
5625  #else
5626 @@ -33,9 +36,31 @@ void *module_alloc(unsigned long size)
5627  {
5628         if (size == 0)
5629                 return NULL;
5630 +
5631 +#ifdef CONFIG_PAX_KERNEXEC
5632 +       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL);
5633 +#else
5634         return vmalloc_exec(size);
5635 +#endif
5636 +
5637  }
5638  
5639 +#ifdef CONFIG_PAX_KERNEXEC
5640 +void *module_alloc_exec(unsigned long size)
5641 +{
5642 +       struct vm_struct *area;
5643 +
5644 +       if (size == 0)
5645 +               return NULL;
5646 +
5647 +       area = __get_vm_area(size, VM_ALLOC, (unsigned long)&MODULES_VADDR, (unsigned long)&MODULES_END);
5648 +       if (area)
5649 +               return area->addr;
5650 +
5651 +       return NULL;
5652 +}
5653 +EXPORT_SYMBOL(module_alloc_exec);
5654 +#endif
5655  
5656  /* Free memory returned from module_alloc */
5657  void module_free(struct module *mod, void *module_region)
5658 @@ -45,6 +70,45 @@ void module_free(struct module *mod, voi
5659             table entries. */
5660  }
5661  
5662 +#ifdef CONFIG_PAX_KERNEXEC
5663 +void module_free_exec(struct module *mod, void *module_region)
5664 +{
5665 +       struct vm_struct **p, *tmp;
5666 +
5667 +       if (!module_region)
5668 +               return;
5669 +
5670 +       if ((PAGE_SIZE-1) & (unsigned long)module_region) {
5671 +               printk(KERN_ERR "Trying to module_free_exec() bad address (%p)\n", module_region);
5672 +               WARN_ON(1);
5673 +               return;
5674 +       }
5675 +
5676 +       write_lock(&vmlist_lock);
5677 +       for (p = &vmlist; (tmp = *p) != NULL; p = &tmp->next)
5678 +                if (tmp->addr == module_region)
5679 +                       break;
5680 +
5681 +       if (tmp) {
5682 +               unsigned long cr0;
5683 +
5684 +               pax_open_kernel(cr0);
5685 +               memset(tmp->addr, 0xCC, tmp->size);
5686 +               pax_close_kernel(cr0);
5687 +
5688 +               *p = tmp->next;
5689 +               kfree(tmp);
5690 +       }
5691 +       write_unlock(&vmlist_lock);
5692 +
5693 +       if (!tmp) {
5694 +               printk(KERN_ERR "Trying to module_free_exec() nonexistent vm area (%p)\n",
5695 +                               module_region);
5696 +               WARN_ON(1);
5697 +       }
5698 +}
5699 +#endif
5700 +
5701  /* We don't need anything special. */
5702  int module_frob_arch_sections(Elf_Ehdr *hdr,
5703                               Elf_Shdr *sechdrs,
5704 @@ -63,14 +127,20 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5705         unsigned int i;
5706         Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
5707         Elf32_Sym *sym;
5708 -       uint32_t *location;
5709 +       uint32_t *plocation, location;
5710 +
5711 +#ifdef CONFIG_PAX_KERNEXEC
5712 +       unsigned long cr0;
5713 +#endif
5714  
5715         DEBUGP("Applying relocate section %u to %u\n", relsec,
5716                sechdrs[relsec].sh_info);
5717         for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
5718                 /* This is where to make the change */
5719 -               location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
5720 -                       + rel[i].r_offset;
5721 +               plocation = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr + rel[i].r_offset;
5722 +               location = (uint32_t)plocation;
5723 +               if (sechdrs[sechdrs[relsec].sh_info].sh_flags & SHF_EXECINSTR)
5724 +                       plocation = ktla_ktva((void *)plocation);
5725                 /* This is the symbol it is referring to.  Note that all
5726                    undefined symbols have been resolved.  */
5727                 sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
5728 @@ -78,12 +148,32 @@ int apply_relocate(Elf32_Shdr *sechdrs,
5729  
5730                 switch (ELF32_R_TYPE(rel[i].r_info)) {
5731                 case R_386_32:
5732 +
5733 +#ifdef CONFIG_PAX_KERNEXEC
5734 +                       pax_open_kernel(cr0);
5735 +#endif
5736 +
5737                         /* We add the value into the location given */
5738 -                       *location += sym->st_value;
5739 +                       *plocation += sym->st_value;
5740 +
5741 +#ifdef CONFIG_PAX_KERNEXEC
5742 +                       pax_close_kernel(cr0);
5743 +#endif
5744 +
5745                         break;
5746                 case R_386_PC32:
5747 +
5748 +#ifdef CONFIG_PAX_KERNEXEC
5749 +                       pax_open_kernel(cr0);
5750 +#endif
5751 +
5752                         /* Add the value, subtract its postition */
5753 -                       *location += sym->st_value - (uint32_t)location;
5754 +                       *plocation += sym->st_value - location;
5755 +
5756 +#ifdef CONFIG_PAX_KERNEXEC
5757 +                       pax_close_kernel(cr0);
5758 +#endif
5759 +
5760                         break;
5761                 default:
5762                         printk(KERN_ERR "module %s: Unknown relocation: %u\n",
5763 diff -urNp linux-2.6.27.10/arch/x86/kernel/module_64.c linux-2.6.27.10/arch/x86/kernel/module_64.c
5764 --- linux-2.6.27.10/arch/x86/kernel/module_64.c 2008-11-07 12:55:34.000000000 -0500
5765 +++ linux-2.6.27.10/arch/x86/kernel/module_64.c 2008-11-18 03:38:44.000000000 -0500
5766 @@ -40,7 +40,7 @@ void module_free(struct module *mod, voi
5767             table entries. */
5768  }
5769  
5770 -void *module_alloc(unsigned long size)
5771 +static void *__module_alloc(unsigned long size, pgprot_t prot)
5772  {
5773         struct vm_struct *area;
5774  
5775 @@ -54,8 +54,31 @@ void *module_alloc(unsigned long size)
5776         if (!area)
5777                 return NULL;
5778  
5779 -       return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
5780 +       return __vmalloc_area(area, GFP_KERNEL | __GFP_ZERO, prot);
5781 +}
5782 +
5783 +#ifdef CONFIG_PAX_KERNEXEC
5784 +void *module_alloc(unsigned long size)
5785 +{
5786 +       return __module_alloc(size, PAGE_KERNEL);
5787 +}
5788 +
5789 +void module_free_exec(struct module *mod, void *module_region)
5790 +{
5791 +       module_free(mod, module_region);
5792 +}
5793 +
5794 +void *module_alloc_exec(unsigned long size)
5795 +{
5796 +       return __module_alloc(size, PAGE_KERNEL_RX);
5797  }
5798 +#else
5799 +void *module_alloc(unsigned long size)
5800 +{
5801 +       return __module_alloc(size, PAGE_KERNEL_EXEC);
5802 +}
5803 +#endif
5804 +
5805  #endif
5806  
5807  /* We don't need anything special. */
5808 @@ -77,7 +100,11 @@ int apply_relocate_add(Elf64_Shdr *sechd
5809         Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
5810         Elf64_Sym *sym;
5811         void *loc;
5812 -       u64 val; 
5813 +       u64 val;
5814 +
5815 +#ifdef CONFIG_PAX_KERNEXEC
5816 +       unsigned long cr0;
5817 +#endif
5818  
5819         DEBUGP("Applying relocate section %u to %u\n", relsec,
5820                sechdrs[relsec].sh_info);
5821 @@ -101,21 +128,61 @@ int apply_relocate_add(Elf64_Shdr *sechd
5822                 case R_X86_64_NONE:
5823                         break;
5824                 case R_X86_64_64:
5825 +
5826 +#ifdef CONFIG_PAX_KERNEXEC
5827 +                       pax_open_kernel(cr0);
5828 +#endif
5829 +
5830                         *(u64 *)loc = val;
5831 +
5832 +#ifdef CONFIG_PAX_KERNEXEC
5833 +                       pax_close_kernel(cr0);
5834 +#endif
5835 +
5836                         break;
5837                 case R_X86_64_32:
5838 +
5839 +#ifdef CONFIG_PAX_KERNEXEC
5840 +                       pax_open_kernel(cr0);
5841 +#endif
5842 +
5843                         *(u32 *)loc = val;
5844 +
5845 +#ifdef CONFIG_PAX_KERNEXEC
5846 +                       pax_close_kernel(cr0);
5847 +#endif
5848 +
5849                         if (val != *(u32 *)loc)
5850                                 goto overflow;
5851                         break;
5852                 case R_X86_64_32S:
5853 +
5854 +#ifdef CONFIG_PAX_KERNEXEC
5855 +                       pax_open_kernel(cr0);
5856 +#endif
5857 +
5858                         *(s32 *)loc = val;
5859 +
5860 +#ifdef CONFIG_PAX_KERNEXEC
5861 +                       pax_close_kernel(cr0);
5862 +#endif
5863 +
5864                         if ((s64)val != *(s32 *)loc)
5865                                 goto overflow;
5866                         break;
5867                 case R_X86_64_PC32: 
5868                         val -= (u64)loc;
5869 +
5870 +#ifdef CONFIG_PAX_KERNEXEC
5871 +                       pax_open_kernel(cr0);
5872 +#endif
5873 +
5874                         *(u32 *)loc = val;
5875 +
5876 +#ifdef CONFIG_PAX_KERNEXEC
5877 +                       pax_close_kernel(cr0);
5878 +#endif
5879 +
5880  #if 0
5881                         if ((s64)val != *(s32 *)loc)
5882                                 goto overflow; 
5883 diff -urNp linux-2.6.27.10/arch/x86/kernel/paravirt.c linux-2.6.27.10/arch/x86/kernel/paravirt.c
5884 --- linux-2.6.27.10/arch/x86/kernel/paravirt.c  2008-11-07 12:55:34.000000000 -0500
5885 +++ linux-2.6.27.10/arch/x86/kernel/paravirt.c  2008-11-18 03:38:44.000000000 -0500
5886 @@ -44,7 +44,7 @@ void _paravirt_nop(void)
5887  {
5888  }
5889  
5890 -static void __init default_banner(void)
5891 +static void default_banner(void)
5892  {
5893         printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
5894                pv_info.name);
5895 @@ -164,7 +164,7 @@ unsigned paravirt_patch_insns(void *insn
5896         if (insn_len > len || start == NULL)
5897                 insn_len = len;
5898         else
5899 -               memcpy(insnbuf, start, insn_len);
5900 +               memcpy(insnbuf, ktla_ktva(start), insn_len);
5901  
5902         return insn_len;
5903  }
5904 @@ -279,21 +279,21 @@ void __init paravirt_use_bytelocks(void)
5905  #endif
5906  }
5907  
5908 -struct pv_info pv_info = {
5909 +struct pv_info pv_info __read_only = {
5910         .name = "bare hardware",
5911         .paravirt_enabled = 0,
5912         .kernel_rpl = 0,
5913         .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */
5914  };
5915  
5916 -struct pv_init_ops pv_init_ops = {
5917 +struct pv_init_ops pv_init_ops __read_only = {
5918         .patch = native_patch,
5919         .banner = default_banner,
5920         .arch_setup = paravirt_nop,
5921         .memory_setup = machine_specific_memory_setup,
5922  };
5923  
5924 -struct pv_time_ops pv_time_ops = {
5925 +struct pv_time_ops pv_time_ops __read_only = {
5926         .time_init = hpet_time_init,
5927         .get_wallclock = native_get_wallclock,
5928         .set_wallclock = native_set_wallclock,
5929 @@ -301,7 +301,7 @@ struct pv_time_ops pv_time_ops = {
5930         .get_tsc_khz = native_calibrate_tsc,
5931  };
5932  
5933 -struct pv_irq_ops pv_irq_ops = {
5934 +struct pv_irq_ops pv_irq_ops __read_only = {
5935         .init_IRQ = native_init_IRQ,
5936         .save_fl = native_save_fl,
5937         .restore_fl = native_restore_fl,
5938 @@ -314,7 +314,7 @@ struct pv_irq_ops pv_irq_ops = {
5939  #endif
5940  };
5941  
5942 -struct pv_cpu_ops pv_cpu_ops = {
5943 +struct pv_cpu_ops pv_cpu_ops __read_only = {
5944         .cpuid = native_cpuid,
5945         .get_debugreg = native_get_debugreg,
5946         .set_debugreg = native_set_debugreg,
5947 @@ -371,7 +371,7 @@ struct pv_cpu_ops pv_cpu_ops = {
5948         },
5949  };
5950  
5951 -struct pv_apic_ops pv_apic_ops = {
5952 +struct pv_apic_ops pv_apic_ops __read_only = {
5953  #ifdef CONFIG_X86_LOCAL_APIC
5954         .apic_write = native_apic_write,
5955         .apic_read = native_apic_read,
5956 @@ -381,7 +381,7 @@ struct pv_apic_ops pv_apic_ops = {
5957  #endif
5958  };
5959  
5960 -struct pv_mmu_ops pv_mmu_ops = {
5961 +struct pv_mmu_ops pv_mmu_ops __read_only = {
5962  #ifndef CONFIG_X86_64
5963         .pagetable_setup_start = native_pagetable_setup_start,
5964         .pagetable_setup_done = native_pagetable_setup_done,
5965 @@ -461,7 +461,7 @@ struct pv_mmu_ops pv_mmu_ops = {
5966         .set_fixmap = native_set_fixmap,
5967  };
5968  
5969 -struct pv_lock_ops pv_lock_ops = {
5970 +struct pv_lock_ops pv_lock_ops __read_only = {
5971  #ifdef CONFIG_SMP
5972         .spin_is_locked = __ticket_spin_is_locked,
5973         .spin_is_contended = __ticket_spin_is_contended,
5974 diff -urNp linux-2.6.27.10/arch/x86/kernel/process_32.c linux-2.6.27.10/arch/x86/kernel/process_32.c
5975 --- linux-2.6.27.10/arch/x86/kernel/process_32.c        2008-11-07 12:55:34.000000000 -0500
5976 +++ linux-2.6.27.10/arch/x86/kernel/process_32.c        2008-11-18 03:38:44.000000000 -0500
5977 @@ -62,8 +62,10 @@ asmlinkage void ret_from_fork(void) __as
5978  DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
5979  EXPORT_PER_CPU_SYMBOL(current_task);
5980  
5981 +#ifdef CONFIG_SMP
5982  DEFINE_PER_CPU(int, cpu_number);
5983  EXPORT_PER_CPU_SYMBOL(cpu_number);
5984 +#endif
5985  
5986  /*
5987   * Return saved PC of a blocked thread.
5988 @@ -71,6 +73,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number);
5989  unsigned long thread_saved_pc(struct task_struct *tsk)
5990  {
5991         return ((unsigned long *)tsk->thread.sp)[3];
5992 +//XXX  return tsk->thread.eip;
5993  }
5994  
5995  #ifdef CONFIG_HOTPLUG_CPU
5996 @@ -162,7 +165,7 @@ void __show_registers(struct pt_regs *re
5997         unsigned long sp;
5998         unsigned short ss, gs;
5999  
6000 -       if (user_mode_vm(regs)) {
6001 +       if (user_mode(regs)) {
6002                 sp = regs->sp;
6003                 ss = regs->ss & 0xffff;
6004                 savesegment(gs, gs);
6005 @@ -239,8 +242,8 @@ int kernel_thread(int (*fn)(void *), voi
6006         regs.bx = (unsigned long) fn;
6007         regs.dx = (unsigned long) arg;
6008  
6009 -       regs.ds = __USER_DS;
6010 -       regs.es = __USER_DS;
6011 +       regs.ds = __KERNEL_DS;
6012 +       regs.es = __KERNEL_DS;
6013         regs.fs = __KERNEL_PERCPU;
6014         regs.orig_ax = -1;
6015         regs.ip = (unsigned long) kernel_thread_helper;
6016 @@ -262,7 +265,7 @@ void exit_thread(void)
6017                 struct task_struct *tsk = current;
6018                 struct thread_struct *t = &tsk->thread;
6019                 int cpu = get_cpu();
6020 -               struct tss_struct *tss = &per_cpu(init_tss, cpu);
6021 +               struct tss_struct *tss = init_tss + cpu;
6022  
6023                 kfree(t->io_bitmap_ptr);
6024                 t->io_bitmap_ptr = NULL;
6025 @@ -283,6 +286,7 @@ void flush_thread(void)
6026  {
6027         struct task_struct *tsk = current;
6028  
6029 +       loadsegment(gs, 0);
6030         tsk->thread.debugreg0 = 0;
6031         tsk->thread.debugreg1 = 0;
6032         tsk->thread.debugreg2 = 0;
6033 @@ -322,7 +326,7 @@ int copy_thread(int nr, unsigned long cl
6034         struct task_struct *tsk;
6035         int err;
6036  
6037 -       childregs = task_pt_regs(p);
6038 +       childregs = task_stack_page(p) + THREAD_SIZE - sizeof(struct pt_regs) - 8;
6039         *childregs = *regs;
6040         childregs->ax = 0;
6041         childregs->sp = sp;
6042 @@ -351,6 +355,7 @@ int copy_thread(int nr, unsigned long cl
6043          * Set a new TLS for the child thread?
6044          */
6045         if (clone_flags & CLONE_SETTLS)
6046 +//XXX needs set_fs()?
6047                 err = do_set_thread_area(p, -1,
6048                         (struct user_desc __user *)childregs->si, 0);
6049  
6050 @@ -550,7 +555,7 @@ struct task_struct * __switch_to(struct 
6051         struct thread_struct *prev = &prev_p->thread,
6052                                  *next = &next_p->thread;
6053         int cpu = smp_processor_id();
6054 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
6055 +       struct tss_struct *tss = init_tss + cpu;
6056  
6057         /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
6058  
6059 @@ -578,6 +583,11 @@ struct task_struct * __switch_to(struct 
6060          */
6061         savesegment(gs, prev->gs);
6062  
6063 +#ifdef CONFIG_PAX_MEMORY_UDEREF
6064 +       if (!segment_eq(task_thread_info(prev_p)->addr_limit, task_thread_info(next_p)->addr_limit))
6065 +               __set_fs(task_thread_info(next_p)->addr_limit, cpu);
6066 +#endif
6067 +
6068         /*
6069          * Load the per-thread Thread-Local Storage descriptor.
6070          */
6071 @@ -716,15 +726,27 @@ unsigned long get_wchan(struct task_stru
6072         return 0;
6073  }
6074  
6075 -unsigned long arch_align_stack(unsigned long sp)
6076 +#ifdef CONFIG_PAX_RANDKSTACK
6077 +asmlinkage void pax_randomize_kstack(void)
6078  {
6079 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6080 -               sp -= get_random_int() % 8192;
6081 -       return sp & ~0xf;
6082 -}
6083 +       struct thread_struct *thread = &current->thread;
6084 +       unsigned long time;
6085  
6086 -unsigned long arch_randomize_brk(struct mm_struct *mm)
6087 -{
6088 -       unsigned long range_end = mm->brk + 0x02000000;
6089 -       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
6090 +       if (!randomize_va_space)
6091 +               return;
6092 +
6093 +       rdtscl(time);
6094 +
6095 +       /* P4 seems to return a 0 LSB, ignore it */
6096 +#ifdef CONFIG_MPENTIUM4
6097 +       time &= 0x1EUL;
6098 +       time <<= 2;
6099 +#else
6100 +       time &= 0xFUL;
6101 +       time <<= 3;
6102 +#endif
6103 +
6104 +       thread->sp0 ^= time;
6105 +       load_sp0(init_tss + smp_processor_id(), thread);
6106  }
6107 +#endif
6108 diff -urNp linux-2.6.27.10/arch/x86/kernel/process_64.c linux-2.6.27.10/arch/x86/kernel/process_64.c
6109 --- linux-2.6.27.10/arch/x86/kernel/process_64.c        2008-11-07 12:55:34.000000000 -0500
6110 +++ linux-2.6.27.10/arch/x86/kernel/process_64.c        2008-11-18 03:38:44.000000000 -0500
6111 @@ -119,6 +119,8 @@ static inline void play_dead(void)
6112  void cpu_idle(void)
6113  {
6114         current_thread_info()->status |= TS_POLLING;
6115 +       current->stack_canary = pax_get_random_long();
6116 +       write_pda(stack_canary, current->stack_canary);
6117         /* endless idle loop with no priority at all */
6118         while (1) {
6119                 tick_nohz_stop_sched_tick(1);
6120 @@ -228,7 +230,7 @@ void exit_thread(void)
6121         struct thread_struct *t = &me->thread;
6122  
6123         if (me->thread.io_bitmap_ptr) {
6124 -               struct tss_struct *tss = &per_cpu(init_tss, get_cpu());
6125 +               struct tss_struct *tss = init_tss + get_cpu();
6126  
6127                 kfree(t->io_bitmap_ptr);
6128                 t->io_bitmap_ptr = NULL;
6129 @@ -541,7 +543,7 @@ __switch_to(struct task_struct *prev_p, 
6130         struct thread_struct *prev = &prev_p->thread;
6131         struct thread_struct *next = &next_p->thread;
6132         int cpu = smp_processor_id();
6133 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
6134 +       struct tss_struct *tss = init_tss + cpu;
6135         unsigned fsindex, gsindex;
6136  
6137         /* we're going to use this soon, after a few expensive things */
6138 @@ -630,7 +632,6 @@ __switch_to(struct task_struct *prev_p, 
6139                   (unsigned long)task_stack_page(next_p) +
6140                   THREAD_SIZE - PDA_STACKOFFSET);
6141  #ifdef CONFIG_CC_STACKPROTECTOR
6142 -       write_pda(stack_canary, next_p->stack_canary);
6143         /*
6144          * Build time only check to make sure the stack_canary is at
6145          * offset 40 in the pda; this is a gcc ABI requirement
6146 @@ -729,12 +730,11 @@ unsigned long get_wchan(struct task_stru
6147         if (!p || p == current || p->state==TASK_RUNNING)
6148                 return 0; 
6149         stack = (unsigned long)task_stack_page(p);
6150 -       if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
6151 +       if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE-8-sizeof(u64))
6152                 return 0;
6153         fp = *(u64 *)(p->thread.sp);
6154         do { 
6155 -               if (fp < (unsigned long)stack ||
6156 -                   fp >= (unsigned long)stack+THREAD_SIZE)
6157 +               if (fp < stack || fp > stack+THREAD_SIZE-8-sizeof(u64))
6158                         return 0; 
6159                 ip = *(u64 *)(fp+8);
6160                 if (!in_sched_functions(ip))
6161 @@ -844,16 +844,3 @@ long sys_arch_prctl(int code, unsigned l
6162  {
6163         return do_arch_prctl(current, code, addr);
6164  }
6165 -
6166 -unsigned long arch_align_stack(unsigned long sp)
6167 -{
6168 -       if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
6169 -               sp -= get_random_int() % 8192;
6170 -       return sp & ~0xf;
6171 -}
6172 -
6173 -unsigned long arch_randomize_brk(struct mm_struct *mm)
6174 -{
6175 -       unsigned long range_end = mm->brk + 0x02000000;
6176 -       return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
6177 -}
6178 diff -urNp linux-2.6.27.10/arch/x86/kernel/ptrace.c linux-2.6.27.10/arch/x86/kernel/ptrace.c
6179 --- linux-2.6.27.10/arch/x86/kernel/ptrace.c    2008-11-07 12:55:34.000000000 -0500
6180 +++ linux-2.6.27.10/arch/x86/kernel/ptrace.c    2008-11-18 03:38:44.000000000 -0500
6181 @@ -1369,7 +1369,7 @@ void send_sigtrap(struct task_struct *ts
6182         info.si_code = TRAP_BRKPT;
6183  
6184         /* User-mode ip? */
6185 -       info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
6186 +       info.si_addr = user_mode(regs) ? (void __user *) regs->ip : NULL;
6187  
6188         /* Send us the fake SIGTRAP */
6189         force_sig_info(SIGTRAP, &info, tsk);
6190 diff -urNp linux-2.6.27.10/arch/x86/kernel/reboot.c linux-2.6.27.10/arch/x86/kernel/reboot.c
6191 --- linux-2.6.27.10/arch/x86/kernel/reboot.c    2008-11-07 12:55:34.000000000 -0500
6192 +++ linux-2.6.27.10/arch/x86/kernel/reboot.c    2008-11-18 03:38:44.000000000 -0500
6193 @@ -28,7 +28,7 @@ void (*pm_power_off)(void);
6194  EXPORT_SYMBOL(pm_power_off);
6195  
6196  static const struct desc_ptr no_idt = {};
6197 -static int reboot_mode;
6198 +static unsigned short reboot_mode;
6199  enum reboot_type reboot_type = BOOT_KBD;
6200  int reboot_force;
6201  
6202 @@ -193,7 +193,7 @@ static struct dmi_system_id __initdata r
6203                         DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
6204                 },
6205         },
6206 -       { }
6207 +       { NULL, NULL, {{0, NULL}}, NULL}
6208  };
6209  
6210  static int __init reboot_init(void)
6211 @@ -209,12 +209,12 @@ core_initcall(reboot_init);
6212     controller to pulse the CPU reset line, which is more thorough, but
6213     doesn't work with at least one type of 486 motherboard.  It is easy
6214     to stop this code working; hence the copious comments. */
6215 -static const unsigned long long
6216 -real_mode_gdt_entries [3] =
6217 +static struct desc_struct
6218 +real_mode_gdt_entries [3] __read_only =
6219  {
6220 -       0x0000000000000000ULL,  /* Null descriptor */
6221 -       0x00009b000000ffffULL,  /* 16-bit real-mode 64k code at 0x00000000 */
6222 -       0x000093000100ffffULL   /* 16-bit real-mode 64k data at 0x00000100 */
6223 +       {{{0x00000000, 0x00000000}}},   /* Null descriptor */
6224 +       {{{0x0000ffff, 0x00009b00}}},   /* 16-bit real-mode 64k code at 0x00000000 */
6225 +       {{{0x0100ffff, 0x00009300}}}    /* 16-bit real-mode 64k data at 0x00000100 */
6226  };
6227  
6228  static const struct desc_ptr
6229 @@ -263,7 +263,7 @@ static const unsigned char jump_to_bios 
6230   * specified by the code and length parameters.
6231   * We assume that length will aways be less that 100!
6232   */
6233 -void machine_real_restart(const unsigned char *code, int length)
6234 +void machine_real_restart(const unsigned char *code, unsigned int length)
6235  {
6236         local_irq_disable();
6237  
6238 @@ -283,8 +283,8 @@ void machine_real_restart(const unsigned
6239         /* Remap the kernel at virtual address zero, as well as offset zero
6240            from the kernel segment.  This assumes the kernel segment starts at
6241            virtual address PAGE_OFFSET. */
6242 -       memcpy(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6243 -               sizeof(swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
6244 +       clone_pgd_range(swapper_pg_dir, swapper_pg_dir + KERNEL_PGD_BOUNDARY,
6245 +                       min_t(unsigned long, KERNEL_PGD_PTRS, KERNEL_PGD_BOUNDARY));
6246  
6247         /*
6248          * Use `swapper_pg_dir' as our page directory.
6249 @@ -296,16 +296,15 @@ void machine_real_restart(const unsigned
6250            boot)".  This seems like a fairly standard thing that gets set by
6251            REBOOT.COM programs, and the previous reset routine did this
6252            too. */
6253 -       *((unsigned short *)0x472) = reboot_mode;
6254 +       *(unsigned short *)(__va(0x472)) = reboot_mode;
6255  
6256         /* For the switch to real mode, copy some code to low memory.  It has
6257            to be in the first 64k because it is running in 16-bit mode, and it
6258            has to have the same physical and virtual address, because it turns
6259            off paging.  Copy it near the end of the first page, out of the way
6260            of BIOS variables. */
6261 -       memcpy((void *)(0x1000 - sizeof(real_mode_switch) - 100),
6262 -               real_mode_switch, sizeof (real_mode_switch));
6263 -       memcpy((void *)(0x1000 - 100), code, length);
6264 +       memcpy(__va(0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch));
6265 +       memcpy(__va(0x1000 - 100), code, length);
6266  
6267         /* Set up the IDT for real mode. */
6268         load_idt(&real_mode_idt);
6269 diff -urNp linux-2.6.27.10/arch/x86/kernel/setup.c linux-2.6.27.10/arch/x86/kernel/setup.c
6270 --- linux-2.6.27.10/arch/x86/kernel/setup.c     2008-12-21 01:18:11.000000000 -0500
6271 +++ linux-2.6.27.10/arch/x86/kernel/setup.c     2008-12-21 01:18:21.000000000 -0500
6272 @@ -578,6 +578,7 @@ static struct x86_quirks default_x86_qui
6273  
6274  struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
6275  
6276 +#ifdef CONFIG_X86_RESERVE_LOW_64K
6277  static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
6278  {
6279         printk(KERN_NOTICE
6280 @@ -589,6 +590,7 @@ static int __init dmi_low_memory_corrupt
6281  
6282         return 0;
6283  }
6284 +#endif
6285  
6286  /* List of systems that have known low memory corruption BIOS problems */
6287  static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
6288 @@ -685,8 +687,8 @@ void __init setup_arch(char **cmdline_p)
6289  
6290         if (!boot_params.hdr.root_flags)
6291                 root_mountflags &= ~MS_RDONLY;
6292 -       init_mm.start_code = (unsigned long) _text;
6293 -       init_mm.end_code = (unsigned long) _etext;
6294 +       init_mm.start_code = ktla_ktva((unsigned long) _text);
6295 +       init_mm.end_code = ktla_ktva((unsigned long) _etext);
6296         init_mm.end_data = (unsigned long) _edata;
6297  #ifdef CONFIG_X86_32
6298         init_mm.brk = init_pg_tables_end + PAGE_OFFSET;
6299 @@ -694,9 +696,9 @@ void __init setup_arch(char **cmdline_p)
6300         init_mm.brk = (unsigned long) &_end;
6301  #endif
6302  
6303 -       code_resource.start = virt_to_phys(_text);
6304 -       code_resource.end = virt_to_phys(_etext)-1;
6305 -       data_resource.start = virt_to_phys(_etext);
6306 +       code_resource.start = virt_to_phys(ktla_ktva(_text));
6307 +       code_resource.end = virt_to_phys(ktla_ktva(_etext))-1;
6308 +       data_resource.start = virt_to_phys(_data);
6309         data_resource.end = virt_to_phys(_edata)-1;
6310         bss_resource.start = virt_to_phys(&__bss_start);
6311         bss_resource.end = virt_to_phys(&__bss_stop)-1;
6312 diff -urNp linux-2.6.27.10/arch/x86/kernel/setup_percpu.c linux-2.6.27.10/arch/x86/kernel/setup_percpu.c
6313 --- linux-2.6.27.10/arch/x86/kernel/setup_percpu.c      2008-11-07 12:55:34.000000000 -0500
6314 +++ linux-2.6.27.10/arch/x86/kernel/setup_percpu.c      2008-11-18 03:38:44.000000000 -0500
6315 @@ -166,7 +166,11 @@ void __init setup_per_cpu_areas(void)
6316                 else
6317                         ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
6318  #endif
6319 +#ifdef CONFIG_X86_32
6320 +               __per_cpu_offset[cpu] = ptr - __per_cpu_start;
6321 +#else
6322                 per_cpu_offset(cpu) = ptr - __per_cpu_start;
6323 +#endif
6324                 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
6325  
6326         }
6327 diff -urNp linux-2.6.27.10/arch/x86/kernel/signal_32.c linux-2.6.27.10/arch/x86/kernel/signal_32.c
6328 --- linux-2.6.27.10/arch/x86/kernel/signal_32.c 2008-11-07 12:55:34.000000000 -0500
6329 +++ linux-2.6.27.10/arch/x86/kernel/signal_32.c 2008-11-18 03:38:44.000000000 -0500
6330 @@ -378,9 +378,9 @@ setup_frame(int sig, struct k_sigaction 
6331         }
6332  
6333         if (current->mm->context.vdso)
6334 -               restorer = VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6335 +               restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, sigreturn);
6336         else
6337 -               restorer = &frame->retcode;
6338 +               restorer = (void __user *)&frame->retcode;
6339         if (ka->sa.sa_flags & SA_RESTORER)
6340                 restorer = ka->sa.sa_restorer;
6341  
6342 @@ -460,7 +460,7 @@ static int setup_rt_frame(int sig, struc
6343                 goto give_sigsegv;
6344  
6345         /* Set up to return from userspace.  */
6346 -       restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6347 +       restorer = (void __user *)VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
6348         if (ka->sa.sa_flags & SA_RESTORER)
6349                 restorer = ka->sa.sa_restorer;
6350         err |= __put_user(restorer, &frame->pretcode);
6351 @@ -590,7 +590,7 @@ static void do_signal(struct pt_regs *re
6352          * X86_32: vm86 regs switched out by assembly code before reaching
6353          * here, so testing against kernel CS suffices.
6354          */
6355 -       if (!user_mode(regs))
6356 +       if (!user_mode_novm(regs))
6357                 return;
6358  
6359         if (current_thread_info()->status & TS_RESTORE_SIGMASK)
6360 diff -urNp linux-2.6.27.10/arch/x86/kernel/signal_64.c linux-2.6.27.10/arch/x86/kernel/signal_64.c
6361 --- linux-2.6.27.10/arch/x86/kernel/signal_64.c 2008-11-07 12:55:34.000000000 -0500
6362 +++ linux-2.6.27.10/arch/x86/kernel/signal_64.c 2008-11-18 03:38:44.000000000 -0500
6363 @@ -312,8 +312,8 @@ static int setup_rt_frame(int sig, struc
6364         err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
6365         err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
6366         if (sizeof(*set) == 16) { 
6367 -               __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6368 -               __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 
6369 +               err |= __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
6370 +               err |= __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
6371         } else
6372                 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
6373  
6374 diff -urNp linux-2.6.27.10/arch/x86/kernel/smpboot.c linux-2.6.27.10/arch/x86/kernel/smpboot.c
6375 --- linux-2.6.27.10/arch/x86/kernel/smpboot.c   2008-12-21 01:18:11.000000000 -0500
6376 +++ linux-2.6.27.10/arch/x86/kernel/smpboot.c   2008-12-21 01:18:21.000000000 -0500
6377 @@ -814,6 +814,11 @@ static int __cpuinit do_boot_cpu(int api
6378                 .cpu = cpu,
6379                 .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
6380         };
6381 +
6382 +#ifdef CONFIG_PAX_KERNEXEC
6383 +       unsigned long cr0;
6384 +#endif
6385 +
6386         INIT_WORK(&c_idle.work, do_fork_idle);
6387  
6388  #ifdef CONFIG_X86_64
6389 @@ -864,7 +869,17 @@ do_rest:
6390         cpu_pda(cpu)->pcurrent = c_idle.idle;
6391         clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
6392  #endif
6393 +
6394 +#ifdef CONFIG_PAX_KERNEXEC
6395 +       pax_open_kernel(cr0);
6396 +#endif
6397 +
6398         early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
6399 +
6400 +#ifdef CONFIG_PAX_KERNEXEC
6401 +       pax_close_kernel(cr0);
6402 +#endif
6403 +
6404         initial_code = (unsigned long)start_secondary;
6405         stack_start.sp = (void *) c_idle.idle->thread.sp;
6406  
6407 diff -urNp linux-2.6.27.10/arch/x86/kernel/smpcommon.c linux-2.6.27.10/arch/x86/kernel/smpcommon.c
6408 --- linux-2.6.27.10/arch/x86/kernel/smpcommon.c 2008-11-07 12:55:34.000000000 -0500
6409 +++ linux-2.6.27.10/arch/x86/kernel/smpcommon.c 2008-11-18 03:38:44.000000000 -0500
6410 @@ -3,9 +3,10 @@
6411   */
6412  #include <linux/module.h>
6413  #include <asm/smp.h>
6414 +#include <asm/sections.h>
6415  
6416  #ifdef CONFIG_X86_32
6417 -DEFINE_PER_CPU(unsigned long, this_cpu_off);
6418 +DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_start;
6419  EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6420  
6421  /*
6422 @@ -15,16 +16,19 @@ EXPORT_PER_CPU_SYMBOL(this_cpu_off);
6423   */
6424  __cpuinit void init_gdt(int cpu)
6425  {
6426 -       struct desc_struct gdt;
6427 +       struct desc_struct d, *gdt = get_cpu_gdt_table(cpu);
6428 +       unsigned long base, limit;
6429  
6430 -       pack_descriptor(&gdt, __per_cpu_offset[cpu], 0xFFFFF,
6431 -                       0x2 | DESCTYPE_S, 0x8);
6432 -       gdt.s = 1;
6433 +       base = per_cpu_offset(cpu);
6434 +       limit = PERCPU_ENOUGH_ROOM - 1;
6435 +       if (limit < 64*1024)
6436 +               pack_descriptor(&d, base, limit, 0x80 | DESCTYPE_S | 0x3, 0x4);
6437 +       else
6438 +               pack_descriptor(&d, base, limit >> PAGE_SHIFT, 0x80 | DESCTYPE_S | 0x3, 0xC);
6439  
6440 -       write_gdt_entry(get_cpu_gdt_table(cpu),
6441 -                       GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
6442 +       write_gdt_entry(gdt, GDT_ENTRY_PERCPU, &d, DESCTYPE_S);
6443  
6444 -       per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
6445 +       per_cpu(this_cpu_off, cpu) = base;
6446         per_cpu(cpu_number, cpu) = cpu;
6447  }
6448  #endif
6449 diff -urNp linux-2.6.27.10/arch/x86/kernel/step.c linux-2.6.27.10/arch/x86/kernel/step.c
6450 --- linux-2.6.27.10/arch/x86/kernel/step.c      2008-11-07 12:55:34.000000000 -0500
6451 +++ linux-2.6.27.10/arch/x86/kernel/step.c      2008-11-18 03:38:44.000000000 -0500
6452 @@ -23,22 +23,20 @@ unsigned long convert_ip_to_linear(struc
6453          * and APM bios ones we just ignore here.
6454          */
6455         if ((seg & SEGMENT_TI_MASK) == SEGMENT_LDT) {
6456 -               u32 *desc;
6457 +               struct desc_struct *desc;
6458                 unsigned long base;
6459  
6460 -               seg &= ~7UL;
6461 +               seg >>= 3;
6462  
6463                 mutex_lock(&child->mm->context.lock);
6464 -               if (unlikely((seg >> 3) >= child->mm->context.size))
6465 -                       addr = -1L; /* bogus selector, access would fault */
6466 +               if (unlikely(seg >= child->mm->context.size))
6467 +                       addr = -EINVAL;
6468                 else {
6469 -                       desc = child->mm->context.ldt + seg;
6470 -                       base = ((desc[0] >> 16) |
6471 -                               ((desc[1] & 0xff) << 16) |
6472 -                               (desc[1] & 0xff000000));
6473 +                       desc = &child->mm->context.ldt[seg];
6474 +                       base = (desc->a >> 16) | ((desc->b & 0xff) << 16) | (desc->b & 0xff000000);
6475  
6476                         /* 16-bit code segment? */
6477 -                       if (!((desc[1] >> 22) & 1))
6478 +                       if (!((desc->b >> 22) & 1))
6479                                 addr &= 0xffff;
6480                         addr += base;
6481                 }
6482 @@ -54,6 +52,9 @@ static int is_setting_trap_flag(struct t
6483         unsigned char opcode[15];
6484         unsigned long addr = convert_ip_to_linear(child, regs);
6485  
6486 +       if (addr == -EINVAL)
6487 +               return 0;
6488 +
6489         copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
6490         for (i = 0; i < copied; i++) {
6491                 switch (opcode[i]) {
6492 @@ -75,7 +76,7 @@ static int is_setting_trap_flag(struct t
6493  
6494  #ifdef CONFIG_X86_64
6495                 case 0x40 ... 0x4f:
6496 -                       if (regs->cs != __USER_CS)
6497 +                       if ((regs->cs & 0xffff) != __USER_CS)
6498                                 /* 32-bit mode: register increment */
6499                                 return 0;
6500                         /* 64-bit mode: REX prefix */
6501 diff -urNp linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S
6502 --- linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S  2008-11-07 12:55:34.000000000 -0500
6503 +++ linux-2.6.27.10/arch/x86/kernel/syscall_table_32.S  2008-11-18 03:38:44.000000000 -0500
6504 @@ -1,3 +1,4 @@
6505 +.section .rodata,"a",@progbits
6506  ENTRY(sys_call_table)
6507         .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
6508         .long sys_exit
6509 diff -urNp linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c
6510 --- linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c       2008-11-07 12:55:34.000000000 -0500
6511 +++ linux-2.6.27.10/arch/x86/kernel/sys_i386_32.c       2008-11-18 03:38:44.000000000 -0500
6512 @@ -22,6 +22,21 @@
6513  #include <linux/uaccess.h>
6514  #include <linux/unistd.h>
6515  
6516 +int i386_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
6517 +{
6518 +       unsigned long pax_task_size = TASK_SIZE;
6519 +
6520 +#ifdef CONFIG_PAX_SEGMEXEC
6521 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
6522 +               pax_task_size = SEGMEXEC_TASK_SIZE;
6523 +#endif
6524 +
6525 +       if (len > pax_task_size || addr > pax_task_size - len)
6526 +               return -EINVAL;
6527 +
6528 +       return 0;
6529 +}
6530 +
6531  asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
6532                           unsigned long prot, unsigned long flags,
6533                           unsigned long fd, unsigned long pgoff)
6534 @@ -81,6 +96,205 @@ out:
6535         return err;
6536  }
6537  
6538 +unsigned long
6539 +arch_get_unmapped_area(struct file *filp, unsigned long addr,
6540 +               unsigned long len, unsigned long pgoff, unsigned long flags)
6541 +{
6542 +       struct mm_struct *mm = current->mm;
6543 +       struct vm_area_struct *vma;
6544 +       unsigned long start_addr, pax_task_size = TASK_SIZE;
6545 +
6546 +#ifdef CONFIG_PAX_SEGMEXEC
6547 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6548 +               pax_task_size = SEGMEXEC_TASK_SIZE;
6549 +#endif
6550 +
6551 +       if (len > pax_task_size)
6552 +               return -ENOMEM;
6553 +
6554 +       if (flags & MAP_FIXED)
6555 +               return addr;
6556 +
6557 +#ifdef CONFIG_PAX_RANDMMAP
6558 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6559 +#endif
6560 +
6561 +       if (addr) {
6562 +               addr = PAGE_ALIGN(addr);
6563 +               vma = find_vma(mm, addr);
6564 +               if (pax_task_size - len >= addr &&
6565 +                   (!vma || addr + len <= vma->vm_start))
6566 +                       return addr;
6567 +       }
6568 +       if (len > mm->cached_hole_size) {
6569 +               start_addr = addr = mm->free_area_cache;
6570 +       } else {
6571 +               start_addr = addr = mm->mmap_base;
6572 +               mm->cached_hole_size = 0;
6573 +       }
6574 +
6575 +#ifdef CONFIG_PAX_PAGEEXEC
6576 +       if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE) && start_addr >= mm->mmap_base) {
6577 +               start_addr = 0x00110000UL;
6578 +
6579 +#ifdef CONFIG_PAX_RANDMMAP
6580 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
6581 +                       start_addr += mm->delta_mmap & 0x03FFF000UL;
6582 +#endif
6583 +
6584 +               if (mm->start_brk <= start_addr && start_addr < mm->mmap_base)
6585 +                       start_addr = addr = mm->mmap_base;
6586 +               else
6587 +                       addr = start_addr;
6588 +       }
6589 +#endif
6590 +
6591 +full_search:
6592 +       for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
6593 +               /* At this point:  (!vma || addr < vma->vm_end). */
6594 +               if (pax_task_size - len < addr) {
6595 +                       /*
6596 +                        * Start a new search - just in case we missed
6597 +                        * some holes.
6598 +                        */
6599 +                       if (start_addr != mm->mmap_base) {
6600 +                               start_addr = addr = mm->mmap_base;
6601 +                               mm->cached_hole_size = 0;
6602 +                               goto full_search;
6603 +                       }
6604 +                       return -ENOMEM;
6605 +               }
6606 +               if (!vma || addr + len <= vma->vm_start) {
6607 +                       /*
6608 +                        * Remember the place where we stopped the search:
6609 +                        */
6610 +                       mm->free_area_cache = addr + len;
6611 +                       return addr;
6612 +               }
6613 +               if (addr + mm->cached_hole_size < vma->vm_start)
6614 +                       mm->cached_hole_size = vma->vm_start - addr;
6615 +               addr = vma->vm_end;
6616 +               if (mm->start_brk <= addr && addr < mm->mmap_base) {
6617 +                       start_addr = addr = mm->mmap_base;
6618 +                       mm->cached_hole_size = 0;
6619 +                       goto full_search;
6620 +               }
6621 +       }
6622 +}
6623 +
6624 +unsigned long
6625 +arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
6626 +                         const unsigned long len, const unsigned long pgoff,
6627 +                         const unsigned long flags)
6628 +{
6629 +       struct vm_area_struct *vma;
6630 +       struct mm_struct *mm = current->mm;
6631 +       unsigned long base = mm->mmap_base, addr = addr0, pax_task_size = TASK_SIZE;
6632 +
6633 +#ifdef CONFIG_PAX_SEGMEXEC
6634 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6635 +               pax_task_size = SEGMEXEC_TASK_SIZE;
6636 +#endif
6637 +
6638 +       /* requested length too big for entire address space */
6639 +       if (len > pax_task_size)
6640 +               return -ENOMEM;
6641 +
6642 +       if (flags & MAP_FIXED)
6643 +               return addr;
6644 +
6645 +#ifdef CONFIG_PAX_PAGEEXEC
6646 +       if (!nx_enabled && (mm->pax_flags & MF_PAX_PAGEEXEC) && (flags & MAP_EXECUTABLE))
6647 +               goto bottomup;
6648 +#endif
6649 +
6650 +#ifdef CONFIG_PAX_RANDMMAP
6651 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6652 +#endif
6653 +
6654 +       /* requesting a specific address */
6655 +       if (addr) {
6656 +               addr = PAGE_ALIGN(addr);
6657 +               vma = find_vma(mm, addr);
6658 +               if (pax_task_size - len >= addr &&
6659 +                               (!vma || addr + len <= vma->vm_start))
6660 +                       return addr;
6661 +       }
6662 +
6663 +       /* check if free_area_cache is useful for us */
6664 +       if (len <= mm->cached_hole_size) {
6665 +               mm->cached_hole_size = 0;
6666 +               mm->free_area_cache = mm->mmap_base;
6667 +       }
6668 +
6669 +       /* either no address requested or can't fit in requested address hole */
6670 +       addr = mm->free_area_cache;
6671 +
6672 +       /* make sure it can fit in the remaining address space */
6673 +       if (addr > len) {
6674 +               vma = find_vma(mm, addr-len);
6675 +               if (!vma || addr <= vma->vm_start)
6676 +                       /* remember the address as a hint for next time */
6677 +                       return (mm->free_area_cache = addr-len);
6678 +       }
6679 +
6680 +       if (mm->mmap_base < len)
6681 +               goto bottomup;
6682 +
6683 +       addr = mm->mmap_base-len;
6684 +
6685 +       do {
6686 +               /*
6687 +                * Lookup failure means no vma is above this address,
6688 +                * else if new region fits below vma->vm_start,
6689 +                * return with success:
6690 +                */
6691 +               vma = find_vma(mm, addr);
6692 +               if (!vma || addr+len <= vma->vm_start)
6693 +                       /* remember the address as a hint for next time */
6694 +                       return (mm->free_area_cache = addr);
6695 +
6696 +               /* remember the largest hole we saw so far */
6697 +               if (addr + mm->cached_hole_size < vma->vm_start)
6698 +                       mm->cached_hole_size = vma->vm_start - addr;
6699 +
6700 +               /* try just below the current vma->vm_start */
6701 +               addr = vma->vm_start-len;
6702 +       } while (len < vma->vm_start);
6703 +
6704 +bottomup:
6705 +       /*
6706 +        * A failed mmap() very likely causes application failure,
6707 +        * so fall back to the bottom-up function here. This scenario
6708 +        * can happen with large stack limits and large mmap()
6709 +        * allocations.
6710 +        */
6711 +
6712 +#ifdef CONFIG_PAX_SEGMEXEC
6713 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
6714 +               mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
6715 +       else
6716 +#endif
6717 +
6718 +       mm->mmap_base = TASK_UNMAPPED_BASE;
6719 +
6720 +#ifdef CONFIG_PAX_RANDMMAP
6721 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
6722 +               mm->mmap_base += mm->delta_mmap;
6723 +#endif
6724 +
6725 +       mm->free_area_cache = mm->mmap_base;
6726 +       mm->cached_hole_size = ~0UL;
6727 +       addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6728 +       /*
6729 +        * Restore the topdown base:
6730 +        */
6731 +       mm->mmap_base = base;
6732 +       mm->free_area_cache = base;
6733 +       mm->cached_hole_size = ~0UL;
6734 +
6735 +       return addr;
6736 +}
6737  
6738  struct sel_arg_struct {
6739         unsigned long n;
6740 diff -urNp linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c
6741 --- linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c        2008-11-07 12:55:34.000000000 -0500
6742 +++ linux-2.6.27.10/arch/x86/kernel/sys_x86_64.c        2008-11-18 03:38:44.000000000 -0500
6743 @@ -45,8 +45,8 @@ out:
6744         return error;
6745  }
6746  
6747 -static void find_start_end(unsigned long flags, unsigned long *begin,
6748 -                          unsigned long *end)
6749 +static void find_start_end(struct mm_struct *mm, unsigned long flags,
6750 +                          unsigned long *begin, unsigned long *end)
6751  {
6752         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT)) {
6753                 unsigned long new_begin;
6754 @@ -65,7 +65,7 @@ static void find_start_end(unsigned long
6755                                 *begin = new_begin;
6756                 }
6757         } else {
6758 -               *begin = TASK_UNMAPPED_BASE;
6759 +               *begin = mm->mmap_base;
6760                 *end = TASK_SIZE; 
6761         }
6762  } 
6763 @@ -82,11 +82,15 @@ arch_get_unmapped_area(struct file *filp
6764         if (flags & MAP_FIXED)
6765                 return addr;
6766  
6767 -       find_start_end(flags, &begin, &end); 
6768 +       find_start_end(mm, flags, &begin, &end);
6769  
6770         if (len > end)
6771                 return -ENOMEM;
6772  
6773 +#ifdef CONFIG_PAX_RANDMMAP
6774 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP) || !filp)
6775 +#endif
6776 +
6777         if (addr) {
6778                 addr = PAGE_ALIGN(addr);
6779                 vma = find_vma(mm, addr);
6780 @@ -141,7 +145,7 @@ arch_get_unmapped_area_topdown(struct fi
6781  {
6782         struct vm_area_struct *vma;
6783         struct mm_struct *mm = current->mm;
6784 -       unsigned long addr = addr0;
6785 +       unsigned long base = mm->mmap_base, addr = addr0;
6786  
6787         /* requested length too big for entire address space */
6788         if (len > TASK_SIZE)
6789 @@ -154,6 +158,10 @@ arch_get_unmapped_area_topdown(struct fi
6790         if (!test_thread_flag(TIF_IA32) && (flags & MAP_32BIT))
6791                 goto bottomup;
6792  
6793 +#ifdef CONFIG_PAX_RANDMMAP
6794 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
6795 +#endif
6796 +
6797         /* requesting a specific address */
6798         if (addr) {
6799                 addr = PAGE_ALIGN(addr);
6800 @@ -211,13 +219,21 @@ bottomup:
6801          * can happen with large stack limits and large mmap()
6802          * allocations.
6803          */
6804 +       mm->mmap_base = TASK_UNMAPPED_BASE;
6805 +
6806 +#ifdef CONFIG_PAX_RANDMMAP
6807 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
6808 +               mm->mmap_base += mm->delta_mmap;
6809 +#endif
6810 +
6811 +       mm->free_area_cache = mm->mmap_base;
6812         mm->cached_hole_size = ~0UL;
6813 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
6814         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
6815         /*
6816          * Restore the topdown base:
6817          */
6818 -       mm->free_area_cache = mm->mmap_base;
6819 +       mm->mmap_base = base;
6820 +       mm->free_area_cache = base;
6821         mm->cached_hole_size = ~0UL;
6822  
6823         return addr;
6824 diff -urNp linux-2.6.27.10/arch/x86/kernel/time_32.c linux-2.6.27.10/arch/x86/kernel/time_32.c
6825 --- linux-2.6.27.10/arch/x86/kernel/time_32.c   2008-11-07 12:55:34.000000000 -0500
6826 +++ linux-2.6.27.10/arch/x86/kernel/time_32.c   2008-11-18 03:38:44.000000000 -0500
6827 @@ -49,20 +49,30 @@ unsigned long profile_pc(struct pt_regs 
6828         if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
6829             in_lock_functions(pc)) {
6830  #ifdef CONFIG_FRAME_POINTER
6831 -               return *(unsigned long *)(regs->bp + 4);
6832 +               return ktla_ktva(*(unsigned long *)(regs->bp + 4));
6833  #else
6834                 unsigned long *sp = (unsigned long *)&regs->sp;
6835  
6836                 /* Return address is either directly at stack pointer
6837                    or above a saved flags. Eflags has bits 22-31 zero,
6838                    kernel addresses don't. */
6839 +
6840 +#ifdef CONFIG_PAX_KERNEXEC
6841 +               return ktla_ktva(sp[0]);
6842 +#else
6843                 if (sp[0] >> 22)
6844                         return sp[0];
6845                 if (sp[1] >> 22)
6846                         return sp[1];
6847  #endif
6848 +
6849 +#endif
6850         }
6851  #endif
6852 +
6853 +       if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs))
6854 +               pc = ktla_ktva(pc);
6855 +
6856         return pc;
6857  }
6858  EXPORT_SYMBOL(profile_pc);
6859 diff -urNp linux-2.6.27.10/arch/x86/kernel/tlb_32.c linux-2.6.27.10/arch/x86/kernel/tlb_32.c
6860 --- linux-2.6.27.10/arch/x86/kernel/tlb_32.c    2008-11-07 12:55:34.000000000 -0500
6861 +++ linux-2.6.27.10/arch/x86/kernel/tlb_32.c    2008-11-18 03:38:44.000000000 -0500
6862 @@ -5,7 +5,7 @@
6863  #include <asm/tlbflush.h>
6864  
6865  DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
6866 -                       ____cacheline_aligned = { &init_mm, 0, };
6867 +                       ____cacheline_aligned = { &init_mm, 0, {0} };
6868  
6869  /* must come after the send_IPI functions above for inlining */
6870  #include <mach_ipi.h>
6871 diff -urNp linux-2.6.27.10/arch/x86/kernel/tls.c linux-2.6.27.10/arch/x86/kernel/tls.c
6872 --- linux-2.6.27.10/arch/x86/kernel/tls.c       2008-11-07 12:55:34.000000000 -0500
6873 +++ linux-2.6.27.10/arch/x86/kernel/tls.c       2008-11-18 03:38:44.000000000 -0500
6874 @@ -84,6 +84,11 @@ int do_set_thread_area(struct task_struc
6875         if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
6876                 return -EINVAL;
6877  
6878 +#ifdef CONFIG_PAX_SEGMEXEC
6879 +       if ((p->mm->pax_flags & MF_PAX_SEGMEXEC) && (info.contents & MODIFY_LDT_CONTENTS_CODE))
6880 +               return -EINVAL;
6881 +#endif
6882 +
6883         set_tls_desc(p, idx, &info, 1);
6884  
6885         return 0;
6886 diff -urNp linux-2.6.27.10/arch/x86/kernel/traps_32.c linux-2.6.27.10/arch/x86/kernel/traps_32.c
6887 --- linux-2.6.27.10/arch/x86/kernel/traps_32.c  2008-11-07 12:55:34.000000000 -0500
6888 +++ linux-2.6.27.10/arch/x86/kernel/traps_32.c  2008-12-10 22:28:27.000000000 -0500
6889 @@ -70,14 +70,6 @@ asmlinkage int system_call(void);
6890  /* Do we ignore FPU interrupts ? */
6891  char ignore_fpu_irq;
6892  
6893 -/*
6894 - * The IDT has to be page-aligned to simplify the Pentium
6895 - * F0 0F bug workaround.. We have a special link segment
6896 - * for this.
6897 - */
6898 -gate_desc idt_table[256]
6899 -       __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
6900 -
6901  int panic_on_unrecovered_nmi;
6902  int kstack_depth_to_print = 24;
6903  static unsigned int code_bytes = 64;
6904 @@ -320,21 +312,22 @@ void show_registers(struct pt_regs *regs
6905          * When in-kernel, we also print out the stack and code at the
6906          * time of the fault..
6907          */
6908 -       if (!user_mode_vm(regs)) {
6909 +       if (!user_mode(regs)) {
6910                 unsigned int code_prologue = code_bytes * 43 / 64;
6911                 unsigned int code_len = code_bytes;
6912                 unsigned char c;
6913                 u8 *ip;
6914 +               unsigned long cs_base = get_desc_base(&get_cpu_gdt_table(smp_processor_id())[(0xffff & regs->cs) >> 3]);
6915  
6916                 printk("\n" KERN_EMERG "Stack: ");
6917                 show_stack_log_lvl(NULL, regs, &regs->sp, 0, KERN_EMERG);
6918  
6919                 printk(KERN_EMERG "Code: ");
6920  
6921 -               ip = (u8 *)regs->ip - code_prologue;
6922 +               ip = (u8 *)regs->ip - code_prologue + cs_base;
6923                 if (ip < (u8 *)PAGE_OFFSET || probe_kernel_address(ip, c)) {
6924                         /* try starting at EIP */
6925 -                       ip = (u8 *)regs->ip;
6926 +                       ip = (u8 *)regs->ip + cs_base;
6927                         code_len = code_len - code_prologue + 1;
6928                 }
6929                 for (i = 0; i < code_len; i++, ip++) {
6930 @@ -343,7 +336,7 @@ void show_registers(struct pt_regs *regs
6931                                 printk(" Bad EIP value.");
6932                                 break;
6933                         }
6934 -                       if (ip == (u8 *)regs->ip)
6935 +                       if (ip == (u8 *)regs->ip + cs_base)
6936                                 printk("<%02x> ", c);
6937                         else
6938                                 printk("%02x ", c);
6939 @@ -356,6 +349,7 @@ int is_valid_bugaddr(unsigned long ip)
6940  {
6941         unsigned short ud2;
6942  
6943 +       ip = ktla_ktva(ip);
6944         if (ip < PAGE_OFFSET)
6945                 return 0;
6946         if (probe_kernel_address((unsigned short *)ip, ud2))
6947 @@ -469,7 +463,7 @@ void die(const char *str, struct pt_regs
6948  static inline void
6949  die_if_kernel(const char *str, struct pt_regs *regs, long err)
6950  {
6951 -       if (!user_mode_vm(regs))
6952 +       if (!user_mode(regs))
6953                 die(str, regs, err);
6954  }
6955  
6956 @@ -479,13 +473,13 @@ do_trap(int trapnr, int signr, char *str
6957  {
6958         struct task_struct *tsk = current;
6959  
6960 -       if (regs->flags & X86_VM_MASK) {
6961 +       if (v8086_mode(regs)) {
6962                 if (vm86)
6963                         goto vm86_trap;
6964                 goto trap_signal;
6965         }
6966  
6967 -       if (!user_mode(regs))
6968 +       if (!user_mode_novm(regs))
6969                 goto kernel_trap;
6970  
6971  trap_signal:
6972 @@ -513,6 +507,12 @@ kernel_trap:
6973                 tsk->thread.trap_no = trapnr;
6974                 die(str, regs, error_code);
6975         }
6976 +
6977 +#ifdef CONFIG_PAX_REFCOUNT
6978 +       if (trapnr == 4)
6979 +               pax_report_refcount_overflow(regs);
6980 +#endif
6981 +
6982         return;
6983  
6984  vm86_trap:
6985 @@ -595,7 +595,7 @@ do_general_protection(struct pt_regs *re
6986         int cpu;
6987  
6988         cpu = get_cpu();
6989 -       tss = &per_cpu(init_tss, cpu);
6990 +       tss = init_tss + cpu;
6991         thread = &current->thread;
6992  
6993         /*
6994 @@ -627,13 +627,29 @@ do_general_protection(struct pt_regs *re
6995         }
6996         put_cpu();
6997  
6998 -       if (regs->flags & X86_VM_MASK)
6999 +       if (v8086_mode(regs))
7000                 goto gp_in_vm86;
7001  
7002         tsk = current;
7003 -       if (!user_mode(regs))
7004 +       if (!user_mode_novm(regs))
7005                 goto gp_in_kernel;
7006  
7007 +#ifdef CONFIG_PAX_PAGEEXEC
7008 +       if (!nx_enabled && tsk->mm && (tsk->mm->pax_flags & MF_PAX_PAGEEXEC)) {
7009 +               struct mm_struct *mm = tsk->mm;
7010 +               unsigned long limit;
7011 +
7012 +               down_write(&mm->mmap_sem);
7013 +               limit = mm->context.user_cs_limit;
7014 +               if (limit < TASK_SIZE) {
7015 +                       track_exec_limit(mm, limit, TASK_SIZE, VM_EXEC);
7016 +                       up_write(&mm->mmap_sem);
7017 +                       return;
7018 +               }
7019 +               up_write(&mm->mmap_sem);
7020 +       }
7021 +#endif
7022 +
7023         tsk->thread.error_code = error_code;
7024         tsk->thread.trap_no = 13;
7025  
7026 @@ -664,6 +680,13 @@ gp_in_kernel:
7027         if (notify_die(DIE_GPF, "general protection fault", regs,
7028                                 error_code, 13, SIGSEGV) == NOTIFY_STOP)
7029                 return;
7030 +
7031 +#ifdef CONFIG_PAX_KERNEXEC
7032 +       if ((regs->cs & 0xFFFF) == __KERNEL_CS)
7033 +               die("PAX: suspicious general protection fault", regs, error_code);
7034 +       else
7035 +#endif
7036 +
7037         die("general protection fault", regs, error_code);
7038  }
7039  
7040 @@ -766,7 +789,7 @@ void notrace __kprobes die_nmi(char *str
7041          * If we are in kernel we are probably nested up pretty bad
7042          * and might aswell get out now while we still can:
7043          */
7044 -       if (!user_mode_vm(regs)) {
7045 +       if (!user_mode(regs)) {
7046                 current->thread.trap_no = 2;
7047                 crash_kexec(regs);
7048         }
7049 @@ -915,7 +938,7 @@ void __kprobes do_debug(struct pt_regs *
7050                         goto clear_dr7;
7051         }
7052  
7053 -       if (regs->flags & X86_VM_MASK)
7054 +       if (v8086_mode(regs))
7055                 goto debug_vm86;
7056  
7057         /* Save debug status register where ptrace can see it */
7058 @@ -931,7 +954,7 @@ void __kprobes do_debug(struct pt_regs *
7059                  * check for kernel mode by just checking the CPL
7060                  * of CS.
7061                  */
7062 -               if (!user_mode(regs))
7063 +               if (!user_mode_novm(regs))
7064                         goto clear_TF_reenable;
7065         }
7066  
7067 @@ -1086,7 +1109,7 @@ void do_simd_coprocessor_error(struct pt
7068          * Handle strange cache flush from user space exception
7069          * in all other cases.  This is undocumented behaviour.
7070          */
7071 -       if (regs->flags & X86_VM_MASK) {
7072 +       if (v8086_mode(regs)) {
7073                 handle_vm86_fault((struct kernel_vm86_regs *)regs, error_code);
7074                 return;
7075         }
7076 @@ -1106,19 +1129,14 @@ void do_spurious_interrupt_bug(struct pt
7077  
7078  unsigned long patch_espfix_desc(unsigned long uesp, unsigned long kesp)
7079  {
7080 -       struct desc_struct *gdt = get_cpu_gdt_table(smp_processor_id());
7081         unsigned long base = (kesp - uesp) & -THREAD_SIZE;
7082         unsigned long new_kesp = kesp - base;
7083         unsigned long lim_pages = (new_kesp | (THREAD_SIZE - 1)) >> PAGE_SHIFT;
7084 -       __u64 desc = *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS];
7085 +       struct desc_struct ss;
7086  
7087         /* Set up base for espfix segment */
7088 -       desc &= 0x00f0ff0000000000ULL;
7089 -       desc |= ((((__u64)base) << 16) & 0x000000ffffff0000ULL) |
7090 -               ((((__u64)base) << 32) & 0xff00000000000000ULL) |
7091 -               ((((__u64)lim_pages) << 32) & 0x000f000000000000ULL) |
7092 -               (lim_pages & 0xffff);
7093 -       *(__u64 *)&gdt[GDT_ENTRY_ESPFIX_SS] = desc;
7094 +       pack_descriptor(&ss, base, lim_pages, 0x93, 0xC);
7095 +       write_gdt_entry(get_cpu_gdt_table(smp_processor_id()), GDT_ENTRY_ESPFIX_SS, &ss, DESCTYPE_S);
7096  
7097         return new_kesp;
7098  }
7099 diff -urNp linux-2.6.27.10/arch/x86/kernel/traps_64.c linux-2.6.27.10/arch/x86/kernel/traps_64.c
7100 --- linux-2.6.27.10/arch/x86/kernel/traps_64.c  2008-11-07 12:55:34.000000000 -0500
7101 +++ linux-2.6.27.10/arch/x86/kernel/traps_64.c  2008-11-18 03:38:44.000000000 -0500
7102 @@ -634,6 +634,12 @@ kernel_trap:
7103                 tsk->thread.trap_no = trapnr;
7104                 die(str, regs, error_code);
7105         }
7106 +
7107 +#ifdef CONFIG_PAX_REFCOUNT
7108 +       if (trapnr == 4)
7109 +               pax_report_refcount_overflow(regs);
7110 +#endif
7111 +
7112         return;
7113  }
7114  
7115 diff -urNp linux-2.6.27.10/arch/x86/kernel/tsc.c linux-2.6.27.10/arch/x86/kernel/tsc.c
7116 --- linux-2.6.27.10/arch/x86/kernel/tsc.c       2008-11-17 20:03:30.000000000 -0500
7117 +++ linux-2.6.27.10/arch/x86/kernel/tsc.c       2008-11-18 03:38:44.000000000 -0500
7118 @@ -554,7 +554,7 @@ static struct dmi_system_id __initdata b
7119                         DMI_MATCH(DMI_BOARD_NAME, "2635FA0"),
7120                 },
7121         },
7122 -       {}
7123 +       { NULL, NULL, {{0, NULL}}, NULL}
7124  };
7125  
7126  /*
7127 diff -urNp linux-2.6.27.10/arch/x86/kernel/vm86_32.c linux-2.6.27.10/arch/x86/kernel/vm86_32.c
7128 --- linux-2.6.27.10/arch/x86/kernel/vm86_32.c   2008-11-07 12:55:34.000000000 -0500
7129 +++ linux-2.6.27.10/arch/x86/kernel/vm86_32.c   2008-11-18 03:38:44.000000000 -0500
7130 @@ -147,7 +147,7 @@ struct pt_regs *save_v86_state(struct ke
7131                 do_exit(SIGSEGV);
7132         }
7133  
7134 -       tss = &per_cpu(init_tss, get_cpu());
7135 +       tss = init_tss + get_cpu();
7136         current->thread.sp0 = current->thread.saved_sp0;
7137         current->thread.sysenter_cs = __KERNEL_CS;
7138         load_sp0(tss, &current->thread);
7139 @@ -324,7 +324,7 @@ static void do_sys_vm86(struct kernel_vm
7140         tsk->thread.saved_fs = info->regs32->fs;
7141         savesegment(gs, tsk->thread.saved_gs);
7142  
7143 -       tss = &per_cpu(init_tss, get_cpu());
7144 +       tss = init_tss + get_cpu();
7145         tsk->thread.sp0 = (unsigned long) &info->VM86_TSS_ESP0;
7146         if (cpu_has_sep)
7147                 tsk->thread.sysenter_cs = 0;
7148 diff -urNp linux-2.6.27.10/arch/x86/kernel/vmi_32.c linux-2.6.27.10/arch/x86/kernel/vmi_32.c
7149 --- linux-2.6.27.10/arch/x86/kernel/vmi_32.c    2008-12-21 01:18:11.000000000 -0500
7150 +++ linux-2.6.27.10/arch/x86/kernel/vmi_32.c    2008-12-21 01:18:21.000000000 -0500
7151 @@ -102,18 +102,43 @@ static unsigned patch_internal(int call,
7152  {
7153         u64 reloc;
7154         struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
7155 +
7156 +#ifdef CONFIG_PAX_KERNEXEC
7157 +       unsigned long cr0;
7158 +#endif
7159 +
7160         reloc = call_vrom_long_func(vmi_rom, get_reloc, call);
7161         switch(rel->type) {
7162                 case VMI_RELOCATION_CALL_REL:
7163                         BUG_ON(len < 5);
7164 +
7165 +#ifdef CONFIG_PAX_KERNEXEC
7166 +                       pax_open_kernel(cr0);
7167 +#endif
7168 +
7169                         *(char *)insnbuf = MNEM_CALL;
7170                         patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7171 +
7172 +#ifdef CONFIG_PAX_KERNEXEC
7173 +                       pax_close_kernel(cr0);
7174 +#endif
7175 +
7176                         return 5;
7177  
7178                 case VMI_RELOCATION_JUMP_REL:
7179                         BUG_ON(len < 5);
7180 +
7181 +#ifdef CONFIG_PAX_KERNEXEC
7182 +                       pax_open_kernel(cr0);
7183 +#endif
7184 +
7185                         *(char *)insnbuf = MNEM_JMP;
7186                         patch_offset(insnbuf, ip, (unsigned long)rel->eip);
7187 +
7188 +#ifdef CONFIG_PAX_KERNEXEC
7189 +                       pax_close_kernel(cr0);
7190 +#endif
7191 +
7192                         return 5;
7193  
7194                 case VMI_RELOCATION_NOP:
7195 @@ -516,14 +541,14 @@ static void vmi_set_pud(pud_t *pudp, pud
7196  
7197  static void vmi_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
7198  {
7199 -       const pte_t pte = { .pte = 0 };
7200 +       const pte_t pte = __pte(0ULL);
7201         vmi_check_page_type(__pa(ptep) >> PAGE_SHIFT, VMI_PAGE_PTE);
7202         vmi_ops.set_pte(pte, ptep, vmi_flags_addr(mm, addr, VMI_PAGE_PT, 0));
7203  }
7204  
7205  static void vmi_pmd_clear(pmd_t *pmd)
7206  {
7207 -       const pte_t pte = { .pte = 0 };
7208 +       const pte_t pte = __pte(0ULL);
7209         vmi_check_page_type(__pa(pmd) >> PAGE_SHIFT, VMI_PAGE_PMD);
7210         vmi_ops.set_pte(pte, (pte_t *)pmd, VMI_PAGE_PD);
7211  }
7212 @@ -552,8 +577,8 @@ vmi_startup_ipi_hook(int phys_apicid, un
7213         ap.ss = __KERNEL_DS;
7214         ap.esp = (unsigned long) start_esp;
7215  
7216 -       ap.ds = __USER_DS;
7217 -       ap.es = __USER_DS;
7218 +       ap.ds = __KERNEL_DS;
7219 +       ap.es = __KERNEL_DS;
7220         ap.fs = __KERNEL_PERCPU;
7221         ap.gs = 0;
7222  
7223 @@ -748,12 +773,20 @@ static inline int __init activate_vmi(vo
7224         u64 reloc;
7225         const struct vmi_relocation_info *rel = (struct vmi_relocation_info *)&reloc;
7226  
7227 +#ifdef CONFIG_PAX_KERNEXEC
7228 +       unsigned long cr0;
7229 +#endif
7230 +
7231         if (call_vrom_func(vmi_rom, vmi_init) != 0) {
7232                 printk(KERN_ERR "VMI ROM failed to initialize!");
7233                 return 0;
7234         }
7235         savesegment(cs, kernel_cs);
7236  
7237 +#ifdef CONFIG_PAX_KERNEXEC
7238 +       pax_open_kernel(cr0);
7239 +#endif
7240 +
7241         pv_info.paravirt_enabled = 1;
7242         pv_info.kernel_rpl = kernel_cs & SEGMENT_RPL_MASK;
7243         pv_info.name = "vmi";
7244 @@ -943,6 +976,10 @@ static inline int __init activate_vmi(vo
7245  
7246         para_fill(pv_irq_ops.safe_halt, Halt);
7247  
7248 +#ifdef CONFIG_PAX_KERNEXEC
7249 +       pax_close_kernel(cr0);
7250 +#endif
7251 +
7252         /*
7253          * Alternative instruction rewriting doesn't happen soon enough
7254          * to convert VMI_IRET to a call instead of a jump; so we have
7255 diff -urNp linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S
7256 --- linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S    2008-11-07 12:55:34.000000000 -0500
7257 +++ linux-2.6.27.10/arch/x86/kernel/vmlinux_32.lds.S    2008-11-18 03:38:44.000000000 -0500
7258 @@ -15,6 +15,20 @@
7259  #include <asm/page.h>
7260  #include <asm/cache.h>
7261  #include <asm/boot.h>
7262 +#include <asm/segment.h>
7263 +
7264 +#ifdef CONFIG_X86_PAE
7265 +#define PMD_SHIFT 21
7266 +#else
7267 +#define PMD_SHIFT 22
7268 +#endif
7269 +#define PMD_SIZE (1 << PMD_SHIFT)
7270 +
7271 +#ifdef CONFIG_PAX_KERNEXEC
7272 +#define __KERNEL_TEXT_OFFSET   (__PAGE_OFFSET + (((____LOAD_PHYSICAL_ADDR + 2*(PMD_SIZE - 1)) - 1) & ~(PMD_SIZE - 1)))
7273 +#else
7274 +#define __KERNEL_TEXT_OFFSET   0
7275 +#endif
7276  
7277  OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
7278  OUTPUT_ARCH(i386)
7279 @@ -22,81 +36,23 @@ ENTRY(phys_startup_32)
7280  jiffies = jiffies_64;
7281  
7282  PHDRS {
7283 -       text PT_LOAD FLAGS(5);  /* R_E */
7284 -       data PT_LOAD FLAGS(7);  /* RWE */
7285 -       note PT_NOTE FLAGS(0);  /* ___ */
7286 +       initdata PT_LOAD FLAGS(6);      /* RW_ */
7287 +       percpu   PT_LOAD FLAGS(6);      /* RW_ */
7288 +       inittext PT_LOAD FLAGS(5);      /* R_E */
7289 +       text     PT_LOAD FLAGS(5);      /* R_E */
7290 +       rodata   PT_LOAD FLAGS(4);      /* R__ */
7291 +       data     PT_LOAD FLAGS(6);      /* RW_ */
7292 +       note     PT_NOTE FLAGS(0);      /* ___ */
7293  }
7294  SECTIONS
7295  {
7296 -  . = LOAD_OFFSET + LOAD_PHYSICAL_ADDR;
7297 -  phys_startup_32 = startup_32 - LOAD_OFFSET;
7298 -
7299 -  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
7300 -       _text = .;                      /* Text and read-only data */
7301 -       *(.text.head)
7302 -  } :text = 0x9090
7303 -
7304 -  /* read-only */
7305 -  .text : AT(ADDR(.text) - LOAD_OFFSET) {
7306 -       . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7307 -       *(.text.page_aligned)
7308 -       TEXT_TEXT
7309 -       SCHED_TEXT
7310 -       LOCK_TEXT
7311 -       KPROBES_TEXT
7312 -       *(.fixup)
7313 -       *(.gnu.warning)
7314 -       _etext = .;                     /* End of text section */
7315 -  } :text = 0x9090
7316 -
7317 -  NOTES :text :note
7318 +  . = LOAD_OFFSET + ____LOAD_PHYSICAL_ADDR;
7319  
7320 -  . = ALIGN(16);               /* Exception table */
7321 -  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7322 -       __start___ex_table = .;
7323 -        *(__ex_table)
7324 -       __stop___ex_table = .;
7325 -  } :text = 0x9090
7326 -
7327 -  RODATA
7328 -
7329 -  /* writeable */
7330 -  . = ALIGN(PAGE_SIZE);
7331 -  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
7332 -       DATA_DATA
7333 -       CONSTRUCTORS
7334 -       } :data
7335 -
7336 -  . = ALIGN(PAGE_SIZE);
7337 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7338 -       __nosave_begin = .;
7339 -       *(.data.nosave)
7340 -       . = ALIGN(PAGE_SIZE);
7341 -       __nosave_end = .;
7342 -  }
7343 -
7344 -  . = ALIGN(PAGE_SIZE);
7345 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7346 -       *(.data.page_aligned)
7347 -       *(.data.idt)
7348 -  }
7349 -
7350 -  . = ALIGN(32);
7351 -  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7352 -       *(.data.cacheline_aligned)
7353 -  }
7354 -
7355 -  /* rarely changed data like cpu maps */
7356 -  . = ALIGN(32);
7357 -  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7358 -       *(.data.read_mostly)
7359 -       _edata = .;             /* End of data section */
7360 -  }
7361 -
7362 -  . = ALIGN(THREAD_SIZE);      /* init_task */
7363 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7364 -       *(.data.init_task)
7365 -  }
7366 +  .text.startup : AT(ADDR(.text.startup) - LOAD_OFFSET) {
7367 +       __LOAD_PHYSICAL_ADDR = . - LOAD_OFFSET;
7368 +       phys_startup_32 = startup_32 - LOAD_OFFSET + __KERNEL_TEXT_OFFSET;
7369 +       *(.text.startup)
7370 +  } :initdata
7371  
7372    /* might get freed after init */
7373    . = ALIGN(PAGE_SIZE);
7374 @@ -114,14 +70,8 @@ SECTIONS
7375    . = ALIGN(PAGE_SIZE);
7376  
7377    /* will be freed after init */
7378 -  . = ALIGN(PAGE_SIZE);                /* Init code and data */
7379 -  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
7380 -       __init_begin = .;
7381 -       _sinittext = .;
7382 -       INIT_TEXT
7383 -       _einittext = .;
7384 -  }
7385    .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
7386 +       __init_begin = .;
7387         INIT_DATA
7388    }
7389    . = ALIGN(16);
7390 @@ -161,11 +111,6 @@ SECTIONS
7391         *(.parainstructions)
7392         __parainstructions_end = .;
7393    }
7394 -  /* .exit.text is discard at runtime, not link time, to deal with references
7395 -     from .altinstructions and .eh_frame */
7396 -  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) {
7397 -       EXIT_TEXT
7398 -  }
7399    .exit.data : AT(ADDR(.exit.data) - LOAD_OFFSET) {
7400         EXIT_DATA
7401    }
7402 @@ -178,17 +123,136 @@ SECTIONS
7403    }
7404  #endif
7405    . = ALIGN(PAGE_SIZE);
7406 -  .data.percpu  : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
7407 -       __per_cpu_start = .;
7408 +  per_cpu_start = .;
7409 +  .data.percpu (0) : AT(ADDR(.data.percpu) - LOAD_OFFSET + per_cpu_start) {
7410 +       __per_cpu_start = . + per_cpu_start;
7411 +       LONG(0)
7412         *(.data.percpu)
7413         *(.data.percpu.shared_aligned)
7414 -       __per_cpu_end = .;
7415 -  }
7416 +       __per_cpu_end = . + per_cpu_start;
7417 +  } :percpu
7418 +  . += per_cpu_start;
7419    . = ALIGN(PAGE_SIZE);
7420    /* freed after init ends here */
7421  
7422 +  . = ALIGN(PAGE_SIZE);                /* Init code and data */
7423 +  .init.text (. - __KERNEL_TEXT_OFFSET) : AT(ADDR(.init.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7424 +       _sinittext = .;
7425 +       INIT_TEXT
7426 +       _einittext = .;
7427 +  } :inittext
7428 +
7429 +  /* .exit.text is discard at runtime, not link time, to deal with references
7430 +     from .altinstructions and .eh_frame */
7431 +  .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7432 +       EXIT_TEXT
7433 +  }
7434 +
7435 +  .filler : AT(ADDR(.filler) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7436 +       BYTE(0)
7437 +       . = ALIGN(2*PMD_SIZE) - 1;
7438 +  }
7439 +
7440 +  /* freed after init ends here */
7441 +
7442 +  .text.head : AT(ADDR(.text.head) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7443 +       __init_end = . + __KERNEL_TEXT_OFFSET;
7444 +       KERNEL_TEXT_OFFSET = . + __KERNEL_TEXT_OFFSET;
7445 +       _text = .;                      /* Text and read-only data */
7446 +       *(.text.head)
7447 +  } :text = 0x9090
7448 +
7449 +  /* read-only */
7450 +  .text : AT(ADDR(.text) - LOAD_OFFSET + __KERNEL_TEXT_OFFSET) {
7451 +       . = ALIGN(PAGE_SIZE); /* not really needed, already page aligned */
7452 +       *(.text.page_aligned)
7453 +       TEXT_TEXT
7454 +       SCHED_TEXT
7455 +       LOCK_TEXT
7456 +       KPROBES_TEXT
7457 +       *(.fixup)
7458 +       *(.gnu.warning)
7459 +       _etext = .;                     /* End of text section */
7460 +  } :text = 0x9090
7461 +
7462 +  . += __KERNEL_TEXT_OFFSET;
7463 +
7464 +  . = ALIGN(4096);             /* Exception table */
7465 +  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
7466 +       __start___ex_table = .;
7467 +        *(__ex_table)
7468 +       __stop___ex_table = .;
7469 +  } :rodata
7470 +
7471 +  NOTES :rodata :note
7472 +
7473 +  RO_DATA(PAGE_SIZE)
7474 +
7475 +  . = ALIGN(PAGE_SIZE);
7476 +  .rodata.page_aligned : AT(ADDR(.rodata.page_aligned) - LOAD_OFFSET) {
7477 +       *(.idt)
7478 +       . = ALIGN(PAGE_SIZE);
7479 +       *(.empty_zero_page)
7480 +       *(.swapper_pg_pmd)
7481 +       *(.swapper_pg_dir)
7482 +       }
7483 +
7484 +#ifdef CONFIG_PAX_KERNEXEC
7485 +
7486 +#ifdef CONFIG_MODULES
7487 +  . = ALIGN(PAGE_SIZE);
7488 +  .module.text : AT(ADDR(.module.text) - LOAD_OFFSET) {
7489 +       MODULES_VADDR = .;
7490 +       BYTE(0)
7491 +       . += (6 * 1024 * 1024);
7492 +       . = ALIGN( PMD_SIZE) - 1;
7493 +       MODULES_END = .;
7494 +  }
7495 +#else
7496 +  . = ALIGN(PMD_SIZE) - 1;
7497 +#endif
7498 +
7499 +#endif
7500 +
7501 +  /* writeable */
7502 +  . = ALIGN(PAGE_SIZE);
7503 +  .data : AT(ADDR(.data) - LOAD_OFFSET) {      /* Data */
7504 +       _data = .;
7505 +       DATA_DATA
7506 +       CONSTRUCTORS
7507 +       } :data
7508 +
7509 +  . = ALIGN(PAGE_SIZE);
7510 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
7511 +       __nosave_begin = .;
7512 +       *(.data.nosave)
7513 +       . = ALIGN(PAGE_SIZE);
7514 +       __nosave_end = .;
7515 +  }
7516 +
7517 +  . = ALIGN(PAGE_SIZE);
7518 +  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7519 +       *(.data.page_aligned)
7520 +  }
7521 +
7522 +  . = ALIGN(32);
7523 +  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7524 +       *(.data.cacheline_aligned)
7525 +  }
7526 +
7527 +  /* rarely changed data like cpu maps */
7528 +  . = ALIGN(32);
7529 +  .data.read_mostly : AT(ADDR(.data.read_mostly) - LOAD_OFFSET) {
7530 +       *(.data.read_mostly)
7531 +       _edata = .;             /* End of data section */
7532 +  }
7533 +
7534 +  . = ALIGN(THREAD_SIZE);      /* init_task */
7535 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7536 +       *(.data.init_task)
7537 +  }
7538 +
7539    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7540 -       __init_end = .;
7541         __bss_start = .;                /* BSS */
7542         *(.bss.page_aligned)
7543         *(.bss)
7544 diff -urNp linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S
7545 --- linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S    2008-11-07 12:55:34.000000000 -0500
7546 +++ linux-2.6.27.10/arch/x86/kernel/vmlinux_64.lds.S    2008-11-18 03:38:44.000000000 -0500
7547 @@ -16,7 +16,7 @@ jiffies_64 = jiffies;
7548  _proxy_pda = 1;
7549  PHDRS {
7550         text PT_LOAD FLAGS(5);  /* R_E */
7551 -       data PT_LOAD FLAGS(7);  /* RWE */
7552 +       data PT_LOAD FLAGS(6);  /* RW_ */
7553         user PT_LOAD FLAGS(7);  /* RWE */
7554         data.init PT_LOAD FLAGS(7);     /* RWE */
7555         note PT_NOTE FLAGS(0);  /* ___ */
7556 @@ -49,17 +49,20 @@ SECTIONS
7557         __stop___ex_table = .;
7558    } :text = 0x9090
7559  
7560 -  RODATA
7561 +  RO_DATA(PAGE_SIZE)
7562  
7563 +#ifdef CONFIG_PAX_KERNEXEC
7564 +  . = ALIGN(2*1024*1024);      /* Align data segment to PMD size boundary */
7565 +#else
7566    . = ALIGN(PAGE_SIZE);                /* Align data segment to page size boundary */
7567 +#endif
7568                                 /* Data */
7569 +  _data = .;
7570    .data : AT(ADDR(.data) - LOAD_OFFSET) {
7571         DATA_DATA
7572         CONSTRUCTORS
7573         } :data
7574  
7575 -  _edata = .;                  /* End of data section */
7576 -
7577    . = ALIGN(PAGE_SIZE);
7578    . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
7579    .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET) {
7580 @@ -70,9 +73,27 @@ SECTIONS
7581         *(.data.read_mostly)
7582    }
7583  
7584 +  . = ALIGN(THREAD_SIZE);      /* init_task */
7585 +  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7586 +       *(.data.init_task)
7587 +  }
7588 +
7589 +  . = ALIGN(PAGE_SIZE);
7590 +  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7591 +       *(.data.page_aligned)
7592 +  }
7593 +
7594 +  . = ALIGN(PAGE_SIZE);
7595 +  __nosave_begin = .;
7596 +  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7597 +  . = ALIGN(PAGE_SIZE);
7598 +  __nosave_end = .;
7599 +
7600 +  _edata = .;                  /* End of data section */
7601 +
7602  #define VSYSCALL_ADDR (-10*1024*1024)
7603 -#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7604 -#define VSYSCALL_VIRT_ADDR ((ADDR(.data.read_mostly) + SIZEOF(.data.read_mostly) + 4095) & ~(4095))
7605 +#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7606 +#define VSYSCALL_VIRT_ADDR ((ADDR(.data_nosave) + SIZEOF(.data_nosave) + 4095) & ~(4095))
7607  
7608  #define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
7609  #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
7610 @@ -120,23 +141,13 @@ SECTIONS
7611  #undef VVIRT_OFFSET
7612  #undef VVIRT
7613  
7614 -  . = ALIGN(THREAD_SIZE);      /* init_task */
7615 -  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET) {
7616 -       *(.data.init_task)
7617 -  }:data.init
7618 -
7619 -  . = ALIGN(PAGE_SIZE);
7620 -  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET) {
7621 -       *(.data.page_aligned)
7622 -  }
7623 -
7624    /* might get freed after init */
7625    . = ALIGN(PAGE_SIZE);
7626    __smp_alt_begin = .;
7627    __smp_locks = .;
7628    .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
7629         *(.smp_locks)
7630 -  }
7631 +  } :data.init
7632    __smp_locks_end = .;
7633    . = ALIGN(PAGE_SIZE);
7634    __smp_alt_end = .;
7635 @@ -213,16 +224,11 @@ SECTIONS
7636    . = ALIGN(PAGE_SIZE);
7637    __init_end = .;
7638  
7639 -  . = ALIGN(PAGE_SIZE);
7640 -  __nosave_begin = .;
7641 -  .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
7642 -  . = ALIGN(PAGE_SIZE);
7643 -  __nosave_end = .;
7644 -
7645    __bss_start = .;             /* BSS */
7646    .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
7647         *(.bss.page_aligned)
7648         *(.bss)
7649 +       . = ALIGN(2*1024*1024);
7650         }
7651    __bss_stop = .;
7652  
7653 diff -urNp linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c
7654 --- linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c       2008-11-07 12:55:34.000000000 -0500
7655 +++ linux-2.6.27.10/arch/x86/kernel/vsyscall_64.c       2008-11-18 03:38:44.000000000 -0500
7656 @@ -236,13 +236,13 @@ static ctl_table kernel_table2[] = {
7657           .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int),
7658           .mode = 0644,
7659           .proc_handler = vsyscall_sysctl_change },
7660 -       {}
7661 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7662  };
7663  
7664  static ctl_table kernel_root_table2[] = {
7665         { .ctl_name = CTL_KERN, .procname = "kernel", .mode = 0555,
7666           .child = kernel_table2 },
7667 -       {}
7668 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
7669  };
7670  #endif
7671  
7672 diff -urNp linux-2.6.27.10/arch/x86/kvm/svm.c linux-2.6.27.10/arch/x86/kvm/svm.c
7673 --- linux-2.6.27.10/arch/x86/kvm/svm.c  2008-11-07 12:55:34.000000000 -0500
7674 +++ linux-2.6.27.10/arch/x86/kvm/svm.c  2008-11-18 03:38:44.000000000 -0500
7675 @@ -1515,7 +1515,19 @@ static void reload_tss(struct kvm_vcpu *
7676         int cpu = raw_smp_processor_id();
7677  
7678         struct svm_cpu_data *svm_data = per_cpu(svm_data, cpu);
7679 +
7680 +#ifdef CONFIG_PAX_KERNEXEC
7681 +       unsigned long cr0;
7682 +
7683 +       pax_open_kernel(cr0);
7684 +#endif
7685 +
7686         svm_data->tss_desc->type = 9; /* available 32/64-bit TSS */
7687 +
7688 +#ifdef CONFIG_PAX_KERNEXEC
7689 +       pax_close_kernel(cr0);
7690 +#endif
7691 +
7692         load_TR_desc();
7693  }
7694  
7695 diff -urNp linux-2.6.27.10/arch/x86/kvm/vmx.c linux-2.6.27.10/arch/x86/kvm/vmx.c
7696 --- linux-2.6.27.10/arch/x86/kvm/vmx.c  2008-11-07 12:55:34.000000000 -0500
7697 +++ linux-2.6.27.10/arch/x86/kvm/vmx.c  2008-11-18 03:38:44.000000000 -0500
7698 @@ -115,7 +115,7 @@ static struct vmcs_config {
7699         u32 vmentry_ctrl;
7700  } vmcs_config;
7701  
7702 -struct vmx_capability {
7703 +static struct vmx_capability {
7704         u32 ept;
7705         u32 vpid;
7706  } vmx_capability;
7707 @@ -484,9 +484,23 @@ static void reload_tss(void)
7708         struct descriptor_table gdt;
7709         struct desc_struct *descs;
7710  
7711 +#ifdef CONFIG_PAX_KERNEXEC
7712 +       unsigned long cr0;
7713 +#endif
7714 +
7715         kvm_get_gdt(&gdt);
7716         descs = (void *)gdt.base;
7717 +
7718 +#ifdef CONFIG_PAX_KERNEXEC
7719 +       pax_open_kernel(cr0);
7720 +#endif
7721 +
7722         descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
7723 +
7724 +#ifdef CONFIG_PAX_KERNEXEC
7725 +       pax_close_kernel(cr0);
7726 +#endif
7727 +
7728         load_TR_desc();
7729  }
7730  
7731 @@ -3069,7 +3083,7 @@ static void vmx_vcpu_run(struct kvm_vcpu
7732                 (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) &
7733                  (GUEST_INTR_STATE_STI | GUEST_INTR_STATE_MOV_SS)) == 0;
7734  
7735 -       asm("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
7736 +       asm("mov %0, %%ds; mov %0, %%es" : : "r"(__KERNEL_DS));
7737         vmx->launched = 1;
7738  
7739         intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
7740 diff -urNp linux-2.6.27.10/arch/x86/kvm/x86.c linux-2.6.27.10/arch/x86/kvm/x86.c
7741 --- linux-2.6.27.10/arch/x86/kvm/x86.c  2008-11-07 12:55:34.000000000 -0500
7742 +++ linux-2.6.27.10/arch/x86/kvm/x86.c  2008-11-18 03:38:44.000000000 -0500
7743 @@ -63,35 +63,35 @@ static int kvm_dev_ioctl_get_supported_c
7744  struct kvm_x86_ops *kvm_x86_ops;
7745  
7746  struct kvm_stats_debugfs_item debugfs_entries[] = {
7747 -       { "pf_fixed", VCPU_STAT(pf_fixed) },
7748 -       { "pf_guest", VCPU_STAT(pf_guest) },
7749 -       { "tlb_flush", VCPU_STAT(tlb_flush) },
7750 -       { "invlpg", VCPU_STAT(invlpg) },
7751 -       { "exits", VCPU_STAT(exits) },
7752 -       { "io_exits", VCPU_STAT(io_exits) },
7753 -       { "mmio_exits", VCPU_STAT(mmio_exits) },
7754 -       { "signal_exits", VCPU_STAT(signal_exits) },
7755 -       { "irq_window", VCPU_STAT(irq_window_exits) },
7756 -       { "nmi_window", VCPU_STAT(nmi_window_exits) },
7757 -       { "halt_exits", VCPU_STAT(halt_exits) },
7758 -       { "halt_wakeup", VCPU_STAT(halt_wakeup) },
7759 -       { "hypercalls", VCPU_STAT(hypercalls) },
7760 -       { "request_irq", VCPU_STAT(request_irq_exits) },
7761 -       { "irq_exits", VCPU_STAT(irq_exits) },
7762 -       { "host_state_reload", VCPU_STAT(host_state_reload) },
7763 -       { "efer_reload", VCPU_STAT(efer_reload) },
7764 -       { "fpu_reload", VCPU_STAT(fpu_reload) },
7765 -       { "insn_emulation", VCPU_STAT(insn_emulation) },
7766 -       { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail) },
7767 -       { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped) },
7768 -       { "mmu_pte_write", VM_STAT(mmu_pte_write) },
7769 -       { "mmu_pte_updated", VM_STAT(mmu_pte_updated) },
7770 -       { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped) },
7771 -       { "mmu_flooded", VM_STAT(mmu_flooded) },
7772 -       { "mmu_recycled", VM_STAT(mmu_recycled) },
7773 -       { "mmu_cache_miss", VM_STAT(mmu_cache_miss) },
7774 -       { "remote_tlb_flush", VM_STAT(remote_tlb_flush) },
7775 -       { "largepages", VM_STAT(lpages) },
7776 +       { "pf_fixed", VCPU_STAT(pf_fixed), NULL },
7777 +       { "pf_guest", VCPU_STAT(pf_guest), NULL },
7778 +       { "tlb_flush", VCPU_STAT(tlb_flush), NULL },
7779 +       { "invlpg", VCPU_STAT(invlpg), NULL },
7780 +       { "exits", VCPU_STAT(exits), NULL },
7781 +       { "io_exits", VCPU_STAT(io_exits), NULL },
7782 +       { "mmio_exits", VCPU_STAT(mmio_exits), NULL },
7783 +       { "signal_exits", VCPU_STAT(signal_exits), NULL },
7784 +       { "irq_window", VCPU_STAT(irq_window_exits), NULL },
7785 +       { "nmi_window", VCPU_STAT(nmi_window_exits), NULL },
7786 +       { "halt_exits", VCPU_STAT(halt_exits), NULL },
7787 +       { "halt_wakeup", VCPU_STAT(halt_wakeup), NULL },
7788 +       { "hypercalls", VCPU_STAT(hypercalls), NULL },
7789 +       { "request_irq", VCPU_STAT(request_irq_exits), NULL },
7790 +       { "irq_exits", VCPU_STAT(irq_exits), NULL },
7791 +       { "host_state_reload", VCPU_STAT(host_state_reload), NULL },
7792 +       { "efer_reload", VCPU_STAT(efer_reload), NULL },
7793 +       { "fpu_reload", VCPU_STAT(fpu_reload), NULL },
7794 +       { "insn_emulation", VCPU_STAT(insn_emulation), NULL },
7795 +       { "insn_emulation_fail", VCPU_STAT(insn_emulation_fail), NULL },
7796 +       { "mmu_shadow_zapped", VM_STAT(mmu_shadow_zapped), NULL },
7797 +       { "mmu_pte_write", VM_STAT(mmu_pte_write), NULL },
7798 +       { "mmu_pte_updated", VM_STAT(mmu_pte_updated), NULL },
7799 +       { "mmu_pde_zapped", VM_STAT(mmu_pde_zapped), NULL },
7800 +       { "mmu_flooded", VM_STAT(mmu_flooded), NULL },
7801 +       { "mmu_recycled", VM_STAT(mmu_recycled), NULL },
7802 +       { "mmu_cache_miss", VM_STAT(mmu_cache_miss), NULL },
7803 +       { "remote_tlb_flush", VM_STAT(remote_tlb_flush), NULL },
7804 +       { "largepages", VM_STAT(lpages), NULL },
7805         { NULL }
7806  };
7807  
7808 @@ -1274,7 +1274,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
7809  static int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu,
7810                                     struct kvm_interrupt *irq)
7811  {
7812 -       if (irq->irq < 0 || irq->irq >= 256)
7813 +       if (irq->irq >= 256)
7814                 return -EINVAL;
7815         if (irqchip_in_kernel(vcpu->kvm))
7816                 return -ENXIO;
7817 diff -urNp linux-2.6.27.10/arch/x86/lib/checksum_32.S linux-2.6.27.10/arch/x86/lib/checksum_32.S
7818 --- linux-2.6.27.10/arch/x86/lib/checksum_32.S  2008-11-07 12:55:34.000000000 -0500
7819 +++ linux-2.6.27.10/arch/x86/lib/checksum_32.S  2008-11-18 03:38:44.000000000 -0500
7820 @@ -28,7 +28,8 @@
7821  #include <linux/linkage.h>
7822  #include <asm/dwarf2.h>
7823  #include <asm/errno.h>
7824 -                               
7825 +#include <asm/segment.h>
7826 +
7827  /*
7828   * computes a partial checksum, e.g. for TCP/UDP fragments
7829   */
7830 @@ -304,9 +305,22 @@ unsigned int csum_partial_copy_generic (
7831  
7832  #define ARGBASE 16             
7833  #define FP             12
7834 -               
7835 -ENTRY(csum_partial_copy_generic)
7836 +
7837 +ENTRY(csum_partial_copy_generic_to_user)
7838         CFI_STARTPROC
7839 +       pushl $(__USER_DS)
7840 +       CFI_ADJUST_CFA_OFFSET 4
7841 +       popl %es
7842 +       CFI_ADJUST_CFA_OFFSET -4
7843 +       jmp csum_partial_copy_generic
7844 +
7845 +ENTRY(csum_partial_copy_generic_from_user)
7846 +       pushl $(__USER_DS)
7847 +       CFI_ADJUST_CFA_OFFSET 4
7848 +       popl %ds
7849 +       CFI_ADJUST_CFA_OFFSET -4
7850 +
7851 +ENTRY(csum_partial_copy_generic)
7852         subl  $4,%esp   
7853         CFI_ADJUST_CFA_OFFSET 4
7854         pushl %edi
7855 @@ -331,7 +345,7 @@ ENTRY(csum_partial_copy_generic)
7856         jmp 4f
7857  SRC(1: movw (%esi), %bx        )
7858         addl $2, %esi
7859 -DST(   movw %bx, (%edi)        )
7860 +DST(   movw %bx, %es:(%edi)    )
7861         addl $2, %edi
7862         addw %bx, %ax   
7863         adcl $0, %eax
7864 @@ -343,30 +357,30 @@ DST(      movw %bx, (%edi)        )
7865  SRC(1: movl (%esi), %ebx       )
7866  SRC(   movl 4(%esi), %edx      )
7867         adcl %ebx, %eax
7868 -DST(   movl %ebx, (%edi)       )
7869 +DST(   movl %ebx, %es:(%edi)   )
7870         adcl %edx, %eax
7871 -DST(   movl %edx, 4(%edi)      )
7872 +DST(   movl %edx, %es:4(%edi)  )
7873  
7874  SRC(   movl 8(%esi), %ebx      )
7875  SRC(   movl 12(%esi), %edx     )
7876         adcl %ebx, %eax
7877 -DST(   movl %ebx, 8(%edi)      )
7878 +DST(   movl %ebx, %es:8(%edi)  )
7879         adcl %edx, %eax
7880 -DST(   movl %edx, 12(%edi)     )
7881 +DST(   movl %edx, %es:12(%edi) )
7882  
7883  SRC(   movl 16(%esi), %ebx     )
7884  SRC(   movl 20(%esi), %edx     )
7885         adcl %ebx, %eax
7886 -DST(   movl %ebx, 16(%edi)     )
7887 +DST(   movl %ebx, %es:16(%edi) )
7888         adcl %edx, %eax
7889 -DST(   movl %edx, 20(%edi)     )
7890 +DST(   movl %edx, %es:20(%edi) )
7891  
7892  SRC(   movl 24(%esi), %ebx     )
7893  SRC(   movl 28(%esi), %edx     )
7894         adcl %ebx, %eax
7895 -DST(   movl %ebx, 24(%edi)     )
7896 +DST(   movl %ebx, %es:24(%edi) )
7897         adcl %edx, %eax
7898 -DST(   movl %edx, 28(%edi)     )
7899 +DST(   movl %edx, %es:28(%edi) )
7900  
7901         lea 32(%esi), %esi
7902         lea 32(%edi), %edi
7903 @@ -380,7 +394,7 @@ DST(        movl %edx, 28(%edi)     )
7904         shrl $2, %edx                   # This clears CF
7905  SRC(3: movl (%esi), %ebx       )
7906         adcl %ebx, %eax
7907 -DST(   movl %ebx, (%edi)       )
7908 +DST(   movl %ebx, %es:(%edi)   )
7909         lea 4(%esi), %esi
7910         lea 4(%edi), %edi
7911         dec %edx
7912 @@ -392,12 +406,12 @@ DST(      movl %ebx, (%edi)       )
7913         jb 5f
7914  SRC(   movw (%esi), %cx        )
7915         leal 2(%esi), %esi
7916 -DST(   movw %cx, (%edi)        )
7917 +DST(   movw %cx, %es:(%edi)    )
7918         leal 2(%edi), %edi
7919         je 6f
7920         shll $16,%ecx
7921  SRC(5: movb (%esi), %cl        )
7922 -DST(   movb %cl, (%edi)        )
7923 +DST(   movb %cl, %es:(%edi)    )
7924  6:     addl %ecx, %eax
7925         adcl $0, %eax
7926  7:
7927 @@ -408,7 +422,7 @@ DST(        movb %cl, (%edi)        )
7928  
7929  6001:
7930         movl ARGBASE+20(%esp), %ebx     # src_err_ptr
7931 -       movl $-EFAULT, (%ebx)
7932 +       movl $-EFAULT, %ss:(%ebx)
7933  
7934         # zero the complete destination - computing the rest
7935         # is too much work 
7936 @@ -421,11 +435,19 @@ DST(      movb %cl, (%edi)        )
7937  
7938  6002:
7939         movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
7940 -       movl $-EFAULT,(%ebx)
7941 +       movl $-EFAULT,%ss:(%ebx)
7942         jmp 5000b
7943  
7944  .previous
7945  
7946 +       pushl %ss
7947 +       CFI_ADJUST_CFA_OFFSET 4
7948 +       popl %ds
7949 +       CFI_ADJUST_CFA_OFFSET -4
7950 +       pushl %ss
7951 +       CFI_ADJUST_CFA_OFFSET 4
7952 +       popl %es
7953 +       CFI_ADJUST_CFA_OFFSET -4
7954         popl %ebx
7955         CFI_ADJUST_CFA_OFFSET -4
7956         CFI_RESTORE ebx
7957 @@ -439,26 +461,41 @@ DST(      movb %cl, (%edi)        )
7958         CFI_ADJUST_CFA_OFFSET -4
7959         ret     
7960         CFI_ENDPROC
7961 -ENDPROC(csum_partial_copy_generic)
7962 +ENDPROC(csum_partial_copy_generic_to_user)
7963  
7964  #else
7965  
7966  /* Version for PentiumII/PPro */
7967  
7968  #define ROUND1(x) \
7969 +       nop; nop; nop;                          \
7970         SRC(movl x(%esi), %ebx  )       ;       \
7971         addl %ebx, %eax                 ;       \
7972 -       DST(movl %ebx, x(%edi)  )       ; 
7973 +       DST(movl %ebx, %es:x(%edi))     ;
7974  
7975  #define ROUND(x) \
7976 +       nop; nop; nop;                          \
7977         SRC(movl x(%esi), %ebx  )       ;       \
7978         adcl %ebx, %eax                 ;       \
7979 -       DST(movl %ebx, x(%edi)  )       ;
7980 +       DST(movl %ebx, %es:x(%edi))     ;
7981  
7982  #define ARGBASE 12
7983 -               
7984 -ENTRY(csum_partial_copy_generic)
7985 +
7986 +ENTRY(csum_partial_copy_generic_to_user)
7987         CFI_STARTPROC
7988 +       pushl $(__USER_DS)
7989 +       CFI_ADJUST_CFA_OFFSET 4
7990 +       popl %es
7991 +       CFI_ADJUST_CFA_OFFSET -4
7992 +       jmp csum_partial_copy_generic
7993 +
7994 +ENTRY(csum_partial_copy_generic_from_user)
7995 +       pushl $(__USER_DS)
7996 +       CFI_ADJUST_CFA_OFFSET 4
7997 +       popl %ds
7998 +       CFI_ADJUST_CFA_OFFSET -4
7999 +
8000 +ENTRY(csum_partial_copy_generic)
8001         pushl %ebx
8002         CFI_ADJUST_CFA_OFFSET 4
8003         CFI_REL_OFFSET ebx, 0
8004 @@ -482,7 +519,7 @@ ENTRY(csum_partial_copy_generic)
8005         subl %ebx, %edi  
8006         lea  -1(%esi),%edx
8007         andl $-32,%edx
8008 -       lea 3f(%ebx,%ebx), %ebx
8009 +       lea 3f(%ebx,%ebx,2), %ebx
8010         testl %esi, %esi 
8011         jmp *%ebx
8012  1:     addl $64,%esi
8013 @@ -503,19 +540,19 @@ ENTRY(csum_partial_copy_generic)
8014         jb 5f
8015  SRC(   movw (%esi), %dx         )
8016         leal 2(%esi), %esi
8017 -DST(   movw %dx, (%edi)         )
8018 +DST(   movw %dx, %es:(%edi)     )
8019         leal 2(%edi), %edi
8020         je 6f
8021         shll $16,%edx
8022  5:
8023  SRC(   movb (%esi), %dl         )
8024 -DST(   movb %dl, (%edi)         )
8025 +DST(   movb %dl, %es:(%edi)     )
8026  6:     addl %edx, %eax
8027         adcl $0, %eax
8028  7:
8029  .section .fixup, "ax"
8030  6001:  movl    ARGBASE+20(%esp), %ebx  # src_err_ptr   
8031 -       movl $-EFAULT, (%ebx)
8032 +       movl $-EFAULT, %ss:(%ebx)
8033         # zero the complete destination (computing the rest is too much work)
8034         movl ARGBASE+8(%esp),%edi       # dst
8035         movl ARGBASE+12(%esp),%ecx      # len
8036 @@ -523,10 +560,18 @@ DST(      movb %dl, (%edi)         )
8037         rep; stosb
8038         jmp 7b
8039  6002:  movl ARGBASE+24(%esp), %ebx     # dst_err_ptr
8040 -       movl $-EFAULT, (%ebx)
8041 +       movl $-EFAULT, %ss:(%ebx)
8042         jmp  7b                 
8043  .previous                              
8044  
8045 +       pushl %ss
8046 +       CFI_ADJUST_CFA_OFFSET 4
8047 +       popl %ds
8048 +       CFI_ADJUST_CFA_OFFSET -4
8049 +       pushl %ss
8050 +       CFI_ADJUST_CFA_OFFSET 4
8051 +       popl %es
8052 +       CFI_ADJUST_CFA_OFFSET -4
8053         popl %esi
8054         CFI_ADJUST_CFA_OFFSET -4
8055         CFI_RESTORE esi
8056 @@ -538,7 +583,7 @@ DST(        movb %dl, (%edi)         )
8057         CFI_RESTORE ebx
8058         ret
8059         CFI_ENDPROC
8060 -ENDPROC(csum_partial_copy_generic)
8061 +ENDPROC(csum_partial_copy_generic_to_user)
8062                                 
8063  #undef ROUND
8064  #undef ROUND1          
8065 diff -urNp linux-2.6.27.10/arch/x86/lib/clear_page_64.S linux-2.6.27.10/arch/x86/lib/clear_page_64.S
8066 --- linux-2.6.27.10/arch/x86/lib/clear_page_64.S        2008-11-07 12:55:34.000000000 -0500
8067 +++ linux-2.6.27.10/arch/x86/lib/clear_page_64.S        2008-11-18 03:38:44.000000000 -0500
8068 @@ -44,7 +44,7 @@ ENDPROC(clear_page)
8069  
8070  #include <asm/cpufeature.h>
8071  
8072 -       .section .altinstr_replacement,"ax"
8073 +       .section .altinstr_replacement,"a"
8074  1:     .byte 0xeb                                      /* jmp <disp8> */
8075         .byte (clear_page_c - clear_page) - (2f - 1b)   /* offset */
8076  2:
8077 diff -urNp linux-2.6.27.10/arch/x86/lib/copy_page_64.S linux-2.6.27.10/arch/x86/lib/copy_page_64.S
8078 --- linux-2.6.27.10/arch/x86/lib/copy_page_64.S 2008-11-07 12:55:34.000000000 -0500
8079 +++ linux-2.6.27.10/arch/x86/lib/copy_page_64.S 2008-11-18 03:38:44.000000000 -0500
8080 @@ -104,7 +104,7 @@ ENDPROC(copy_page)
8081  
8082  #include <asm/cpufeature.h>
8083  
8084 -       .section .altinstr_replacement,"ax"
8085 +       .section .altinstr_replacement,"a"
8086  1:     .byte 0xeb                                      /* jmp <disp8> */
8087         .byte (copy_page_c - copy_page) - (2f - 1b)     /* offset */
8088  2:
8089 diff -urNp linux-2.6.27.10/arch/x86/lib/copy_user_64.S linux-2.6.27.10/arch/x86/lib/copy_user_64.S
8090 --- linux-2.6.27.10/arch/x86/lib/copy_user_64.S 2008-11-07 12:55:34.000000000 -0500
8091 +++ linux-2.6.27.10/arch/x86/lib/copy_user_64.S 2008-11-18 03:38:44.000000000 -0500
8092 @@ -21,7 +21,7 @@
8093         .byte 0xe9      /* 32bit jump */
8094         .long \orig-1f  /* by default jump to orig */
8095  1:
8096 -       .section .altinstr_replacement,"ax"
8097 +       .section .altinstr_replacement,"a"
8098  2:     .byte 0xe9                      /* near jump with 32bit immediate */
8099         .long \alt-1b /* offset */   /* or alternatively to alt */
8100         .previous
8101 @@ -106,6 +106,8 @@ ENDPROC(__copy_from_user_inatomic)
8102  ENTRY(bad_from_user)
8103  bad_from_user:
8104         CFI_STARTPROC
8105 +       testl %edx,%edx
8106 +       js bad_to_user
8107         movl %edx,%ecx
8108         xorl %eax,%eax
8109         rep
8110 diff -urNp linux-2.6.27.10/arch/x86/lib/getuser.S linux-2.6.27.10/arch/x86/lib/getuser.S
8111 --- linux-2.6.27.10/arch/x86/lib/getuser.S      2008-11-07 12:55:34.000000000 -0500
8112 +++ linux-2.6.27.10/arch/x86/lib/getuser.S      2008-11-18 03:38:44.000000000 -0500
8113 @@ -33,6 +33,7 @@
8114  #include <asm/asm-offsets.h>
8115  #include <asm/thread_info.h>
8116  #include <asm/asm.h>
8117 +#include <asm/segment.h>
8118  
8119         .text
8120  ENTRY(__get_user_1)
8121 @@ -40,7 +41,19 @@ ENTRY(__get_user_1)
8122         GET_THREAD_INFO(%_ASM_DX)
8123         cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8124         jae bad_get_user
8125 +
8126 +#ifdef CONFIG_X86_32
8127 +       pushl $(__USER_DS)
8128 +       popl %ds
8129 +#endif
8130 +
8131  1:     movzb (%_ASM_AX),%edx
8132 +
8133 +#ifdef CONFIG_X86_32
8134 +       pushl %ss
8135 +       pop %ds
8136 +#endif
8137 +
8138         xor %eax,%eax
8139         ret
8140         CFI_ENDPROC
8141 @@ -53,7 +66,19 @@ ENTRY(__get_user_2)
8142         GET_THREAD_INFO(%_ASM_DX)
8143         cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8144         jae bad_get_user
8145 +
8146 +#ifdef CONFIG_X86_32
8147 +       pushl $(__USER_DS)
8148 +       popl %ds
8149 +#endif
8150 +
8151  2:     movzwl -1(%_ASM_AX),%edx
8152 +
8153 +#ifdef CONFIG_X86_32
8154 +       pushl %ss
8155 +       pop %ds
8156 +#endif
8157 +
8158         xor %eax,%eax
8159         ret
8160         CFI_ENDPROC
8161 @@ -66,7 +91,19 @@ ENTRY(__get_user_4)
8162         GET_THREAD_INFO(%_ASM_DX)
8163         cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
8164         jae bad_get_user
8165 +
8166 +#ifdef CONFIG_X86_32
8167 +       pushl $(__USER_DS)
8168 +       popl %ds
8169 +#endif
8170 +
8171  3:     mov -3(%_ASM_AX),%edx
8172 +
8173 +#ifdef CONFIG_X86_32
8174 +       pushl %ss
8175 +       pop %ds
8176 +#endif
8177 +
8178         xor %eax,%eax
8179         ret
8180         CFI_ENDPROC
8181 @@ -89,6 +126,12 @@ ENDPROC(__get_user_8)
8182  
8183  bad_get_user:
8184         CFI_STARTPROC
8185 +
8186 +#ifdef CONFIG_X86_32
8187 +       pushl %ss
8188 +       pop %ds
8189 +#endif
8190 +
8191         xor %edx,%edx
8192         mov $(-EFAULT),%_ASM_AX
8193         ret
8194 diff -urNp linux-2.6.27.10/arch/x86/lib/memcpy_64.S linux-2.6.27.10/arch/x86/lib/memcpy_64.S
8195 --- linux-2.6.27.10/arch/x86/lib/memcpy_64.S    2008-11-07 12:55:34.000000000 -0500
8196 +++ linux-2.6.27.10/arch/x86/lib/memcpy_64.S    2008-11-18 03:38:44.000000000 -0500
8197 @@ -114,7 +114,7 @@ ENDPROC(__memcpy)
8198         /* Some CPUs run faster using the string copy instructions.
8199            It is also a lot simpler. Use this when possible */
8200  
8201 -       .section .altinstr_replacement,"ax"
8202 +       .section .altinstr_replacement,"a"
8203  1:     .byte 0xeb                              /* jmp <disp8> */
8204         .byte (memcpy_c - memcpy) - (2f - 1b)   /* offset */
8205  2:
8206 diff -urNp linux-2.6.27.10/arch/x86/lib/memset_64.S linux-2.6.27.10/arch/x86/lib/memset_64.S
8207 --- linux-2.6.27.10/arch/x86/lib/memset_64.S    2008-11-07 12:55:34.000000000 -0500
8208 +++ linux-2.6.27.10/arch/x86/lib/memset_64.S    2008-11-18 03:38:44.000000000 -0500
8209 @@ -118,7 +118,7 @@ ENDPROC(__memset)
8210  
8211  #include <asm/cpufeature.h>
8212  
8213 -       .section .altinstr_replacement,"ax"
8214 +       .section .altinstr_replacement,"a"
8215  1:     .byte 0xeb                              /* jmp <disp8> */
8216         .byte (memset_c - memset) - (2f - 1b)   /* offset */
8217  2:
8218 diff -urNp linux-2.6.27.10/arch/x86/lib/mmx_32.c linux-2.6.27.10/arch/x86/lib/mmx_32.c
8219 --- linux-2.6.27.10/arch/x86/lib/mmx_32.c       2008-11-07 12:55:34.000000000 -0500
8220 +++ linux-2.6.27.10/arch/x86/lib/mmx_32.c       2008-11-18 03:38:44.000000000 -0500
8221 @@ -29,6 +29,7 @@ void *_mmx_memcpy(void *to, const void *
8222  {
8223         void *p;
8224         int i;
8225 +       unsigned long cr0;
8226  
8227         if (unlikely(in_interrupt()))
8228                 return __memcpy(to, from, len);
8229 @@ -39,44 +40,72 @@ void *_mmx_memcpy(void *to, const void *
8230         kernel_fpu_begin();
8231  
8232         __asm__ __volatile__ (
8233 -               "1: prefetch (%0)\n"            /* This set is 28 bytes */
8234 -               "   prefetch 64(%0)\n"
8235 -               "   prefetch 128(%0)\n"
8236 -               "   prefetch 192(%0)\n"
8237 -               "   prefetch 256(%0)\n"
8238 +               "1: prefetch (%1)\n"            /* This set is 28 bytes */
8239 +               "   prefetch 64(%1)\n"
8240 +               "   prefetch 128(%1)\n"
8241 +               "   prefetch 192(%1)\n"
8242 +               "   prefetch 256(%1)\n"
8243                 "2:  \n"
8244                 ".section .fixup, \"ax\"\n"
8245 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8246 +               "3:  \n"
8247 +
8248 +#ifdef CONFIG_PAX_KERNEXEC
8249 +               "   movl %%cr0, %0\n"
8250 +               "   movl %0, %%eax\n"
8251 +               "   andl $0xFFFEFFFF, %%eax\n"
8252 +               "   movl %%eax, %%cr0\n"
8253 +#endif
8254 +
8255 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8256 +
8257 +#ifdef CONFIG_PAX_KERNEXEC
8258 +               "   movl %0, %%cr0\n"
8259 +#endif
8260 +
8261                 "   jmp 2b\n"
8262                 ".previous\n"
8263                         _ASM_EXTABLE(1b, 3b)
8264 -                       : : "r" (from));
8265 +                       : "=&r" (cr0) : "r" (from) : "ax");
8266  
8267         for ( ; i > 5; i--) {
8268                 __asm__ __volatile__ (
8269 -               "1:  prefetch 320(%0)\n"
8270 -               "2:  movq (%0), %%mm0\n"
8271 -               "  movq 8(%0), %%mm1\n"
8272 -               "  movq 16(%0), %%mm2\n"
8273 -               "  movq 24(%0), %%mm3\n"
8274 -               "  movq %%mm0, (%1)\n"
8275 -               "  movq %%mm1, 8(%1)\n"
8276 -               "  movq %%mm2, 16(%1)\n"
8277 -               "  movq %%mm3, 24(%1)\n"
8278 -               "  movq 32(%0), %%mm0\n"
8279 -               "  movq 40(%0), %%mm1\n"
8280 -               "  movq 48(%0), %%mm2\n"
8281 -               "  movq 56(%0), %%mm3\n"
8282 -               "  movq %%mm0, 32(%1)\n"
8283 -               "  movq %%mm1, 40(%1)\n"
8284 -               "  movq %%mm2, 48(%1)\n"
8285 -               "  movq %%mm3, 56(%1)\n"
8286 +               "1:  prefetch 320(%1)\n"
8287 +               "2:  movq (%1), %%mm0\n"
8288 +               "  movq 8(%1), %%mm1\n"
8289 +               "  movq 16(%1), %%mm2\n"
8290 +               "  movq 24(%1), %%mm3\n"
8291 +               "  movq %%mm0, (%2)\n"
8292 +               "  movq %%mm1, 8(%2)\n"
8293 +               "  movq %%mm2, 16(%2)\n"
8294 +               "  movq %%mm3, 24(%2)\n"
8295 +               "  movq 32(%1), %%mm0\n"
8296 +               "  movq 40(%1), %%mm1\n"
8297 +               "  movq 48(%1), %%mm2\n"
8298 +               "  movq 56(%1), %%mm3\n"
8299 +               "  movq %%mm0, 32(%2)\n"
8300 +               "  movq %%mm1, 40(%2)\n"
8301 +               "  movq %%mm2, 48(%2)\n"
8302 +               "  movq %%mm3, 56(%2)\n"
8303                 ".section .fixup, \"ax\"\n"
8304 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8305 +               "3:\n"
8306 +
8307 +#ifdef CONFIG_PAX_KERNEXEC
8308 +               "   movl %%cr0, %0\n"
8309 +               "   movl %0, %%eax\n"
8310 +               "   andl $0xFFFEFFFF, %%eax\n"
8311 +               "   movl %%eax, %%cr0\n"
8312 +#endif
8313 +
8314 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8315 +
8316 +#ifdef CONFIG_PAX_KERNEXEC
8317 +               "   movl %0, %%cr0\n"
8318 +#endif
8319 +
8320                 "   jmp 2b\n"
8321                 ".previous\n"
8322                         _ASM_EXTABLE(1b, 3b)
8323 -                       : : "r" (from), "r" (to) : "memory");
8324 +                       : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8325  
8326                 from += 64;
8327                 to += 64;
8328 @@ -158,6 +187,7 @@ static void fast_clear_page(void *page)
8329  static void fast_copy_page(void *to, void *from)
8330  {
8331         int i;
8332 +       unsigned long cr0;
8333  
8334         kernel_fpu_begin();
8335  
8336 @@ -166,42 +196,70 @@ static void fast_copy_page(void *to, voi
8337          * but that is for later. -AV
8338          */
8339         __asm__ __volatile__(
8340 -               "1: prefetch (%0)\n"
8341 -               "   prefetch 64(%0)\n"
8342 -               "   prefetch 128(%0)\n"
8343 -               "   prefetch 192(%0)\n"
8344 -               "   prefetch 256(%0)\n"
8345 +               "1: prefetch (%1)\n"
8346 +               "   prefetch 64(%1)\n"
8347 +               "   prefetch 128(%1)\n"
8348 +               "   prefetch 192(%1)\n"
8349 +               "   prefetch 256(%1)\n"
8350                 "2:  \n"
8351                 ".section .fixup, \"ax\"\n"
8352 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8353 +               "3:  \n"
8354 +
8355 +#ifdef CONFIG_PAX_KERNEXEC
8356 +               "   movl %%cr0, %0\n"
8357 +               "   movl %0, %%eax\n"
8358 +               "   andl $0xFFFEFFFF, %%eax\n"
8359 +               "   movl %%eax, %%cr0\n"
8360 +#endif
8361 +
8362 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8363 +
8364 +#ifdef CONFIG_PAX_KERNEXEC
8365 +               "   movl %0, %%cr0\n"
8366 +#endif
8367 +
8368                 "   jmp 2b\n"
8369                 ".previous\n"
8370 -                       _ASM_EXTABLE(1b, 3b) : : "r" (from));
8371 +                       _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8372  
8373         for (i = 0; i < (4096-320)/64; i++) {
8374                 __asm__ __volatile__ (
8375 -               "1: prefetch 320(%0)\n"
8376 -               "2: movq (%0), %%mm0\n"
8377 -               "   movntq %%mm0, (%1)\n"
8378 -               "   movq 8(%0), %%mm1\n"
8379 -               "   movntq %%mm1, 8(%1)\n"
8380 -               "   movq 16(%0), %%mm2\n"
8381 -               "   movntq %%mm2, 16(%1)\n"
8382 -               "   movq 24(%0), %%mm3\n"
8383 -               "   movntq %%mm3, 24(%1)\n"
8384 -               "   movq 32(%0), %%mm4\n"
8385 -               "   movntq %%mm4, 32(%1)\n"
8386 -               "   movq 40(%0), %%mm5\n"
8387 -               "   movntq %%mm5, 40(%1)\n"
8388 -               "   movq 48(%0), %%mm6\n"
8389 -               "   movntq %%mm6, 48(%1)\n"
8390 -               "   movq 56(%0), %%mm7\n"
8391 -               "   movntq %%mm7, 56(%1)\n"
8392 +               "1: prefetch 320(%1)\n"
8393 +               "2: movq (%1), %%mm0\n"
8394 +               "   movntq %%mm0, (%2)\n"
8395 +               "   movq 8(%1), %%mm1\n"
8396 +               "   movntq %%mm1, 8(%2)\n"
8397 +               "   movq 16(%1), %%mm2\n"
8398 +               "   movntq %%mm2, 16(%2)\n"
8399 +               "   movq 24(%1), %%mm3\n"
8400 +               "   movntq %%mm3, 24(%2)\n"
8401 +               "   movq 32(%1), %%mm4\n"
8402 +               "   movntq %%mm4, 32(%2)\n"
8403 +               "   movq 40(%1), %%mm5\n"
8404 +               "   movntq %%mm5, 40(%2)\n"
8405 +               "   movq 48(%1), %%mm6\n"
8406 +               "   movntq %%mm6, 48(%2)\n"
8407 +               "   movq 56(%1), %%mm7\n"
8408 +               "   movntq %%mm7, 56(%2)\n"
8409                 ".section .fixup, \"ax\"\n"
8410 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8411 +               "3:\n"
8412 +
8413 +#ifdef CONFIG_PAX_KERNEXEC
8414 +               "   movl %%cr0, %0\n"
8415 +               "   movl %0, %%eax\n"
8416 +               "   andl $0xFFFEFFFF, %%eax\n"
8417 +               "   movl %%eax, %%cr0\n"
8418 +#endif
8419 +
8420 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8421 +
8422 +#ifdef CONFIG_PAX_KERNEXEC
8423 +               "   movl %0, %%cr0\n"
8424 +#endif
8425 +
8426                 "   jmp 2b\n"
8427                 ".previous\n"
8428 -               _ASM_EXTABLE(1b, 3b) : : "r" (from), "r" (to) : "memory");
8429 +               _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8430  
8431                 from += 64;
8432                 to += 64;
8433 @@ -280,47 +338,76 @@ static void fast_clear_page(void *page)
8434  static void fast_copy_page(void *to, void *from)
8435  {
8436         int i;
8437 +       unsigned long cr0;
8438  
8439         kernel_fpu_begin();
8440  
8441         __asm__ __volatile__ (
8442 -               "1: prefetch (%0)\n"
8443 -               "   prefetch 64(%0)\n"
8444 -               "   prefetch 128(%0)\n"
8445 -               "   prefetch 192(%0)\n"
8446 -               "   prefetch 256(%0)\n"
8447 +               "1: prefetch (%1)\n"
8448 +               "   prefetch 64(%1)\n"
8449 +               "   prefetch 128(%1)\n"
8450 +               "   prefetch 192(%1)\n"
8451 +               "   prefetch 256(%1)\n"
8452                 "2:  \n"
8453                 ".section .fixup, \"ax\"\n"
8454 -               "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8455 +               "3:  \n"
8456 +
8457 +#ifdef CONFIG_PAX_KERNEXEC
8458 +               "   movl %%cr0, %0\n"
8459 +               "   movl %0, %%eax\n"
8460 +               "   andl $0xFFFEFFFF, %%eax\n"
8461 +               "   movl %%eax, %%cr0\n"
8462 +#endif
8463 +
8464 +               "   movw $0x1AEB, 1b\n" /* jmp on 26 bytes */
8465 +
8466 +#ifdef CONFIG_PAX_KERNEXEC
8467 +               "   movl %0, %%cr0\n"
8468 +#endif
8469 +
8470                 "   jmp 2b\n"
8471                 ".previous\n"
8472 -                       _ASM_EXTABLE(1b, 3b) : : "r" (from));
8473 +                       _ASM_EXTABLE(1b, 3b) : "=&r" (cr0) : "r" (from) : "ax");
8474  
8475         for (i = 0; i < 4096/64; i++) {
8476                 __asm__ __volatile__ (
8477 -               "1: prefetch 320(%0)\n"
8478 -               "2: movq (%0), %%mm0\n"
8479 -               "   movq 8(%0), %%mm1\n"
8480 -               "   movq 16(%0), %%mm2\n"
8481 -               "   movq 24(%0), %%mm3\n"
8482 -               "   movq %%mm0, (%1)\n"
8483 -               "   movq %%mm1, 8(%1)\n"
8484 -               "   movq %%mm2, 16(%1)\n"
8485 -               "   movq %%mm3, 24(%1)\n"
8486 -               "   movq 32(%0), %%mm0\n"
8487 -               "   movq 40(%0), %%mm1\n"
8488 -               "   movq 48(%0), %%mm2\n"
8489 -               "   movq 56(%0), %%mm3\n"
8490 -               "   movq %%mm0, 32(%1)\n"
8491 -               "   movq %%mm1, 40(%1)\n"
8492 -               "   movq %%mm2, 48(%1)\n"
8493 -               "   movq %%mm3, 56(%1)\n"
8494 +               "1: prefetch 320(%1)\n"
8495 +               "2: movq (%1), %%mm0\n"
8496 +               "   movq 8(%1), %%mm1\n"
8497 +               "   movq 16(%1), %%mm2\n"
8498 +               "   movq 24(%1), %%mm3\n"
8499 +               "   movq %%mm0, (%2)\n"
8500 +               "   movq %%mm1, 8(%2)\n"
8501 +               "   movq %%mm2, 16(%2)\n"
8502 +               "   movq %%mm3, 24(%2)\n"
8503 +               "   movq 32(%1), %%mm0\n"
8504 +               "   movq 40(%1), %%mm1\n"
8505 +               "   movq 48(%1), %%mm2\n"
8506 +               "   movq 56(%1), %%mm3\n"
8507 +               "   movq %%mm0, 32(%2)\n"
8508 +               "   movq %%mm1, 40(%2)\n"
8509 +               "   movq %%mm2, 48(%2)\n"
8510 +               "   movq %%mm3, 56(%2)\n"
8511                 ".section .fixup, \"ax\"\n"
8512 -               "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8513 +               "3:\n"
8514 +
8515 +#ifdef CONFIG_PAX_KERNEXEC
8516 +               "   movl %%cr0, %0\n"
8517 +               "   movl %0, %%eax\n"
8518 +               "   andl $0xFFFEFFFF, %%eax\n"
8519 +               "   movl %%eax, %%cr0\n"
8520 +#endif
8521 +
8522 +               "   movw $0x05EB, 1b\n" /* jmp on 5 bytes */
8523 +
8524 +#ifdef CONFIG_PAX_KERNEXEC
8525 +               "   movl %0, %%cr0\n"
8526 +#endif
8527 +
8528                 "   jmp 2b\n"
8529                 ".previous\n"
8530                         _ASM_EXTABLE(1b, 3b)
8531 -                       : : "r" (from), "r" (to) : "memory");
8532 +                       : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax");
8533  
8534                 from += 64;
8535                 to += 64;
8536 diff -urNp linux-2.6.27.10/arch/x86/lib/putuser.S linux-2.6.27.10/arch/x86/lib/putuser.S
8537 --- linux-2.6.27.10/arch/x86/lib/putuser.S      2008-11-07 12:55:34.000000000 -0500
8538 +++ linux-2.6.27.10/arch/x86/lib/putuser.S      2008-11-18 03:38:44.000000000 -0500
8539 @@ -15,6 +15,7 @@
8540  #include <asm/thread_info.h>
8541  #include <asm/errno.h>
8542  #include <asm/asm.h>
8543 +#include <asm/segment.h>
8544  
8545  
8546  /*
8547 @@ -39,7 +40,19 @@ ENTRY(__put_user_1)
8548         ENTER
8549         cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
8550         jae bad_put_user
8551 +
8552 +#ifdef CONFIG_X86_32
8553 +       pushl $(__USER_DS)
8554 +       popl %ds
8555 +#endif
8556 +
8557  1:     movb %al,(%_ASM_CX)
8558 +
8559 +#ifdef CONFIG_X86_32
8560 +       pushl %ss
8561 +       popl %ds
8562 +#endif
8563 +
8564         xor %eax,%eax
8565         EXIT
8566  ENDPROC(__put_user_1)
8567 @@ -50,7 +63,19 @@ ENTRY(__put_user_2)
8568         sub $1,%_ASM_BX
8569         cmp %_ASM_BX,%_ASM_CX
8570         jae bad_put_user
8571 +
8572 +#ifdef CONFIG_X86_32
8573 +       pushl $(__USER_DS)
8574 +       popl %ds
8575 +#endif
8576 +
8577  2:     movw %ax,(%_ASM_CX)
8578 +
8579 +#ifdef CONFIG_X86_32
8580 +       pushl %ss
8581 +       popl %ds
8582 +#endif
8583 +
8584         xor %eax,%eax
8585         EXIT
8586  ENDPROC(__put_user_2)
8587 @@ -61,7 +86,19 @@ ENTRY(__put_user_4)
8588         sub $3,%_ASM_BX
8589         cmp %_ASM_BX,%_ASM_CX
8590         jae bad_put_user
8591 +
8592 +#ifdef CONFIG_X86_32
8593 +       pushl $(__USER_DS)
8594 +       popl %ds
8595 +#endif
8596 +
8597  3:     movl %eax,(%_ASM_CX)
8598 +
8599 +#ifdef CONFIG_X86_32
8600 +       pushl %ss
8601 +       popl %ds
8602 +#endif
8603 +
8604         xor %eax,%eax
8605         EXIT
8606  ENDPROC(__put_user_4)
8607 @@ -72,16 +109,34 @@ ENTRY(__put_user_8)
8608         sub $7,%_ASM_BX
8609         cmp %_ASM_BX,%_ASM_CX
8610         jae bad_put_user
8611 +
8612 +#ifdef CONFIG_X86_32
8613 +       pushl $(__USER_DS)
8614 +       popl %ds
8615 +#endif
8616 +
8617  4:     mov %_ASM_AX,(%_ASM_CX)
8618  #ifdef CONFIG_X86_32
8619  5:     movl %edx,4(%_ASM_CX)
8620  #endif
8621 +
8622 +#ifdef CONFIG_X86_32
8623 +       pushl %ss
8624 +       popl %ds
8625 +#endif
8626 +
8627         xor %eax,%eax
8628         EXIT
8629  ENDPROC(__put_user_8)
8630  
8631  bad_put_user:
8632         CFI_STARTPROC
8633 +
8634 +#ifdef CONFIG_X86_32
8635 +       pushl %ss
8636 +       popl %ds
8637 +#endif
8638 +
8639         movl $-EFAULT,%eax
8640         EXIT
8641  END(bad_put_user)
8642 diff -urNp linux-2.6.27.10/arch/x86/lib/usercopy_32.c linux-2.6.27.10/arch/x86/lib/usercopy_32.c
8643 --- linux-2.6.27.10/arch/x86/lib/usercopy_32.c  2008-11-07 12:55:34.000000000 -0500
8644 +++ linux-2.6.27.10/arch/x86/lib/usercopy_32.c  2008-11-18 03:38:44.000000000 -0500
8645 @@ -29,31 +29,38 @@ static inline int __movsl_is_ok(unsigned
8646   * Copy a null terminated string from userspace.
8647   */
8648  
8649 -#define __do_strncpy_from_user(dst, src, count, res)                      \
8650 -do {                                                                      \
8651 -       int __d0, __d1, __d2;                                              \
8652 -       might_sleep();                                                     \
8653 -       __asm__ __volatile__(                                              \
8654 -               "       testl %1,%1\n"                                     \
8655 -               "       jz 2f\n"                                           \
8656 -               "0:     lodsb\n"                                           \
8657 -               "       stosb\n"                                           \
8658 -               "       testb %%al,%%al\n"                                 \
8659 -               "       jz 1f\n"                                           \
8660 -               "       decl %1\n"                                         \
8661 -               "       jnz 0b\n"                                          \
8662 -               "1:     subl %1,%0\n"                                      \
8663 -               "2:\n"                                                     \
8664 -               ".section .fixup,\"ax\"\n"                                 \
8665 -               "3:     movl %5,%0\n"                                      \
8666 -               "       jmp 2b\n"                                          \
8667 -               ".previous\n"                                              \
8668 -               _ASM_EXTABLE(0b,3b)                                        \
8669 -               : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),    \
8670 -                 "=&D" (__d2)                                             \
8671 -               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
8672 -               : "memory");                                               \
8673 -} while (0)
8674 +static long __do_strncpy_from_user(char *dst, const char __user *src, long count)
8675 +{
8676 +       int __d0, __d1, __d2;
8677 +       long res = -EFAULT;
8678 +
8679 +       might_sleep();
8680 +       __asm__ __volatile__(
8681 +               "       movw %w10,%%ds\n"
8682 +               "       testl %1,%1\n"
8683 +               "       jz 2f\n"
8684 +               "0:     lodsb\n"
8685 +               "       stosb\n"
8686 +               "       testb %%al,%%al\n"
8687 +               "       jz 1f\n"
8688 +               "       decl %1\n"
8689 +               "       jnz 0b\n"
8690 +               "1:     subl %1,%0\n"
8691 +               "2:\n"
8692 +               "       pushl %%ss\n"
8693 +               "       popl %%ds\n"
8694 +               ".section .fixup,\"ax\"\n"
8695 +               "3:     movl %5,%0\n"
8696 +               "       jmp 2b\n"
8697 +               ".previous\n"
8698 +               _ASM_EXTABLE(0b,3b)
8699 +               : "=&d"(res), "=&c"(count), "=&a" (__d0), "=&S" (__d1),
8700 +                 "=&D" (__d2)
8701 +               : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst),
8702 +                 "r"(__USER_DS)
8703 +               : "memory");
8704 +       return res;
8705 +}
8706  
8707  /**
8708   * __strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
8709 @@ -78,9 +85,7 @@ do {                                                                     \
8710  long
8711  __strncpy_from_user(char *dst, const char __user *src, long count)
8712  {
8713 -       long res;
8714 -       __do_strncpy_from_user(dst, src, count, res);
8715 -       return res;
8716 +       return __do_strncpy_from_user(dst, src, count);
8717  }
8718  EXPORT_SYMBOL(__strncpy_from_user);
8719  
8720 @@ -107,7 +112,7 @@ strncpy_from_user(char *dst, const char 
8721  {
8722         long res = -EFAULT;
8723         if (access_ok(VERIFY_READ, src, 1))
8724 -               __do_strncpy_from_user(dst, src, count, res);
8725 +               res = __do_strncpy_from_user(dst, src, count);
8726         return res;
8727  }
8728  EXPORT_SYMBOL(strncpy_from_user);
8729 @@ -116,24 +121,30 @@ EXPORT_SYMBOL(strncpy_from_user);
8730   * Zero Userspace
8731   */
8732  
8733 -#define __do_clear_user(addr,size)                                     \
8734 -do {                                                                   \
8735 -       int __d0;                                                       \
8736 -       might_sleep();                                                  \
8737 -       __asm__ __volatile__(                                           \
8738 -               "0:     rep; stosl\n"                                   \
8739 -               "       movl %2,%0\n"                                   \
8740 -               "1:     rep; stosb\n"                                   \
8741 -               "2:\n"                                                  \
8742 -               ".section .fixup,\"ax\"\n"                              \
8743 -               "3:     lea 0(%2,%0,4),%0\n"                            \
8744 -               "       jmp 2b\n"                                       \
8745 -               ".previous\n"                                           \
8746 -               _ASM_EXTABLE(0b,3b)                                     \
8747 -               _ASM_EXTABLE(1b,2b)                                     \
8748 -               : "=&c"(size), "=&D" (__d0)                             \
8749 -               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
8750 -} while (0)
8751 +static unsigned long __do_clear_user(void __user *addr, unsigned long size)
8752 +{
8753 +       int __d0;
8754 +
8755 +       might_sleep();
8756 +       __asm__ __volatile__(
8757 +               "       movw %w6,%%es\n"
8758 +               "0:     rep; stosl\n"
8759 +               "       movl %2,%0\n"
8760 +               "1:     rep; stosb\n"
8761 +               "2:\n"
8762 +               "       pushl %%ss\n"
8763 +               "       popl %%es\n"
8764 +               ".section .fixup,\"ax\"\n"
8765 +               "3:     lea 0(%2,%0,4),%0\n"
8766 +               "       jmp 2b\n"
8767 +               ".previous\n"
8768 +               _ASM_EXTABLE(0b,3b)
8769 +               _ASM_EXTABLE(1b,2b)
8770 +               : "=&c"(size), "=&D" (__d0)
8771 +               : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0),
8772 +                 "r"(__USER_DS));
8773 +       return size;
8774 +}
8775  
8776  /**
8777   * clear_user: - Zero a block of memory in user space.
8778 @@ -150,7 +161,7 @@ clear_user(void __user *to, unsigned lon
8779  {
8780         might_sleep();
8781         if (access_ok(VERIFY_WRITE, to, n))
8782 -               __do_clear_user(to, n);
8783 +               n = __do_clear_user(to, n);
8784         return n;
8785  }
8786  EXPORT_SYMBOL(clear_user);
8787 @@ -169,8 +180,7 @@ EXPORT_SYMBOL(clear_user);
8788  unsigned long
8789  __clear_user(void __user *to, unsigned long n)
8790  {
8791 -       __do_clear_user(to, n);
8792 -       return n;
8793 +       return __do_clear_user(to, n);
8794  }
8795  EXPORT_SYMBOL(__clear_user);
8796  
8797 @@ -193,14 +203,17 @@ long strnlen_user(const char __user *s, 
8798         might_sleep();
8799  
8800         __asm__ __volatile__(
8801 +               "       movw %w8,%%es\n"
8802                 "       testl %0, %0\n"
8803                 "       jz 3f\n"
8804 -               "       andl %0,%%ecx\n"
8805 +               "       movl %0,%%ecx\n"
8806                 "0:     repne; scasb\n"
8807                 "       setne %%al\n"
8808                 "       subl %%ecx,%0\n"
8809                 "       addl %0,%%eax\n"
8810                 "1:\n"
8811 +               "       pushl %%ss\n"
8812 +               "       popl %%es\n"
8813                 ".section .fixup,\"ax\"\n"
8814                 "2:     xorl %%eax,%%eax\n"
8815                 "       jmp 1b\n"
8816 @@ -212,7 +225,7 @@ long strnlen_user(const char __user *s, 
8817                 "       .long 0b,2b\n"
8818                 ".previous"
8819                 :"=&r" (n), "=&D" (s), "=&a" (res), "=&c" (tmp)
8820 -               :"0" (n), "1" (s), "2" (0), "3" (mask)
8821 +               :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS)
8822                 :"cc");
8823         return res & mask;
8824  }
8825 @@ -220,10 +233,11 @@ EXPORT_SYMBOL(strnlen_user);
8826  
8827  #ifdef CONFIG_X86_INTEL_USERCOPY
8828  static unsigned long
8829 -__copy_user_intel(void __user *to, const void *from, unsigned long size)
8830 +__generic_copy_to_user_intel(void __user *to, const void *from, unsigned long size)
8831  {
8832         int d0, d1;
8833         __asm__ __volatile__(
8834 +                      "       movw %w6, %%es\n"
8835                        "       .align 2,0x90\n"
8836                        "1:     movl 32(%4), %%eax\n"
8837                        "       cmpl $67, %0\n"
8838 @@ -232,36 +246,36 @@ __copy_user_intel(void __user *to, const
8839                        "       .align 2,0x90\n"
8840                        "3:     movl 0(%4), %%eax\n"
8841                        "4:     movl 4(%4), %%edx\n"
8842 -                      "5:     movl %%eax, 0(%3)\n"
8843 -                      "6:     movl %%edx, 4(%3)\n"
8844 +                      "5:     movl %%eax, %%es:0(%3)\n"
8845 +                      "6:     movl %%edx, %%es:4(%3)\n"
8846                        "7:     movl 8(%4), %%eax\n"
8847                        "8:     movl 12(%4),%%edx\n"
8848 -                      "9:     movl %%eax, 8(%3)\n"
8849 -                      "10:    movl %%edx, 12(%3)\n"
8850 +                      "9:     movl %%eax, %%es:8(%3)\n"
8851 +                      "10:    movl %%edx, %%es:12(%3)\n"
8852                        "11:    movl 16(%4), %%eax\n"
8853                        "12:    movl 20(%4), %%edx\n"
8854 -                      "13:    movl %%eax, 16(%3)\n"
8855 -                      "14:    movl %%edx, 20(%3)\n"
8856 +                      "13:    movl %%eax, %%es:16(%3)\n"
8857 +                      "14:    movl %%edx, %%es:20(%3)\n"
8858                        "15:    movl 24(%4), %%eax\n"
8859                        "16:    movl 28(%4), %%edx\n"
8860 -                      "17:    movl %%eax, 24(%3)\n"
8861 -                      "18:    movl %%edx, 28(%3)\n"
8862 +                      "17:    movl %%eax, %%es:24(%3)\n"
8863 +                      "18:    movl %%edx, %%es:28(%3)\n"
8864                        "19:    movl 32(%4), %%eax\n"
8865                        "20:    movl 36(%4), %%edx\n"
8866 -                      "21:    movl %%eax, 32(%3)\n"
8867 -                      "22:    movl %%edx, 36(%3)\n"
8868 +                      "21:    movl %%eax, %%es:32(%3)\n"
8869 +                      "22:    movl %%edx, %%es:36(%3)\n"
8870                        "23:    movl 40(%4), %%eax\n"
8871                        "24:    movl 44(%4), %%edx\n"
8872 -                      "25:    movl %%eax, 40(%3)\n"
8873 -                      "26:    movl %%edx, 44(%3)\n"
8874 +                      "25:    movl %%eax, %%es:40(%3)\n"
8875 +                      "26:    movl %%edx, %%es:44(%3)\n"
8876                        "27:    movl 48(%4), %%eax\n"
8877                        "28:    movl 52(%4), %%edx\n"
8878 -                      "29:    movl %%eax, 48(%3)\n"
8879 -                      "30:    movl %%edx, 52(%3)\n"
8880 +                      "29:    movl %%eax, %%es:48(%3)\n"
8881 +                      "30:    movl %%edx, %%es:52(%3)\n"
8882                        "31:    movl 56(%4), %%eax\n"
8883                        "32:    movl 60(%4), %%edx\n"
8884 -                      "33:    movl %%eax, 56(%3)\n"
8885 -                      "34:    movl %%edx, 60(%3)\n"
8886 +                      "33:    movl %%eax, %%es:56(%3)\n"
8887 +                      "34:    movl %%edx, %%es:60(%3)\n"
8888                        "       addl $-64, %0\n"
8889                        "       addl $64, %4\n"
8890                        "       addl $64, %3\n"
8891 @@ -275,6 +289,8 @@ __copy_user_intel(void __user *to, const
8892                        "36:    movl %%eax, %0\n"
8893                        "37:    rep; movsb\n"
8894                        "100:\n"
8895 +                      "       pushl %%ss\n"
8896 +                      "       popl %%es\n"
8897                        ".section .fixup,\"ax\"\n"
8898                        "101:   lea 0(%%eax,%0,4),%0\n"
8899                        "       jmp 100b\n"
8900 @@ -321,7 +337,117 @@ __copy_user_intel(void __user *to, const
8901                        "       .long 99b,101b\n"
8902                        ".previous"
8903                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
8904 -                      :  "1"(to), "2"(from), "0"(size)
8905 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
8906 +                      : "eax", "edx", "memory");
8907 +       return size;
8908 +}
8909 +
8910 +static unsigned long
8911 +__generic_copy_from_user_intel(void *to, const void __user *from, unsigned long size)
8912 +{
8913 +       int d0, d1;
8914 +       __asm__ __volatile__(
8915 +                      "       movw %w6, %%ds\n"
8916 +                      "       .align 2,0x90\n"
8917 +                      "1:     movl 32(%4), %%eax\n"
8918 +                      "       cmpl $67, %0\n"
8919 +                      "       jbe 3f\n"
8920 +                      "2:     movl 64(%4), %%eax\n"
8921 +                      "       .align 2,0x90\n"
8922 +                      "3:     movl 0(%4), %%eax\n"
8923 +                      "4:     movl 4(%4), %%edx\n"
8924 +                      "5:     movl %%eax, %%es:0(%3)\n"
8925 +                      "6:     movl %%edx, %%es:4(%3)\n"
8926 +                      "7:     movl 8(%4), %%eax\n"
8927 +                      "8:     movl 12(%4),%%edx\n"
8928 +                      "9:     movl %%eax, %%es:8(%3)\n"
8929 +                      "10:    movl %%edx, %%es:12(%3)\n"
8930 +                      "11:    movl 16(%4), %%eax\n"
8931 +                      "12:    movl 20(%4), %%edx\n"
8932 +                      "13:    movl %%eax, %%es:16(%3)\n"
8933 +                      "14:    movl %%edx, %%es:20(%3)\n"
8934 +                      "15:    movl 24(%4), %%eax\n"
8935 +                      "16:    movl 28(%4), %%edx\n"
8936 +                      "17:    movl %%eax, %%es:24(%3)\n"
8937 +                      "18:    movl %%edx, %%es:28(%3)\n"
8938 +                      "19:    movl 32(%4), %%eax\n"
8939 +                      "20:    movl 36(%4), %%edx\n"
8940 +                      "21:    movl %%eax, %%es:32(%3)\n"
8941 +                      "22:    movl %%edx, %%es:36(%3)\n"
8942 +                      "23:    movl 40(%4), %%eax\n"
8943 +                      "24:    movl 44(%4), %%edx\n"
8944 +                      "25:    movl %%eax, %%es:40(%3)\n"
8945 +                      "26:    movl %%edx, %%es:44(%3)\n"
8946 +                      "27:    movl 48(%4), %%eax\n"
8947 +                      "28:    movl 52(%4), %%edx\n"
8948 +                      "29:    movl %%eax, %%es:48(%3)\n"
8949 +                      "30:    movl %%edx, %%es:52(%3)\n"
8950 +                      "31:    movl 56(%4), %%eax\n"
8951 +                      "32:    movl 60(%4), %%edx\n"
8952 +                      "33:    movl %%eax, %%es:56(%3)\n"
8953 +                      "34:    movl %%edx, %%es:60(%3)\n"
8954 +                      "       addl $-64, %0\n"
8955 +                      "       addl $64, %4\n"
8956 +                      "       addl $64, %3\n"
8957 +                      "       cmpl $63, %0\n"
8958 +                      "       ja  1b\n"
8959 +                      "35:    movl  %0, %%eax\n"
8960 +                      "       shrl  $2, %0\n"
8961 +                      "       andl  $3, %%eax\n"
8962 +                      "       cld\n"
8963 +                      "99:    rep; movsl\n"
8964 +                      "36:    movl %%eax, %0\n"
8965 +                      "37:    rep; movsb\n"
8966 +                      "100:\n"
8967 +                      "       pushl %%ss\n"
8968 +                      "       popl %%ds\n"
8969 +                      ".section .fixup,\"ax\"\n"
8970 +                      "101:   lea 0(%%eax,%0,4),%0\n"
8971 +                      "       jmp 100b\n"
8972 +                      ".previous\n"
8973 +                      ".section __ex_table,\"a\"\n"
8974 +                      "       .align 4\n"
8975 +                      "       .long 1b,100b\n"
8976 +                      "       .long 2b,100b\n"
8977 +                      "       .long 3b,100b\n"
8978 +                      "       .long 4b,100b\n"
8979 +                      "       .long 5b,100b\n"
8980 +                      "       .long 6b,100b\n"
8981 +                      "       .long 7b,100b\n"
8982 +                      "       .long 8b,100b\n"
8983 +                      "       .long 9b,100b\n"
8984 +                      "       .long 10b,100b\n"
8985 +                      "       .long 11b,100b\n"
8986 +                      "       .long 12b,100b\n"
8987 +                      "       .long 13b,100b\n"
8988 +                      "       .long 14b,100b\n"
8989 +                      "       .long 15b,100b\n"
8990 +                      "       .long 16b,100b\n"
8991 +                      "       .long 17b,100b\n"
8992 +                      "       .long 18b,100b\n"
8993 +                      "       .long 19b,100b\n"
8994 +                      "       .long 20b,100b\n"
8995 +                      "       .long 21b,100b\n"
8996 +                      "       .long 22b,100b\n"
8997 +                      "       .long 23b,100b\n"
8998 +                      "       .long 24b,100b\n"
8999 +                      "       .long 25b,100b\n"
9000 +                      "       .long 26b,100b\n"
9001 +                      "       .long 27b,100b\n"
9002 +                      "       .long 28b,100b\n"
9003 +                      "       .long 29b,100b\n"
9004 +                      "       .long 30b,100b\n"
9005 +                      "       .long 31b,100b\n"
9006 +                      "       .long 32b,100b\n"
9007 +                      "       .long 33b,100b\n"
9008 +                      "       .long 34b,100b\n"
9009 +                      "       .long 35b,100b\n"
9010 +                      "       .long 36b,100b\n"
9011 +                      "       .long 37b,100b\n"
9012 +                      "       .long 99b,101b\n"
9013 +                      ".previous"
9014 +                      : "=&c"(size), "=&D" (d0), "=&S" (d1)
9015 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9016                        : "eax", "edx", "memory");
9017         return size;
9018  }
9019 @@ -331,6 +457,7 @@ __copy_user_zeroing_intel(void *to, cons
9020  {
9021         int d0, d1;
9022         __asm__ __volatile__(
9023 +                      "        movw %w6, %%ds\n"
9024                        "        .align 2,0x90\n"
9025                        "0:      movl 32(%4), %%eax\n"
9026                        "        cmpl $67, %0\n"
9027 @@ -339,36 +466,36 @@ __copy_user_zeroing_intel(void *to, cons
9028                        "        .align 2,0x90\n"
9029                        "2:      movl 0(%4), %%eax\n"
9030                        "21:     movl 4(%4), %%edx\n"
9031 -                      "        movl %%eax, 0(%3)\n"
9032 -                      "        movl %%edx, 4(%3)\n"
9033 +                      "        movl %%eax, %%es:0(%3)\n"
9034 +                      "        movl %%edx, %%es:4(%3)\n"
9035                        "3:      movl 8(%4), %%eax\n"
9036                        "31:     movl 12(%4),%%edx\n"
9037 -                      "        movl %%eax, 8(%3)\n"
9038 -                      "        movl %%edx, 12(%3)\n"
9039 +                      "        movl %%eax, %%es:8(%3)\n"
9040 +                      "        movl %%edx, %%es:12(%3)\n"
9041                        "4:      movl 16(%4), %%eax\n"
9042                        "41:     movl 20(%4), %%edx\n"
9043 -                      "        movl %%eax, 16(%3)\n"
9044 -                      "        movl %%edx, 20(%3)\n"
9045 +                      "        movl %%eax, %%es:16(%3)\n"
9046 +                      "        movl %%edx, %%es:20(%3)\n"
9047                        "10:     movl 24(%4), %%eax\n"
9048                        "51:     movl 28(%4), %%edx\n"
9049 -                      "        movl %%eax, 24(%3)\n"
9050 -                      "        movl %%edx, 28(%3)\n"
9051 +                      "        movl %%eax, %%es:24(%3)\n"
9052 +                      "        movl %%edx, %%es:28(%3)\n"
9053                        "11:     movl 32(%4), %%eax\n"
9054                        "61:     movl 36(%4), %%edx\n"
9055 -                      "        movl %%eax, 32(%3)\n"
9056 -                      "        movl %%edx, 36(%3)\n"
9057 +                      "        movl %%eax, %%es:32(%3)\n"
9058 +                      "        movl %%edx, %%es:36(%3)\n"
9059                        "12:     movl 40(%4), %%eax\n"
9060                        "71:     movl 44(%4), %%edx\n"
9061 -                      "        movl %%eax, 40(%3)\n"
9062 -                      "        movl %%edx, 44(%3)\n"
9063 +                      "        movl %%eax, %%es:40(%3)\n"
9064 +                      "        movl %%edx, %%es:44(%3)\n"
9065                        "13:     movl 48(%4), %%eax\n"
9066                        "81:     movl 52(%4), %%edx\n"
9067 -                      "        movl %%eax, 48(%3)\n"
9068 -                      "        movl %%edx, 52(%3)\n"
9069 +                      "        movl %%eax, %%es:48(%3)\n"
9070 +                      "        movl %%edx, %%es:52(%3)\n"
9071                        "14:     movl 56(%4), %%eax\n"
9072                        "91:     movl 60(%4), %%edx\n"
9073 -                      "        movl %%eax, 56(%3)\n"
9074 -                      "        movl %%edx, 60(%3)\n"
9075 +                      "        movl %%eax, %%es:56(%3)\n"
9076 +                      "        movl %%edx, %%es:60(%3)\n"
9077                        "        addl $-64, %0\n"
9078                        "        addl $64, %4\n"
9079                        "        addl $64, %3\n"
9080 @@ -382,6 +509,8 @@ __copy_user_zeroing_intel(void *to, cons
9081                        "        movl %%eax,%0\n"
9082                        "7:      rep; movsb\n"
9083                        "8:\n"
9084 +                      "        pushl %%ss\n"
9085 +                      "        popl %%ds\n"
9086                        ".section .fixup,\"ax\"\n"
9087                        "9:      lea 0(%%eax,%0,4),%0\n"
9088                        "16:     pushl %0\n"
9089 @@ -416,7 +545,7 @@ __copy_user_zeroing_intel(void *to, cons
9090                        "        .long 7b,16b\n"
9091                        ".previous"
9092                        : "=&c"(size), "=&D" (d0), "=&S" (d1)
9093 -                      :  "1"(to), "2"(from), "0"(size)
9094 +                      :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9095                        : "eax", "edx", "memory");
9096         return size;
9097  }
9098 @@ -432,6 +561,7 @@ static unsigned long __copy_user_zeroing
9099         int d0, d1;
9100  
9101         __asm__ __volatile__(
9102 +              "        movw %w6, %%ds\n"
9103                "        .align 2,0x90\n"
9104                "0:      movl 32(%4), %%eax\n"
9105                "        cmpl $67, %0\n"
9106 @@ -440,36 +570,36 @@ static unsigned long __copy_user_zeroing
9107                "        .align 2,0x90\n"
9108                "2:      movl 0(%4), %%eax\n"
9109                "21:     movl 4(%4), %%edx\n"
9110 -              "        movnti %%eax, 0(%3)\n"
9111 -              "        movnti %%edx, 4(%3)\n"
9112 +              "        movnti %%eax, %%es:0(%3)\n"
9113 +              "        movnti %%edx, %%es:4(%3)\n"
9114                "3:      movl 8(%4), %%eax\n"
9115                "31:     movl 12(%4),%%edx\n"
9116 -              "        movnti %%eax, 8(%3)\n"
9117 -              "        movnti %%edx, 12(%3)\n"
9118 +              "        movnti %%eax, %%es:8(%3)\n"
9119 +              "        movnti %%edx, %%es:12(%3)\n"
9120                "4:      movl 16(%4), %%eax\n"
9121                "41:     movl 20(%4), %%edx\n"
9122 -              "        movnti %%eax, 16(%3)\n"
9123 -              "        movnti %%edx, 20(%3)\n"
9124 +              "        movnti %%eax, %%es:16(%3)\n"
9125 +              "        movnti %%edx, %%es:20(%3)\n"
9126                "10:     movl 24(%4), %%eax\n"
9127                "51:     movl 28(%4), %%edx\n"
9128 -              "        movnti %%eax, 24(%3)\n"
9129 -              "        movnti %%edx, 28(%3)\n"
9130 +              "        movnti %%eax, %%es:24(%3)\n"
9131 +              "        movnti %%edx, %%es:28(%3)\n"
9132                "11:     movl 32(%4), %%eax\n"
9133                "61:     movl 36(%4), %%edx\n"
9134 -              "        movnti %%eax, 32(%3)\n"
9135 -              "        movnti %%edx, 36(%3)\n"
9136 +              "        movnti %%eax, %%es:32(%3)\n"
9137 +              "        movnti %%edx, %%es:36(%3)\n"
9138                "12:     movl 40(%4), %%eax\n"
9139                "71:     movl 44(%4), %%edx\n"
9140 -              "        movnti %%eax, 40(%3)\n"
9141 -              "        movnti %%edx, 44(%3)\n"
9142 +              "        movnti %%eax, %%es:40(%3)\n"
9143 +              "        movnti %%edx, %%es:44(%3)\n"
9144                "13:     movl 48(%4), %%eax\n"
9145                "81:     movl 52(%4), %%edx\n"
9146 -              "        movnti %%eax, 48(%3)\n"
9147 -              "        movnti %%edx, 52(%3)\n"
9148 +              "        movnti %%eax, %%es:48(%3)\n"
9149 +              "        movnti %%edx, %%es:52(%3)\n"
9150                "14:     movl 56(%4), %%eax\n"
9151                "91:     movl 60(%4), %%edx\n"
9152 -              "        movnti %%eax, 56(%3)\n"
9153 -              "        movnti %%edx, 60(%3)\n"
9154 +              "        movnti %%eax, %%es:56(%3)\n"
9155 +              "        movnti %%edx, %%es:60(%3)\n"
9156                "        addl $-64, %0\n"
9157                "        addl $64, %4\n"
9158                "        addl $64, %3\n"
9159 @@ -484,6 +614,8 @@ static unsigned long __copy_user_zeroing
9160                "        movl %%eax,%0\n"
9161                "7:      rep; movsb\n"
9162                "8:\n"
9163 +              "        pushl %%ss\n"
9164 +              "        popl %%ds\n"
9165                ".section .fixup,\"ax\"\n"
9166                "9:      lea 0(%%eax,%0,4),%0\n"
9167                "16:     pushl %0\n"
9168 @@ -518,7 +650,7 @@ static unsigned long __copy_user_zeroing
9169                "        .long 7b,16b\n"
9170                ".previous"
9171                : "=&c"(size), "=&D" (d0), "=&S" (d1)
9172 -              :  "1"(to), "2"(from), "0"(size)
9173 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9174                : "eax", "edx", "memory");
9175         return size;
9176  }
9177 @@ -529,6 +661,7 @@ static unsigned long __copy_user_intel_n
9178         int d0, d1;
9179  
9180         __asm__ __volatile__(
9181 +              "        movw %w6, %%ds\n"
9182                "        .align 2,0x90\n"
9183                "0:      movl 32(%4), %%eax\n"
9184                "        cmpl $67, %0\n"
9185 @@ -537,36 +670,36 @@ static unsigned long __copy_user_intel_n
9186                "        .align 2,0x90\n"
9187                "2:      movl 0(%4), %%eax\n"
9188                "21:     movl 4(%4), %%edx\n"
9189 -              "        movnti %%eax, 0(%3)\n"
9190 -              "        movnti %%edx, 4(%3)\n"
9191 +              "        movnti %%eax, %%es:0(%3)\n"
9192 +              "        movnti %%edx, %%es:4(%3)\n"
9193                "3:      movl 8(%4), %%eax\n"
9194                "31:     movl 12(%4),%%edx\n"
9195 -              "        movnti %%eax, 8(%3)\n"
9196 -              "        movnti %%edx, 12(%3)\n"
9197 +              "        movnti %%eax, %%es:8(%3)\n"
9198 +              "        movnti %%edx, %%es:12(%3)\n"
9199                "4:      movl 16(%4), %%eax\n"
9200                "41:     movl 20(%4), %%edx\n"
9201 -              "        movnti %%eax, 16(%3)\n"
9202 -              "        movnti %%edx, 20(%3)\n"
9203 +              "        movnti %%eax, %%es:16(%3)\n"
9204 +              "        movnti %%edx, %%es:20(%3)\n"
9205                "10:     movl 24(%4), %%eax\n"
9206                "51:     movl 28(%4), %%edx\n"
9207 -              "        movnti %%eax, 24(%3)\n"
9208 -              "        movnti %%edx, 28(%3)\n"
9209 +              "        movnti %%eax, %%es:24(%3)\n"
9210 +              "        movnti %%edx, %%es:28(%3)\n"
9211                "11:     movl 32(%4), %%eax\n"
9212                "61:     movl 36(%4), %%edx\n"
9213 -              "        movnti %%eax, 32(%3)\n"
9214 -              "        movnti %%edx, 36(%3)\n"
9215 +              "        movnti %%eax, %%es:32(%3)\n"
9216 +              "        movnti %%edx, %%es:36(%3)\n"
9217                "12:     movl 40(%4), %%eax\n"
9218                "71:     movl 44(%4), %%edx\n"
9219 -              "        movnti %%eax, 40(%3)\n"
9220 -              "        movnti %%edx, 44(%3)\n"
9221 +              "        movnti %%eax, %%es:40(%3)\n"
9222 +              "        movnti %%edx, %%es:44(%3)\n"
9223                "13:     movl 48(%4), %%eax\n"
9224                "81:     movl 52(%4), %%edx\n"
9225 -              "        movnti %%eax, 48(%3)\n"
9226 -              "        movnti %%edx, 52(%3)\n"
9227 +              "        movnti %%eax, %%es:48(%3)\n"
9228 +              "        movnti %%edx, %%es:52(%3)\n"
9229                "14:     movl 56(%4), %%eax\n"
9230                "91:     movl 60(%4), %%edx\n"
9231 -              "        movnti %%eax, 56(%3)\n"
9232 -              "        movnti %%edx, 60(%3)\n"
9233 +              "        movnti %%eax, %%es:56(%3)\n"
9234 +              "        movnti %%edx, %%es:60(%3)\n"
9235                "        addl $-64, %0\n"
9236                "        addl $64, %4\n"
9237                "        addl $64, %3\n"
9238 @@ -581,6 +714,8 @@ static unsigned long __copy_user_intel_n
9239                "        movl %%eax,%0\n"
9240                "7:      rep; movsb\n"
9241                "8:\n"
9242 +              "        pushl %%ss\n"
9243 +              "        popl %%ds\n"
9244                ".section .fixup,\"ax\"\n"
9245                "9:      lea 0(%%eax,%0,4),%0\n"
9246                "16:     jmp 8b\n"
9247 @@ -609,7 +744,7 @@ static unsigned long __copy_user_intel_n
9248                "        .long 7b,16b\n"
9249                ".previous"
9250                : "=&c"(size), "=&D" (d0), "=&S" (d1)
9251 -              :  "1"(to), "2"(from), "0"(size)
9252 +              :  "1"(to), "2"(from), "0"(size), "r"(__USER_DS)
9253                : "eax", "edx", "memory");
9254         return size;
9255  }
9256 @@ -622,90 +757,146 @@ static unsigned long __copy_user_intel_n
9257   */
9258  unsigned long __copy_user_zeroing_intel(void *to, const void __user *from,
9259                                         unsigned long size);
9260 -unsigned long __copy_user_intel(void __user *to, const void *from,
9261 +unsigned long __generic_copy_to_user_intel(void __user *to, const void *from,
9262 +                                       unsigned long size);
9263 +unsigned long __generic_copy_from_user_intel(void *to, const void __user *from,
9264                                         unsigned long size);
9265  unsigned long __copy_user_zeroing_intel_nocache(void *to,
9266                                 const void __user *from, unsigned long size);
9267  #endif /* CONFIG_X86_INTEL_USERCOPY */
9268  
9269  /* Generic arbitrary sized copy.  */
9270 -#define __copy_user(to, from, size)                                    \
9271 -do {                                                                   \
9272 -       int __d0, __d1, __d2;                                           \
9273 -       __asm__ __volatile__(                                           \
9274 -               "       cmp  $7,%0\n"                                   \
9275 -               "       jbe  1f\n"                                      \
9276 -               "       movl %1,%0\n"                                   \
9277 -               "       negl %0\n"                                      \
9278 -               "       andl $7,%0\n"                                   \
9279 -               "       subl %0,%3\n"                                   \
9280 -               "4:     rep; movsb\n"                                   \
9281 -               "       movl %3,%0\n"                                   \
9282 -               "       shrl $2,%0\n"                                   \
9283 -               "       andl $3,%3\n"                                   \
9284 -               "       .align 2,0x90\n"                                \
9285 -               "0:     rep; movsl\n"                                   \
9286 -               "       movl %3,%0\n"                                   \
9287 -               "1:     rep; movsb\n"                                   \
9288 -               "2:\n"                                                  \
9289 -               ".section .fixup,\"ax\"\n"                              \
9290 -               "5:     addl %3,%0\n"                                   \
9291 -               "       jmp 2b\n"                                       \
9292 -               "3:     lea 0(%3,%0,4),%0\n"                            \
9293 -               "       jmp 2b\n"                                       \
9294 -               ".previous\n"                                           \
9295 -               ".section __ex_table,\"a\"\n"                           \
9296 -               "       .align 4\n"                                     \
9297 -               "       .long 4b,5b\n"                                  \
9298 -               "       .long 0b,3b\n"                                  \
9299 -               "       .long 1b,2b\n"                                  \
9300 -               ".previous"                                             \
9301 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
9302 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
9303 -               : "memory");                                            \
9304 -} while (0)
9305 -
9306 -#define __copy_user_zeroing(to, from, size)                            \
9307 -do {                                                                   \
9308 -       int __d0, __d1, __d2;                                           \
9309 -       __asm__ __volatile__(                                           \
9310 -               "       cmp  $7,%0\n"                                   \
9311 -               "       jbe  1f\n"                                      \
9312 -               "       movl %1,%0\n"                                   \
9313 -               "       negl %0\n"                                      \
9314 -               "       andl $7,%0\n"                                   \
9315 -               "       subl %0,%3\n"                                   \
9316 -               "4:     rep; movsb\n"                                   \
9317 -               "       movl %3,%0\n"                                   \
9318 -               "       shrl $2,%0\n"                                   \
9319 -               "       andl $3,%3\n"                                   \
9320 -               "       .align 2,0x90\n"                                \
9321 -               "0:     rep; movsl\n"                                   \
9322 -               "       movl %3,%0\n"                                   \
9323 -               "1:     rep; movsb\n"                                   \
9324 -               "2:\n"                                                  \
9325 -               ".section .fixup,\"ax\"\n"                              \
9326 -               "5:     addl %3,%0\n"                                   \
9327 -               "       jmp 6f\n"                                       \
9328 -               "3:     lea 0(%3,%0,4),%0\n"                            \
9329 -               "6:     pushl %0\n"                                     \
9330 -               "       pushl %%eax\n"                                  \
9331 -               "       xorl %%eax,%%eax\n"                             \
9332 -               "       rep; stosb\n"                                   \
9333 -               "       popl %%eax\n"                                   \
9334 -               "       popl %0\n"                                      \
9335 -               "       jmp 2b\n"                                       \
9336 -               ".previous\n"                                           \
9337 -               ".section __ex_table,\"a\"\n"                           \
9338 -               "       .align 4\n"                                     \
9339 -               "       .long 4b,5b\n"                                  \
9340 -               "       .long 0b,3b\n"                                  \
9341 -               "       .long 1b,6b\n"                                  \
9342 -               ".previous"                                             \
9343 -               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)   \
9344 -               : "3"(size), "0"(size), "1"(to), "2"(from)              \
9345 -               : "memory");                                            \
9346 -} while (0)
9347 +static unsigned long
9348 +__generic_copy_to_user(void __user *to, const void *from, unsigned long size)
9349 +{
9350 +       int __d0, __d1, __d2;
9351 +
9352 +       __asm__ __volatile__(
9353 +               "       movw %w8,%%es\n"
9354 +               "       cmp  $7,%0\n"
9355 +               "       jbe  1f\n"
9356 +               "       movl %1,%0\n"
9357 +               "       negl %0\n"
9358 +               "       andl $7,%0\n"
9359 +               "       subl %0,%3\n"
9360 +               "4:     rep; movsb\n"
9361 +               "       movl %3,%0\n"
9362 +               "       shrl $2,%0\n"
9363 +               "       andl $3,%3\n"
9364 +               "       .align 2,0x90\n"
9365 +               "0:     rep; movsl\n"
9366 +               "       movl %3,%0\n"
9367 +               "1:     rep; movsb\n"
9368 +               "2:\n"
9369 +               "       pushl %%ss\n"
9370 +               "       popl %%es\n"
9371 +               ".section .fixup,\"ax\"\n"
9372 +               "5:     addl %3,%0\n"
9373 +               "       jmp 2b\n"
9374 +               "3:     lea 0(%3,%0,4),%0\n"
9375 +               "       jmp 2b\n"
9376 +               ".previous\n"
9377 +               ".section __ex_table,\"a\"\n"
9378 +               "       .align 4\n"
9379 +               "       .long 4b,5b\n"
9380 +               "       .long 0b,3b\n"
9381 +               "       .long 1b,2b\n"
9382 +               ".previous"
9383 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9384 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9385 +               : "memory");
9386 +       return size;
9387 +}
9388 +
9389 +static unsigned long
9390 +__generic_copy_from_user(void *to, const void __user *from, unsigned long size)
9391 +{
9392 +       int __d0, __d1, __d2;
9393 +
9394 +       __asm__ __volatile__(
9395 +               "       movw %w8,%%ds\n"
9396 +               "       cmp  $7,%0\n"
9397 +               "       jbe  1f\n"
9398 +               "       movl %1,%0\n"
9399 +               "       negl %0\n"
9400 +               "       andl $7,%0\n"
9401 +               "       subl %0,%3\n"
9402 +               "4:     rep; movsb\n"
9403 +               "       movl %3,%0\n"
9404 +               "       shrl $2,%0\n"
9405 +               "       andl $3,%3\n"
9406 +               "       .align 2,0x90\n"
9407 +               "0:     rep; movsl\n"
9408 +               "       movl %3,%0\n"
9409 +               "1:     rep; movsb\n"
9410 +               "2:\n"
9411 +               "       pushl %%ss\n"
9412 +               "       popl %%ds\n"
9413 +               ".section .fixup,\"ax\"\n"
9414 +               "5:     addl %3,%0\n"
9415 +               "       jmp 2b\n"
9416 +               "3:     lea 0(%3,%0,4),%0\n"
9417 +               "       jmp 2b\n"
9418 +               ".previous\n"
9419 +               ".section __ex_table,\"a\"\n"
9420 +               "       .align 4\n"
9421 +               "       .long 4b,5b\n"
9422 +               "       .long 0b,3b\n"
9423 +               "       .long 1b,2b\n"
9424 +               ".previous"
9425 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9426 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9427 +               : "memory");
9428 +       return size;
9429 +}
9430 +
9431 +static unsigned long
9432 +__copy_user_zeroing(void *to, const void __user *from, unsigned long size)
9433 +{
9434 +       int __d0, __d1, __d2;
9435 +
9436 +       __asm__ __volatile__(
9437 +               "       movw %w8,%%ds\n"
9438 +               "       cmp  $7,%0\n"
9439 +               "       jbe  1f\n"
9440 +               "       movl %1,%0\n"
9441 +               "       negl %0\n"
9442 +               "       andl $7,%0\n"
9443 +               "       subl %0,%3\n"
9444 +               "4:     rep; movsb\n"
9445 +               "       movl %3,%0\n"
9446 +               "       shrl $2,%0\n"
9447 +               "       andl $3,%3\n"
9448 +               "       .align 2,0x90\n"
9449 +               "0:     rep; movsl\n"
9450 +               "       movl %3,%0\n"
9451 +               "1:     rep; movsb\n"
9452 +               "2:\n"
9453 +               "       pushl %%ss\n"
9454 +               "       popl %%ds\n"
9455 +               ".section .fixup,\"ax\"\n"
9456 +               "5:     addl %3,%0\n"
9457 +               "       jmp 6f\n"
9458 +               "3:     lea 0(%3,%0,4),%0\n"
9459 +               "6:     pushl %0\n"
9460 +               "       pushl %%eax\n"
9461 +               "       xorl %%eax,%%eax\n"
9462 +               "       rep; stosb\n"
9463 +               "       popl %%eax\n"
9464 +               "       popl %0\n"
9465 +               "       jmp 2b\n"
9466 +               ".previous\n"
9467 +               ".section __ex_table,\"a\"\n"
9468 +               "       .align 4\n"
9469 +               "       .long 4b,5b\n"
9470 +               "       .long 0b,3b\n"
9471 +               "       .long 1b,6b\n"
9472 +               ".previous"
9473 +               : "=&c"(size), "=&D" (__d0), "=&S" (__d1), "=r"(__d2)
9474 +               : "3"(size), "0"(size), "1"(to), "2"(from), "r"(__USER_DS)
9475 +               : "memory");
9476 +       return size;
9477 +}
9478  
9479  unsigned long __copy_to_user_ll(void __user *to, const void *from,
9480                                 unsigned long n)
9481 @@ -768,9 +959,9 @@ survive:
9482         }
9483  #endif
9484         if (movsl_is_ok(to, from, n))
9485 -               __copy_user(to, from, n);
9486 +               n = __generic_copy_to_user(to, from, n);
9487         else
9488 -               n = __copy_user_intel(to, from, n);
9489 +               n = __generic_copy_to_user_intel(to, from, n);
9490         return n;
9491  }
9492  EXPORT_SYMBOL(__copy_to_user_ll);
9493 @@ -779,7 +970,7 @@ unsigned long __copy_from_user_ll(void *
9494                                         unsigned long n)
9495  {
9496         if (movsl_is_ok(to, from, n))
9497 -               __copy_user_zeroing(to, from, n);
9498 +               n = __copy_user_zeroing(to, from, n);
9499         else
9500                 n = __copy_user_zeroing_intel(to, from, n);
9501         return n;
9502 @@ -790,10 +981,9 @@ unsigned long __copy_from_user_ll_nozero
9503                                          unsigned long n)
9504  {
9505         if (movsl_is_ok(to, from, n))
9506 -               __copy_user(to, from, n);
9507 +               n = __generic_copy_from_user(to, from, n);
9508         else
9509 -               n = __copy_user_intel((void __user *)to,
9510 -                                     (const void *)from, n);
9511 +               n = __generic_copy_from_user_intel(to, from, n);
9512         return n;
9513  }
9514  EXPORT_SYMBOL(__copy_from_user_ll_nozero);
9515 @@ -802,12 +992,12 @@ unsigned long __copy_from_user_ll_nocach
9516                                         unsigned long n)
9517  {
9518  #ifdef CONFIG_X86_INTEL_USERCOPY
9519 -       if (n > 64 && cpu_has_xmm2)
9520 +       if ( n > 64 && cpu_has_xmm2)
9521                 n = __copy_user_zeroing_intel_nocache(to, from, n);
9522         else
9523 -               __copy_user_zeroing(to, from, n);
9524 +               n = __copy_user_zeroing(to, from, n);
9525  #else
9526 -       __copy_user_zeroing(to, from, n);
9527 +       n = __copy_user_zeroing(to, from, n);
9528  #endif
9529         return n;
9530  }
9531 @@ -817,12 +1007,12 @@ unsigned long __copy_from_user_ll_nocach
9532                                         unsigned long n)
9533  {
9534  #ifdef CONFIG_X86_INTEL_USERCOPY
9535 -       if (n > 64 && cpu_has_xmm2)
9536 +       if ( n > 64 && cpu_has_xmm2)
9537                 n = __copy_user_intel_nocache(to, from, n);
9538         else
9539 -               __copy_user(to, from, n);
9540 +               n = __generic_copy_from_user(to, from, n);
9541  #else
9542 -       __copy_user(to, from, n);
9543 +       n = __generic_copy_from_user(to, from, n);
9544  #endif
9545         return n;
9546  }
9547 @@ -871,8 +1061,35 @@ copy_from_user(void *to, const void __us
9548  {
9549         if (access_ok(VERIFY_READ, from, n))
9550                 n = __copy_from_user(to, from, n);
9551 -       else
9552 +       else if ((long)n > 0)
9553                 memset(to, 0, n);
9554         return n;
9555  }
9556  EXPORT_SYMBOL(copy_from_user);
9557 +
9558 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9559 +void __set_fs(mm_segment_t x, int cpu)
9560 +{
9561 +       unsigned long limit = x.seg;
9562 +       struct desc_struct d;
9563 +
9564 +       current_thread_info()->addr_limit = x;
9565 +       if (likely(limit))
9566 +               limit = (limit - 1UL) >> PAGE_SHIFT;
9567 +       pack_descriptor(&d, 0UL, limit, 0xF3, 0xC);
9568 +       write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_DS, &d, DESCTYPE_S);
9569 +}
9570 +
9571 +void set_fs(mm_segment_t x)
9572 +{
9573 +       __set_fs(x, get_cpu());
9574 +       put_cpu_no_resched();
9575 +}
9576 +#else
9577 +void set_fs(mm_segment_t x)
9578 +{
9579 +       current_thread_info()->addr_limit = x;
9580 +}
9581 +#endif
9582 +
9583 +EXPORT_SYMBOL(set_fs);
9584 diff -urNp linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c
9585 --- linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c       2008-11-07 12:55:34.000000000 -0500
9586 +++ linux-2.6.27.10/arch/x86/mach-voyager/voyager_basic.c       2008-11-18 03:38:44.000000000 -0500
9587 @@ -123,7 +123,7 @@ int __init voyager_memory_detect(int reg
9588         __u8 cmos[4];
9589         ClickMap_t *map;
9590         unsigned long map_addr;
9591 -       unsigned long old;
9592 +       pte_t old;
9593  
9594         if (region >= CLICK_ENTRIES) {
9595                 printk("Voyager: Illegal ClickMap region %d\n", region);
9596 @@ -138,7 +138,7 @@ int __init voyager_memory_detect(int reg
9597  
9598         /* steal page 0 for this */
9599         old = pg0[0];
9600 -       pg0[0] = ((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9601 +       pg0[0] = __pte((map_addr & PAGE_MASK) | _PAGE_RW | _PAGE_PRESENT);
9602         local_flush_tlb();
9603         /* now clear everything out but page 0 */
9604         map = (ClickMap_t *) (map_addr & (~PAGE_MASK));
9605 diff -urNp linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c
9606 --- linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c 2008-11-07 12:55:34.000000000 -0500
9607 +++ linux-2.6.27.10/arch/x86/mach-voyager/voyager_smp.c 2008-11-18 03:38:44.000000000 -0500
9608 @@ -510,6 +510,10 @@ static void __init do_boot_cpu(__u8 cpu)
9609         __u32 *hijack_vector;
9610         __u32 start_phys_address = setup_trampoline();
9611  
9612 +#ifdef CONFIG_PAX_KERNEXEC
9613 +       unsigned long cr0;
9614 +#endif
9615 +
9616         /* There's a clever trick to this: The linux trampoline is
9617          * compiled to begin at absolute location zero, so make the
9618          * address zero but have the data segment selector compensate
9619 @@ -529,7 +533,17 @@ static void __init do_boot_cpu(__u8 cpu)
9620  
9621         init_gdt(cpu);
9622         per_cpu(current_task, cpu) = idle;
9623 -       early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
9624 +
9625 +#ifdef CONFIG_PAX_KERNEXEC
9626 +       pax_open_kernel(cr0);
9627 +#endif
9628 +
9629 +       early_gdt_descr.address = get_cpu_gdt_table(cpu);
9630 +
9631 +#ifdef CONFIG_PAX_KERNEXEC
9632 +       pax_close_kernel(cr0);
9633 +#endif
9634 +
9635         irq_ctx_init(cpu);
9636  
9637         /* Note: Don't modify initial ss override */
9638 @@ -1141,7 +1155,7 @@ void smp_local_timer_interrupt(void)
9639                             per_cpu(prof_counter, cpu);
9640                 }
9641  
9642 -               update_process_times(user_mode_vm(get_irq_regs()));
9643 +               update_process_times(user_mode(get_irq_regs()));
9644         }
9645  
9646         if (((1 << cpu) & voyager_extended_vic_processors) == 0)
9647 diff -urNp linux-2.6.27.10/arch/x86/Makefile linux-2.6.27.10/arch/x86/Makefile
9648 --- linux-2.6.27.10/arch/x86/Makefile   2008-11-07 12:55:34.000000000 -0500
9649 +++ linux-2.6.27.10/arch/x86/Makefile   2008-11-18 03:38:44.000000000 -0500
9650 @@ -232,3 +232,12 @@ endef
9651  CLEAN_FILES += arch/x86/boot/fdimage \
9652                arch/x86/boot/image.iso \
9653                arch/x86/boot/mtools.conf
9654 +
9655 +define OLD_LD
9656 +
9657 +*** ${VERSION}.${PATCHLEVEL} PaX kernels no longer build correctly with old versions of binutils.
9658 +*** Please upgrade your binutils to 2.18 or newer
9659 +endef
9660 +
9661 +archprepare:
9662 +       $(if $(LDFLAGS_BUILD_ID),,$(error $(OLD_LD)))
9663 diff -urNp linux-2.6.27.10/arch/x86/mm/discontig_32.c linux-2.6.27.10/arch/x86/mm/discontig_32.c
9664 --- linux-2.6.27.10/arch/x86/mm/discontig_32.c  2008-12-10 22:35:36.000000000 -0500
9665 +++ linux-2.6.27.10/arch/x86/mm/discontig_32.c  2008-12-10 22:35:46.000000000 -0500
9666 @@ -98,7 +98,6 @@ unsigned long node_memmap_size_bytes(int
9667  }
9668  #endif
9669  
9670 -extern unsigned long find_max_low_pfn(void);
9671  extern unsigned long highend_pfn, highstart_pfn;
9672  
9673  #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
9674 diff -urNp linux-2.6.27.10/arch/x86/mm/extable.c linux-2.6.27.10/arch/x86/mm/extable.c
9675 --- linux-2.6.27.10/arch/x86/mm/extable.c       2008-11-07 12:55:34.000000000 -0500
9676 +++ linux-2.6.27.10/arch/x86/mm/extable.c       2008-11-18 03:38:44.000000000 -0500
9677 @@ -1,14 +1,62 @@
9678  #include <linux/module.h>
9679  #include <linux/spinlock.h>
9680 +#include <linux/sort.h>
9681  #include <asm/uaccess.h>
9682  
9683 +/*
9684 + * The exception table needs to be sorted so that the binary
9685 + * search that we use to find entries in it works properly.
9686 + * This is used both for the kernel exception table and for
9687 + * the exception tables of modules that get loaded.
9688 + */
9689 +static int cmp_ex(const void *a, const void *b)
9690 +{
9691 +       const struct exception_table_entry *x = a, *y = b;
9692 +
9693 +       /* avoid overflow */
9694 +       if (x->insn > y->insn)
9695 +               return 1;
9696 +       if (x->insn < y->insn)
9697 +               return -1;
9698 +       return 0;
9699 +}
9700 +
9701 +static void swap_ex(void *a, void *b, int size)
9702 +{
9703 +       struct exception_table_entry t, *x = a, *y = b;
9704 +
9705 +#ifdef CONFIG_PAX_KERNEXEC
9706 +       unsigned long cr0;
9707 +#endif
9708 +
9709 +       t = *x;
9710 +
9711 +#ifdef CONFIG_PAX_KERNEXEC
9712 +       pax_open_kernel(cr0);
9713 +#endif
9714 +
9715 +       *x = *y;
9716 +       *y = t;
9717 +
9718 +#ifdef CONFIG_PAX_KERNEXEC
9719 +       pax_close_kernel(cr0);
9720 +#endif
9721 +
9722 +}
9723 +
9724 +void sort_extable(struct exception_table_entry *start,
9725 +                 struct exception_table_entry *finish)
9726 +{
9727 +       sort(start, finish - start, sizeof(struct exception_table_entry),
9728 +            cmp_ex, swap_ex);
9729 +}
9730  
9731  int fixup_exception(struct pt_regs *regs)
9732  {
9733         const struct exception_table_entry *fixup;
9734  
9735  #ifdef CONFIG_PNPBIOS
9736 -       if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs))) {
9737 +       if (unlikely(!v8086_mode(regs) && SEGMENT_IS_PNP_CODE(regs->cs))) {
9738                 extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
9739                 extern u32 pnp_bios_is_utter_crap;
9740                 pnp_bios_is_utter_crap = 1;
9741 diff -urNp linux-2.6.27.10/arch/x86/mm/fault.c linux-2.6.27.10/arch/x86/mm/fault.c
9742 --- linux-2.6.27.10/arch/x86/mm/fault.c 2008-11-07 12:55:34.000000000 -0500
9743 +++ linux-2.6.27.10/arch/x86/mm/fault.c 2008-12-10 22:28:27.000000000 -0500
9744 @@ -26,6 +26,8 @@
9745  #include <linux/kprobes.h>
9746  #include <linux/uaccess.h>
9747  #include <linux/kdebug.h>
9748 +#include <linux/unistd.h>
9749 +#include <linux/compiler.h>
9750  
9751  #include <asm/system.h>
9752  #include <asm/desc.h>
9753 @@ -66,7 +68,7 @@ static inline int notify_page_fault(stru
9754         int ret = 0;
9755  
9756         /* kprobe_running() needs smp_processor_id() */
9757 -       if (!user_mode_vm(regs)) {
9758 +       if (!user_mode(regs)) {
9759                 preempt_disable();
9760                 if (kprobe_running() && kprobe_fault_handler(regs, 14))
9761                         ret = 1;
9762 @@ -264,6 +266,30 @@ bad:
9763  #endif
9764  }
9765  
9766 +#ifdef CONFIG_PAX_EMUTRAMP
9767 +static int pax_handle_fetch_fault(struct pt_regs *regs);
9768 +#endif
9769 +
9770 +#ifdef CONFIG_PAX_PAGEEXEC
9771 +static inline pmd_t * pax_get_pmd(struct mm_struct *mm, unsigned long address)
9772 +{
9773 +       pgd_t *pgd;
9774 +       pud_t *pud;
9775 +       pmd_t *pmd;
9776 +
9777 +       pgd = pgd_offset(mm, address);
9778 +       if (!pgd_present(*pgd))
9779 +               return NULL;
9780 +       pud = pud_offset(pgd, address);
9781 +       if (!pud_present(*pud))
9782 +               return NULL;
9783 +       pmd = pmd_offset(pud, address);
9784 +       if (!pmd_present(*pmd))
9785 +               return NULL;
9786 +       return pmd;
9787 +}
9788 +#endif
9789 +
9790  #ifdef CONFIG_X86_32
9791  static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
9792  {
9793 @@ -350,7 +376,7 @@ static int is_errata93(struct pt_regs *r
9794  static int is_errata100(struct pt_regs *regs, unsigned long address)
9795  {
9796  #ifdef CONFIG_X86_64
9797 -       if ((regs->cs == __USER32_CS || (regs->cs & (1<<2))) &&
9798 +       if ((regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT)) &&
9799             (address >> 32))
9800                 return 1;
9801  #endif
9802 @@ -387,14 +413,31 @@ static void show_fault_oops(struct pt_re
9803  #endif
9804  
9805  #ifdef CONFIG_X86_PAE
9806 -       if (error_code & PF_INSTR) {
9807 +       if (nx_enabled && (error_code & PF_INSTR)) {
9808                 unsigned int level;
9809                 pte_t *pte = lookup_address(address, &level);
9810  
9811                 if (pte && pte_present(*pte) && !pte_exec(*pte))
9812                         printk(KERN_CRIT "kernel tried to execute "
9813                                 "NX-protected page - exploit attempt? "
9814 -                               "(uid: %d)\n", current->uid);
9815 +                               "(uid: %d, task: %s, pid: %d)\n",
9816 +                               current->uid, current->comm, task_pid_nr(current));
9817 +       }
9818 +#endif
9819 +
9820 +#ifdef CONFIG_PAX_KERNEXEC
9821 +#ifdef CONFIG_MODULES
9822 +       if (init_mm.start_code <= address && address < (unsigned long)MODULES_END)
9823 +#else
9824 +       if (init_mm.start_code <= address && address < init_mm.end_code)
9825 +#endif
9826 +       {
9827 +               if (current->signal->curr_ip)
9828 +                       printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9829 +                               NIPQUAD(current->signal->curr_ip), current->comm, task_pid_nr(current), current->uid, current->euid);
9830 +               else
9831 +                       printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code\n",
9832 +                               current->comm, task_pid_nr(current), current->uid, current->euid);
9833         }
9834  #endif
9835  
9836 @@ -586,13 +629,22 @@ void __kprobes do_page_fault(struct pt_r
9837         struct task_struct *tsk;
9838         struct mm_struct *mm;
9839         struct vm_area_struct *vma;
9840 -       unsigned long address;
9841         int write, si_code;
9842         int fault;
9843  #ifdef CONFIG_X86_64
9844         unsigned long flags;
9845  #endif
9846  
9847 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9848 +       pte_t *pte;
9849 +       pmd_t *pmd;
9850 +       spinlock_t *ptl;
9851 +       unsigned char pte_mask;
9852 +#endif
9853 +
9854 +       /* get the address */
9855 +       const unsigned long address = read_cr2();
9856 +
9857         /*
9858          * We can fault from pretty much anywhere, with unknown IRQ state.
9859          */
9860 @@ -602,9 +654,6 @@ void __kprobes do_page_fault(struct pt_r
9861         mm = tsk->mm;
9862         prefetchw(&mm->mmap_sem);
9863  
9864 -       /* get the address */
9865 -       address = read_cr2();
9866 -
9867         si_code = SEGV_MAPERR;
9868  
9869         if (notify_page_fault(regs))
9870 @@ -657,7 +706,7 @@ void __kprobes do_page_fault(struct pt_r
9871          * atomic region then we must not take the fault.
9872          */
9873         if (in_atomic() || !mm)
9874 -               goto bad_area_nosemaphore;
9875 +               goto bad_area_nopax;
9876  #else /* CONFIG_X86_64 */
9877         if (likely(regs->flags & X86_EFLAGS_IF))
9878                 local_irq_enable();
9879 @@ -670,13 +719,13 @@ void __kprobes do_page_fault(struct pt_r
9880          * atomic region then we must not take the fault.
9881          */
9882         if (unlikely(in_atomic() || !mm))
9883 -               goto bad_area_nosemaphore;
9884 +               goto bad_area_nopax;
9885  
9886         /*
9887          * User-mode registers count as a user access even for any
9888          * potential system fault or CPU buglet.
9889          */
9890 -       if (user_mode_vm(regs))
9891 +       if (user_mode(regs))
9892                 error_code |= PF_USER;
9893  again:
9894  #endif
9895 @@ -698,10 +747,104 @@ again:
9896         if (!down_read_trylock(&mm->mmap_sem)) {
9897                 if ((error_code & PF_USER) == 0 &&
9898                     !search_exception_tables(regs->ip))
9899 -                       goto bad_area_nosemaphore;
9900 +                       goto bad_area_nopax;
9901                 down_read(&mm->mmap_sem);
9902         }
9903  
9904 +#if defined(CONFIG_X86_32) && defined(CONFIG_PAX_PAGEEXEC)
9905 +       if (nx_enabled || (error_code & (PF_PROT|PF_USER)) != (PF_PROT|PF_USER) || v8086_mode(regs) ||
9906 +           !(mm->pax_flags & MF_PAX_PAGEEXEC))
9907 +               goto not_pax_fault;
9908 +
9909 +       /* PaX: it's our fault, let's handle it if we can */
9910 +
9911 +       /* PaX: take a look at read faults before acquiring any locks */
9912 +       if (unlikely(!(error_code & PF_WRITE) && (regs->ip == address))) {
9913 +               /* instruction fetch attempt from a protected page in user mode */
9914 +               up_read(&mm->mmap_sem);
9915 +
9916 +#ifdef CONFIG_PAX_EMUTRAMP
9917 +               switch (pax_handle_fetch_fault(regs)) {
9918 +               case 2:
9919 +                       return;
9920 +               }
9921 +#endif
9922 +
9923 +               pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
9924 +               do_group_exit(SIGKILL);
9925 +       }
9926 +
9927 +       pmd = pax_get_pmd(mm, address);
9928 +       if (unlikely(!pmd))
9929 +               goto not_pax_fault;
9930 +
9931 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
9932 +       if (unlikely(!(pte_val(*pte) & _PAGE_PRESENT) || pte_user(*pte))) {
9933 +               pte_unmap_unlock(pte, ptl);
9934 +               goto not_pax_fault;
9935 +       }
9936 +
9937 +       if (unlikely((error_code & PF_WRITE) && !pte_write(*pte))) {
9938 +               /* write attempt to a protected page in user mode */
9939 +               pte_unmap_unlock(pte, ptl);
9940 +               goto not_pax_fault;
9941 +       }
9942 +
9943 +#ifdef CONFIG_SMP
9944 +       if (likely(address > get_limit(regs->cs) && cpu_isset(smp_processor_id(), mm->context.cpu_user_cs_mask)))
9945 +#else
9946 +       if (likely(address > get_limit(regs->cs)))
9947 +#endif
9948 +       {
9949 +               set_pte(pte, pte_mkread(*pte));
9950 +               __flush_tlb_one(address);
9951 +               pte_unmap_unlock(pte, ptl);
9952 +               up_read(&mm->mmap_sem);
9953 +               return;
9954 +       }
9955 +
9956 +       pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & PF_WRITE) << (_PAGE_BIT_DIRTY-1));
9957 +
9958 +       /*
9959 +        * PaX: fill DTLB with user rights and retry
9960 +        */
9961 +       __asm__ __volatile__ (
9962 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9963 +               "movw %w4,%%es\n"
9964 +#endif
9965 +               "orb %2,(%1)\n"
9966 +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC)
9967 +/*
9968 + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's
9969 + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any*
9970 + * page fault when examined during a TLB load attempt. this is true not only
9971 + * for PTEs holding a non-present entry but also present entries that will
9972 + * raise a page fault (such as those set up by PaX, or the copy-on-write
9973 + * mechanism). in effect it means that we do *not* need to flush the TLBs
9974 + * for our target pages since their PTEs are simply not in the TLBs at all.
9975 +
9976 + * the best thing in omitting it is that we gain around 15-20% speed in the
9977 + * fast path of the page fault handler and can get rid of tracing since we
9978 + * can no longer flush unintended entries.
9979 + */
9980 +               "invlpg (%0)\n"
9981 +#endif
9982 +               "testb $0,%%es:(%0)\n"
9983 +               "xorb %3,(%1)\n"
9984 +#ifdef CONFIG_PAX_MEMORY_UDEREF
9985 +               "pushl %%ss\n"
9986 +               "popl %%es\n"
9987 +#endif
9988 +               :
9989 +               : "r" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS)
9990 +               : "memory", "cc");
9991 +       pte_unmap_unlock(pte, ptl);
9992 +       up_read(&mm->mmap_sem);
9993 +       return;
9994 +
9995 +not_pax_fault:
9996 +#endif
9997 +
9998         vma = find_vma(mm, address);
9999         if (!vma)
10000                 goto bad_area;
10001 @@ -709,16 +852,20 @@ again:
10002                 goto good_area;
10003         if (!(vma->vm_flags & VM_GROWSDOWN))
10004                 goto bad_area;
10005 -       if (error_code & PF_USER) {
10006 -               /*
10007 -                * Accessing the stack below %sp is always a bug.
10008 -                * The large cushion allows instructions like enter
10009 -                * and pusha to work.  ("enter $65535,$31" pushes
10010 -                * 32 pointers and then decrements %sp by 65535.)
10011 -                */
10012 -               if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
10013 -                       goto bad_area;
10014 -       }
10015 +       /*
10016 +        * Accessing the stack below %sp is always a bug.
10017 +        * The large cushion allows instructions like enter
10018 +        * and pusha to work.  ("enter $65535,$31" pushes
10019 +        * 32 pointers and then decrements %sp by 65535.)
10020 +        */
10021 +       if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
10022 +               goto bad_area;
10023 +
10024 +#ifdef CONFIG_PAX_SEGMEXEC
10025 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1)
10026 +               goto bad_area;
10027 +#endif
10028 +
10029         if (expand_stack(vma, address))
10030                 goto bad_area;
10031  /*
10032 @@ -728,6 +875,8 @@ again:
10033  good_area:
10034         si_code = SEGV_ACCERR;
10035         write = 0;
10036 +       if (nx_enabled && (error_code & PF_INSTR) && !(vma->vm_flags & VM_EXEC))
10037 +               goto bad_area;
10038         switch (error_code & (PF_PROT|PF_WRITE)) {
10039         default:        /* 3: write, present */
10040                 /* fall through */
10041 @@ -785,6 +934,54 @@ bad_area:
10042         up_read(&mm->mmap_sem);
10043  
10044  bad_area_nosemaphore:
10045 +
10046 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10047 +       if (mm && (error_code & PF_USER)) {
10048 +               unsigned long ip = regs->ip;
10049 +
10050 +               if (v8086_mode(regs))
10051 +                       ip = ((regs->cs & 0xffff) << 4) + (regs->ip & 0xffff);
10052 +
10053 +               /*
10054 +                * It's possible to have interrupts off here.
10055 +                */
10056 +               local_irq_enable();
10057 +
10058 +#ifdef CONFIG_PAX_PAGEEXEC
10059 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) &&
10060 +                   ((nx_enabled && (error_code & PF_INSTR)) || (!(error_code & (PF_PROT | PF_WRITE)) && regs->ip == address))) {
10061 +
10062 +#ifdef CONFIG_PAX_EMUTRAMP
10063 +                       switch (pax_handle_fetch_fault(regs)) {
10064 +                       case 2:
10065 +                               return;
10066 +                       }
10067 +#endif
10068 +
10069 +                       pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
10070 +                       do_group_exit(SIGKILL);
10071 +               }
10072 +#endif
10073 +
10074 +#ifdef CONFIG_PAX_SEGMEXEC
10075 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & (PF_PROT | PF_WRITE)) && (regs->ip + SEGMEXEC_TASK_SIZE == address)) {
10076 +
10077 +#ifdef CONFIG_PAX_EMUTRAMP
10078 +                       switch (pax_handle_fetch_fault(regs)) {
10079 +                       case 2:
10080 +                               return;
10081 +                       }
10082 +#endif
10083 +
10084 +                       pax_report_fault(regs, (void *)regs->ip, (void *)regs->sp);
10085 +                       do_group_exit(SIGKILL);
10086 +               }
10087 +#endif
10088 +
10089 +       }
10090 +#endif
10091 +
10092 +bad_area_nopax:
10093         /* User mode accesses just cause a SIGSEGV */
10094         if (error_code & PF_USER) {
10095                 /*
10096 @@ -863,7 +1060,7 @@ no_context:
10097  #ifdef CONFIG_X86_32
10098         die("Oops", regs, error_code);
10099         bust_spinlocks(0);
10100 -       do_exit(SIGKILL);
10101 +       do_group_exit(SIGKILL);
10102  #else
10103         if (__die("Oops", regs, error_code))
10104                 regs = NULL;
10105 @@ -877,17 +1074,17 @@ no_context:
10106   * us unable to handle the page fault gracefully.
10107   */
10108  out_of_memory:
10109 -       up_read(&mm->mmap_sem);
10110         if (is_global_init(tsk)) {
10111                 yield();
10112  #ifdef CONFIG_X86_32
10113 -               down_read(&mm->mmap_sem);
10114                 goto survive;
10115  #else
10116 +               up_read(&mm->mmap_sem);
10117                 goto again;
10118  #endif
10119         }
10120  
10121 +       up_read(&mm->mmap_sem);
10122         printk("VM: killing process %s\n", tsk->comm);
10123         if (error_code & PF_USER)
10124                 do_group_exit(SIGKILL);
10125 @@ -959,3 +1156,174 @@ void vmalloc_sync_all(void)
10126         }
10127  #endif
10128  }
10129 +
10130 +#ifdef CONFIG_PAX_EMUTRAMP
10131 +static int pax_handle_fetch_fault_32(struct pt_regs *regs)
10132 +{
10133 +       int err;
10134 +
10135 +       do { /* PaX: gcc trampoline emulation #1 */
10136 +               unsigned char mov1, mov2;
10137 +               unsigned short jmp;
10138 +               unsigned int addr1, addr2;
10139 +
10140 +#ifdef CONFIG_X86_64
10141 +               if ((regs->ip + 11) >> 32)
10142 +                       break;
10143 +#endif
10144 +
10145 +               err = get_user(mov1, (unsigned char __user *)regs->ip);
10146 +               err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
10147 +               err |= get_user(mov2, (unsigned char __user *)(regs->ip + 5));
10148 +               err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
10149 +               err |= get_user(jmp, (unsigned short __user *)(regs->ip + 10));
10150 +
10151 +               if (err)
10152 +                       break;
10153 +
10154 +               if (mov1 == 0xB9 && mov2 == 0xB8 && jmp == 0xE0FF) {
10155 +                       regs->cx = addr1;
10156 +                       regs->ax = addr2;
10157 +                       regs->ip = addr2;
10158 +                       return 2;
10159 +               }
10160 +       } while (0);
10161 +
10162 +       do { /* PaX: gcc trampoline emulation #2 */
10163 +               unsigned char mov, jmp;
10164 +               unsigned int addr1, addr2;
10165 +
10166 +#ifdef CONFIG_X86_64
10167 +               if ((regs->ip + 9) >> 32)
10168 +                       break;
10169 +#endif
10170 +
10171 +               err = get_user(mov, (unsigned char __user *)regs->ip);
10172 +               err |= get_user(addr1, (unsigned int __user *)(regs->ip + 1));
10173 +               err |= get_user(jmp, (unsigned char __user *)(regs->ip + 5));
10174 +               err |= get_user(addr2, (unsigned int __user *)(regs->ip + 6));
10175 +
10176 +               if (err)
10177 +                       break;
10178 +
10179 +               if (mov == 0xB9 && jmp == 0xE9) {
10180 +                       regs->cx = addr1;
10181 +                       regs->ip = (unsigned int)(regs->ip + addr2 + 10);
10182 +                       return 2;
10183 +               }
10184 +       } while (0);
10185 +
10186 +       return 1; /* PaX in action */
10187 +}
10188 +
10189 +#ifdef CONFIG_X86_64
10190 +static int pax_handle_fetch_fault_64(struct pt_regs *regs)
10191 +{
10192 +       int err;
10193 +
10194 +       do { /* PaX: gcc trampoline emulation #1 */
10195 +               unsigned short mov1, mov2, jmp1;
10196 +               unsigned char jmp2;
10197 +               unsigned int addr1;
10198 +               unsigned long addr2;
10199 +
10200 +               err = get_user(mov1, (unsigned short __user *)regs->ip);
10201 +               err |= get_user(addr1, (unsigned int __user *)(regs->ip + 2));
10202 +               err |= get_user(mov2, (unsigned short __user *)(regs->ip + 6));
10203 +               err |= get_user(addr2, (unsigned long __user *)(regs->ip + 8));
10204 +               err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 16));
10205 +               err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 18));
10206 +
10207 +               if (err)
10208 +                       break;
10209 +
10210 +               if (mov1 == 0xBB41 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10211 +                       regs->r11 = addr1;
10212 +                       regs->r10 = addr2;
10213 +                       regs->ip = addr1;
10214 +                       return 2;
10215 +               }
10216 +       } while (0);
10217 +
10218 +       do { /* PaX: gcc trampoline emulation #2 */
10219 +               unsigned short mov1, mov2, jmp1;
10220 +               unsigned char jmp2;
10221 +               unsigned long addr1, addr2;
10222 +
10223 +               err = get_user(mov1, (unsigned short __user *)regs->ip);
10224 +               err |= get_user(addr1, (unsigned long __user *)(regs->ip + 2));
10225 +               err |= get_user(mov2, (unsigned short __user *)(regs->ip + 10));
10226 +               err |= get_user(addr2, (unsigned long __user *)(regs->ip + 12));
10227 +               err |= get_user(jmp1, (unsigned short __user *)(regs->ip + 20));
10228 +               err |= get_user(jmp2, (unsigned char __user *)(regs->ip + 22));
10229 +
10230 +               if (err)
10231 +                       break;
10232 +
10233 +               if (mov1 == 0xBB49 && mov2 == 0xBA49 && jmp1 == 0xFF49 && jmp2 == 0xE3) {
10234 +                       regs->r11 = addr1;
10235 +                       regs->r10 = addr2;
10236 +                       regs->ip = addr1;
10237 +                       return 2;
10238 +               }
10239 +       } while (0);
10240 +
10241 +       return 1; /* PaX in action */
10242 +}
10243 +#endif
10244 +
10245 +/*
10246 + * PaX: decide what to do with offenders (regs->ip = fault address)
10247 + *
10248 + * returns 1 when task should be killed
10249 + *         2 when gcc trampoline was detected
10250 + */
10251 +static int pax_handle_fetch_fault(struct pt_regs *regs)
10252 +{
10253 +       if (v8086_mode(regs))
10254 +               return 1;
10255 +
10256 +       if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP))
10257 +               return 1;
10258 +
10259 +#ifdef CONFIG_X86_32
10260 +       return pax_handle_fetch_fault_32(regs);
10261 +#else
10262 +       if (regs->cs == __USER32_CS || (regs->cs & SEGMENT_LDT))
10263 +               return pax_handle_fetch_fault_32(regs);
10264 +       else
10265 +               return pax_handle_fetch_fault_64(regs);
10266 +#endif
10267 +}
10268 +#endif
10269 +
10270 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10271 +void pax_report_insns(void *pc, void *sp)
10272 +{
10273 +       long i;
10274 +
10275 +       printk(KERN_ERR "PAX: bytes at PC: ");
10276 +       for (i = 0; i < 20; i++) {
10277 +               unsigned char c;
10278 +               if (get_user(c, (unsigned char __user *)pc+i))
10279 +                       printk(KERN_CONT "?? ");
10280 +               else
10281 +                       printk(KERN_CONT "%02x ", c);
10282 +       }
10283 +       printk("\n");
10284 +
10285 +       printk(KERN_ERR "PAX: bytes at SP-%lu: ", (unsigned long)sizeof(long));
10286 +       for (i = -1; i < 80 / sizeof(long); i++) {
10287 +               unsigned long c;
10288 +               if (get_user(c, (unsigned long __user *)sp+i))
10289 +#ifdef CONFIG_X86_32
10290 +                       printk(KERN_CONT "???????? ");
10291 +#else
10292 +                       printk(KERN_CONT "???????????????? ");
10293 +#endif
10294 +               else
10295 +                       printk(KERN_CONT "%0*lx ", 2 * (int)sizeof(long), c);
10296 +       }
10297 +       printk("\n");
10298 +}
10299 +#endif
10300 diff -urNp linux-2.6.27.10/arch/x86/mm/highmem_32.c linux-2.6.27.10/arch/x86/mm/highmem_32.c
10301 --- linux-2.6.27.10/arch/x86/mm/highmem_32.c    2008-11-07 12:55:34.000000000 -0500
10302 +++ linux-2.6.27.10/arch/x86/mm/highmem_32.c    2008-11-18 03:38:44.000000000 -0500
10303 @@ -74,6 +74,10 @@ void *kmap_atomic_prot(struct page *page
10304         enum fixed_addresses idx;
10305         unsigned long vaddr;
10306  
10307 +#ifdef CONFIG_PAX_KERNEXEC
10308 +       unsigned long cr0;
10309 +#endif
10310 +
10311         /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
10312         pagefault_disable();
10313  
10314 @@ -85,7 +89,17 @@ void *kmap_atomic_prot(struct page *page
10315         idx = type + KM_TYPE_NR*smp_processor_id();
10316         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10317         BUG_ON(!pte_none(*(kmap_pte-idx)));
10318 +
10319 +#ifdef CONFIG_PAX_KERNEXEC
10320 +       pax_open_kernel(cr0);
10321 +#endif
10322 +
10323         set_pte(kmap_pte-idx, mk_pte(page, prot));
10324 +
10325 +#ifdef CONFIG_PAX_KERNEXEC
10326 +       pax_close_kernel(cr0);
10327 +#endif
10328 +
10329         arch_flush_lazy_mmu_mode();
10330  
10331         return (void *)vaddr;
10332 @@ -101,15 +115,29 @@ void kunmap_atomic(void *kvaddr, enum km
10333         unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
10334         enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
10335  
10336 +#ifdef CONFIG_PAX_KERNEXEC
10337 +       unsigned long cr0;
10338 +#endif
10339 +
10340         /*
10341          * Force other mappings to Oops if they'll try to access this pte
10342          * without first remap it.  Keeping stale mappings around is a bad idea
10343          * also, in case the page changes cacheability attributes or becomes
10344          * a protected page in a hypervisor.
10345          */
10346 -       if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx))
10347 +       if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
10348 +
10349 +#ifdef CONFIG_PAX_KERNEXEC
10350 +               pax_open_kernel(cr0);
10351 +#endif
10352 +
10353                 kpte_clear_flush(kmap_pte-idx, vaddr);
10354 -       else {
10355 +
10356 +#ifdef CONFIG_PAX_KERNEXEC
10357 +               pax_close_kernel(cr0);
10358 +#endif
10359 +
10360 +       } else {
10361  #ifdef CONFIG_DEBUG_HIGHMEM
10362                 BUG_ON(vaddr < PAGE_OFFSET);
10363                 BUG_ON(vaddr >= (unsigned long)high_memory);
10364 @@ -128,11 +156,25 @@ void *kmap_atomic_pfn(unsigned long pfn,
10365         enum fixed_addresses idx;
10366         unsigned long vaddr;
10367  
10368 +#ifdef CONFIG_PAX_KERNEXEC
10369 +       unsigned long cr0;
10370 +#endif
10371 +
10372         pagefault_disable();
10373  
10374         idx = type + KM_TYPE_NR*smp_processor_id();
10375         vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
10376 +
10377 +#ifdef CONFIG_PAX_KERNEXEC
10378 +       pax_open_kernel(cr0);
10379 +#endif
10380 +
10381         set_pte(kmap_pte-idx, pfn_pte(pfn, kmap_prot));
10382 +
10383 +#ifdef CONFIG_PAX_KERNEXEC
10384 +       pax_close_kernel(cr0);
10385 +#endif
10386 +
10387         arch_flush_lazy_mmu_mode();
10388  
10389         return (void*) vaddr;
10390 diff -urNp linux-2.6.27.10/arch/x86/mm/hugetlbpage.c linux-2.6.27.10/arch/x86/mm/hugetlbpage.c
10391 --- linux-2.6.27.10/arch/x86/mm/hugetlbpage.c   2008-11-07 12:55:34.000000000 -0500
10392 +++ linux-2.6.27.10/arch/x86/mm/hugetlbpage.c   2008-11-18 03:38:44.000000000 -0500
10393 @@ -263,13 +263,18 @@ static unsigned long hugetlb_get_unmappe
10394         struct hstate *h = hstate_file(file);
10395         struct mm_struct *mm = current->mm;
10396         struct vm_area_struct *vma;
10397 -       unsigned long start_addr;
10398 +       unsigned long start_addr, pax_task_size = TASK_SIZE;
10399 +
10400 +#ifdef CONFIG_PAX_SEGMEXEC
10401 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
10402 +               pax_task_size = SEGMEXEC_TASK_SIZE;
10403 +#endif
10404  
10405         if (len > mm->cached_hole_size) {
10406 -               start_addr = mm->free_area_cache;
10407 +               start_addr = mm->free_area_cache;
10408         } else {
10409 -               start_addr = TASK_UNMAPPED_BASE;
10410 -               mm->cached_hole_size = 0;
10411 +               start_addr = mm->mmap_base;
10412 +               mm->cached_hole_size = 0;
10413         }
10414  
10415  full_search:
10416 @@ -277,13 +282,13 @@ full_search:
10417  
10418         for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
10419                 /* At this point:  (!vma || addr < vma->vm_end). */
10420 -               if (TASK_SIZE - len < addr) {
10421 +               if (pax_task_size - len < addr) {
10422                         /*
10423                          * Start a new search - just in case we missed
10424                          * some holes.
10425                          */
10426 -                       if (start_addr != TASK_UNMAPPED_BASE) {
10427 -                               start_addr = TASK_UNMAPPED_BASE;
10428 +                       if (start_addr != mm->mmap_base) {
10429 +                               start_addr = mm->mmap_base;
10430                                 mm->cached_hole_size = 0;
10431                                 goto full_search;
10432                         }
10433 @@ -306,9 +311,8 @@ static unsigned long hugetlb_get_unmappe
10434         struct hstate *h = hstate_file(file);
10435         struct mm_struct *mm = current->mm;
10436         struct vm_area_struct *vma, *prev_vma;
10437 -       unsigned long base = mm->mmap_base, addr = addr0;
10438 +       unsigned long base = mm->mmap_base, addr;
10439         unsigned long largest_hole = mm->cached_hole_size;
10440 -       int first_time = 1;
10441  
10442         /* don't allow allocations above current base */
10443         if (mm->free_area_cache > base)
10444 @@ -318,7 +322,7 @@ static unsigned long hugetlb_get_unmappe
10445                 largest_hole = 0;
10446                 mm->free_area_cache  = base;
10447         }
10448 -try_again:
10449 +
10450         /* make sure it can fit in the remaining address space */
10451         if (mm->free_area_cache < len)
10452                 goto fail;
10453 @@ -360,22 +364,26 @@ try_again:
10454  
10455  fail:
10456         /*
10457 -        * if hint left us with no space for the requested
10458 -        * mapping then try again:
10459 -        */
10460 -       if (first_time) {
10461 -               mm->free_area_cache = base;
10462 -               largest_hole = 0;
10463 -               first_time = 0;
10464 -               goto try_again;
10465 -       }
10466 -       /*
10467          * A failed mmap() very likely causes application failure,
10468          * so fall back to the bottom-up function here. This scenario
10469          * can happen with large stack limits and large mmap()
10470          * allocations.
10471          */
10472 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
10473 +
10474 +#ifdef CONFIG_PAX_SEGMEXEC
10475 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
10476 +               mm->mmap_base = SEGMEXEC_TASK_UNMAPPED_BASE;
10477 +       else
10478 +#endif
10479 +
10480 +       mm->mmap_base = TASK_UNMAPPED_BASE;
10481 +
10482 +#ifdef CONFIG_PAX_RANDMMAP
10483 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
10484 +               mm->mmap_base += mm->delta_mmap;
10485 +#endif
10486 +
10487 +       mm->free_area_cache = mm->mmap_base;
10488         mm->cached_hole_size = ~0UL;
10489         addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
10490                         len, pgoff, flags);
10491 @@ -383,6 +391,7 @@ fail:
10492         /*
10493          * Restore the topdown base:
10494          */
10495 +       mm->mmap_base = base;
10496         mm->free_area_cache = base;
10497         mm->cached_hole_size = ~0UL;
10498  
10499 @@ -396,10 +405,17 @@ hugetlb_get_unmapped_area(struct file *f
10500         struct hstate *h = hstate_file(file);
10501         struct mm_struct *mm = current->mm;
10502         struct vm_area_struct *vma;
10503 +       unsigned long pax_task_size = TASK_SIZE;
10504  
10505         if (len & ~huge_page_mask(h))
10506                 return -EINVAL;
10507 -       if (len > TASK_SIZE)
10508 +
10509 +#ifdef CONFIG_PAX_SEGMEXEC
10510 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
10511 +               pax_task_size = SEGMEXEC_TASK_SIZE;
10512 +#endif
10513 +
10514 +       if (len > pax_task_size)
10515                 return -ENOMEM;
10516  
10517         if (flags & MAP_FIXED) {
10518 @@ -411,7 +427,7 @@ hugetlb_get_unmapped_area(struct file *f
10519         if (addr) {
10520                 addr = ALIGN(addr, huge_page_size(h));
10521                 vma = find_vma(mm, addr);
10522 -               if (TASK_SIZE - len >= addr &&
10523 +               if (pax_task_size - len >= addr &&
10524                     (!vma || addr + len <= vma->vm_start))
10525                         return addr;
10526         }
10527 diff -urNp linux-2.6.27.10/arch/x86/mm/init_32.c linux-2.6.27.10/arch/x86/mm/init_32.c
10528 --- linux-2.6.27.10/arch/x86/mm/init_32.c       2008-11-07 12:55:34.000000000 -0500
10529 +++ linux-2.6.27.10/arch/x86/mm/init_32.c       2008-11-18 03:38:44.000000000 -0500
10530 @@ -47,6 +47,7 @@
10531  #include <asm/paravirt.h>
10532  #include <asm/setup.h>
10533  #include <asm/cacheflush.h>
10534 +#include <asm/desc.h>
10535  
10536  unsigned int __VMALLOC_RESERVE = 128 << 20;
10537  
10538 @@ -80,35 +81,6 @@ static __init void *alloc_low_page(unsig
10539  }
10540  
10541  /*
10542 - * Creates a middle page table and puts a pointer to it in the
10543 - * given global directory entry. This only returns the gd entry
10544 - * in non-PAE compilation mode, since the middle layer is folded.
10545 - */
10546 -static pmd_t * __init one_md_table_init(pgd_t *pgd)
10547 -{
10548 -       pud_t *pud;
10549 -       pmd_t *pmd_table;
10550 -
10551 -#ifdef CONFIG_X86_PAE
10552 -       unsigned long phys;
10553 -       if (!(pgd_val(*pgd) & _PAGE_PRESENT)) {
10554 -               if (after_init_bootmem)
10555 -                       pmd_table = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
10556 -               else
10557 -                       pmd_table = (pmd_t *)alloc_low_page(&phys);
10558 -               paravirt_alloc_pmd(&init_mm, __pa(pmd_table) >> PAGE_SHIFT);
10559 -               set_pgd(pgd, __pgd(__pa(pmd_table) | _PAGE_PRESENT));
10560 -               pud = pud_offset(pgd, 0);
10561 -               BUG_ON(pmd_table != pmd_offset(pud, 0));
10562 -       }
10563 -#endif
10564 -       pud = pud_offset(pgd, 0);
10565 -       pmd_table = pmd_offset(pud, 0);
10566 -
10567 -       return pmd_table;
10568 -}
10569 -
10570 -/*
10571   * Create a page table and place a pointer to it in a middle page
10572   * directory entry:
10573   */
10574 @@ -130,7 +102,11 @@ static pte_t * __init one_page_table_ini
10575                 }
10576  
10577                 paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
10578 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
10579 +               set_pmd(pmd, __pmd(__pa(page_table) | _KERNPG_TABLE));
10580 +#else
10581                 set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
10582 +#endif
10583                 BUG_ON(page_table != pte_offset_kernel(pmd, 0));
10584         }
10585  
10586 @@ -152,6 +128,7 @@ page_table_range_init(unsigned long star
10587         int pgd_idx, pmd_idx;
10588         unsigned long vaddr;
10589         pgd_t *pgd;
10590 +       pud_t *pud;
10591         pmd_t *pmd;
10592  
10593         vaddr = start;
10594 @@ -160,8 +137,13 @@ page_table_range_init(unsigned long star
10595         pgd = pgd_base + pgd_idx;
10596  
10597         for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
10598 -               pmd = one_md_table_init(pgd);
10599 -               pmd = pmd + pmd_index(vaddr);
10600 +               pud = pud_offset(pgd, vaddr);
10601 +               pmd = pmd_offset(pud, vaddr);
10602 +
10603 +#ifdef CONFIG_X86_PAE
10604 +               paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10605 +#endif
10606 +
10607                 for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end);
10608                                                         pmd++, pmd_idx++) {
10609                         one_page_table_init(pmd);
10610 @@ -172,11 +154,23 @@ page_table_range_init(unsigned long star
10611         }
10612  }
10613  
10614 -static inline int is_kernel_text(unsigned long addr)
10615 +static inline int is_kernel_text(unsigned long start, unsigned long end)
10616  {
10617 -       if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
10618 -               return 1;
10619 -       return 0;
10620 +       unsigned long etext;
10621 +
10622 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
10623 +       etext = ktva_ktla((unsigned long)&MODULES_END);
10624 +#else
10625 +       etext = (unsigned long)&_etext;
10626 +#endif
10627 +
10628 +       if ((start > ktla_ktva(etext) ||
10629 +            end <= ktla_ktva((unsigned long)_stext)) &&
10630 +           (start > ktla_ktva((unsigned long)_einittext) ||
10631 +            end <= ktla_ktva((unsigned long)_sinittext)) &&
10632 +           (start > (unsigned long)__va(0xfffff) || end <= (unsigned long)__va(0xc0000)))
10633 +               return 0;
10634 +       return 1;
10635  }
10636  
10637  /*
10638 @@ -189,9 +183,10 @@ static void __init kernel_physical_mappi
10639                                                 unsigned long end_pfn,
10640                                                 int use_pse)
10641  {
10642 -       int pgd_idx, pmd_idx, pte_ofs;
10643 +       unsigned int pgd_idx, pmd_idx, pte_ofs;
10644         unsigned long pfn;
10645         pgd_t *pgd;
10646 +       pud_t *pud;
10647         pmd_t *pmd;
10648         pte_t *pte;
10649         unsigned pages_2m = 0, pages_4k = 0;
10650 @@ -202,8 +197,13 @@ static void __init kernel_physical_mappi
10651         pfn = start_pfn;
10652         pgd_idx = pgd_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10653         pgd = pgd_base + pgd_idx;
10654 -       for (; pgd_idx < PTRS_PER_PGD; pgd++, pgd_idx++) {
10655 -               pmd = one_md_table_init(pgd);
10656 +       for (; pgd_idx < PTRS_PER_PGD && pfn < max_low_pfn; pgd++, pgd_idx++) {
10657 +               pud = pud_offset(pgd, 0);
10658 +               pmd = pmd_offset(pud, 0);
10659 +
10660 +#ifdef CONFIG_X86_PAE
10661 +               paravirt_alloc_pmd(&init_mm, __pa(pmd) >> PAGE_SHIFT);
10662 +#endif
10663  
10664                 if (pfn >= end_pfn)
10665                         continue;
10666 @@ -215,21 +215,16 @@ static void __init kernel_physical_mappi
10667  #endif
10668                 for (; pmd_idx < PTRS_PER_PMD && pfn < end_pfn;
10669                      pmd++, pmd_idx++) {
10670 -                       unsigned int addr = pfn * PAGE_SIZE + PAGE_OFFSET;
10671 +                       unsigned long address = pfn * PAGE_SIZE + PAGE_OFFSET;
10672  
10673                         /*
10674                          * Map with big pages if possible, otherwise
10675                          * create normal page tables:
10676                          */
10677                         if (use_pse) {
10678 -                               unsigned int addr2;
10679                                 pgprot_t prot = PAGE_KERNEL_LARGE;
10680  
10681 -                               addr2 = (pfn + PTRS_PER_PTE-1) * PAGE_SIZE +
10682 -                                       PAGE_OFFSET + PAGE_SIZE-1;
10683 -
10684 -                               if (is_kernel_text(addr) ||
10685 -                                   is_kernel_text(addr2))
10686 +                               if (is_kernel_text(address, address + PMD_SIZE))
10687                                         prot = PAGE_KERNEL_LARGE_EXEC;
10688  
10689                                 pages_2m++;
10690 @@ -243,10 +238,10 @@ static void __init kernel_physical_mappi
10691                         pte_ofs = pte_index((pfn<<PAGE_SHIFT) + PAGE_OFFSET);
10692                         pte += pte_ofs;
10693                         for (; pte_ofs < PTRS_PER_PTE && pfn < end_pfn;
10694 -                            pte++, pfn++, pte_ofs++, addr += PAGE_SIZE) {
10695 +                            pte++, pfn++, pte_ofs++, address += PAGE_SIZE) {
10696                                 pgprot_t prot = PAGE_KERNEL;
10697  
10698 -                               if (is_kernel_text(addr))
10699 +                               if (is_kernel_text(address, address + PAGE_SIZE))
10700                                         prot = PAGE_KERNEL_EXEC;
10701  
10702                                 pages_4k++;
10703 @@ -270,7 +265,9 @@ static void __init kernel_physical_mappi
10704   */
10705  int devmem_is_allowed(unsigned long pagenr)
10706  {
10707 -       if (pagenr <= 256)
10708 +       if (!pagenr)
10709 +               return 1;
10710 +       if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10711                 return 1;
10712         if (!page_is_ram(pagenr))
10713                 return 1;
10714 @@ -404,7 +401,7 @@ void __init native_pagetable_setup_start
10715  
10716                 pud = pud_offset(pgd, va);
10717                 pmd = pmd_offset(pud, va);
10718 -               if (!pmd_present(*pmd))
10719 +               if (!pmd_present(*pmd) || pmd_huge(*pmd))
10720                         break;
10721  
10722                 pte = pte_offset_kernel(pmd, va);
10723 @@ -456,9 +453,7 @@ static void __init early_ioremap_page_ta
10724  
10725  static void __init pagetable_init(void)
10726  {
10727 -       pgd_t *pgd_base = swapper_pg_dir;
10728 -
10729 -       permanent_kmaps_init(pgd_base);
10730 +       permanent_kmaps_init(swapper_pg_dir);
10731  }
10732  
10733  #ifdef CONFIG_ACPI_SLEEP
10734 @@ -466,12 +461,12 @@ static void __init pagetable_init(void)
10735   * ACPI suspend needs this for resume, because things like the intel-agp
10736   * driver might have split up a kernel 4MB mapping.
10737   */
10738 -char swsusp_pg_dir[PAGE_SIZE]
10739 +pgd_t swsusp_pg_dir[PTRS_PER_PGD]
10740         __attribute__ ((aligned(PAGE_SIZE)));
10741  
10742  static inline void save_pg_dir(void)
10743  {
10744 -       memcpy(swsusp_pg_dir, swapper_pg_dir, PAGE_SIZE);
10745 +       clone_pgd_range(swsusp_pg_dir, swapper_pg_dir, PTRS_PER_PGD);
10746  }
10747  #else /* !CONFIG_ACPI_SLEEP */
10748  static inline void save_pg_dir(void)
10749 @@ -501,13 +496,11 @@ void zap_low_mappings(void)
10750  
10751  int nx_enabled;
10752  
10753 -pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL);
10754 +pteval_t __supported_pte_mask __read_only = ~(_PAGE_NX | _PAGE_GLOBAL);
10755  EXPORT_SYMBOL_GPL(__supported_pte_mask);
10756  
10757  #ifdef CONFIG_X86_PAE
10758  
10759 -static int disable_nx __initdata;
10760 -
10761  /*
10762   * noexec = on|off
10763   *
10764 @@ -516,40 +509,33 @@ static int disable_nx __initdata;
10765   * on      Enable
10766   * off     Disable
10767   */
10768 +#if !defined(CONFIG_PAX_PAGEEXEC)
10769  static int __init noexec_setup(char *str)
10770  {
10771         if (!str || !strcmp(str, "on")) {
10772 -               if (cpu_has_nx) {
10773 -                       __supported_pte_mask |= _PAGE_NX;
10774 -                       disable_nx = 0;
10775 -               }
10776 +               if (cpu_has_nx)
10777 +                       nx_enabled = 1;
10778         } else {
10779 -               if (!strcmp(str, "off")) {
10780 -                       disable_nx = 1;
10781 -                       __supported_pte_mask &= ~_PAGE_NX;
10782 -               } else {
10783 +               if (!strcmp(str, "off"))
10784 +                       nx_enabled = 0;
10785 +               else
10786                         return -EINVAL;
10787 -               }
10788         }
10789  
10790         return 0;
10791  }
10792  early_param("noexec", noexec_setup);
10793 +#endif
10794  
10795  static void __init set_nx(void)
10796  {
10797 -       unsigned int v[4], l, h;
10798 -
10799 -       if (cpu_has_pae && (cpuid_eax(0x80000000) > 0x80000001)) {
10800 -               cpuid(0x80000001, &v[0], &v[1], &v[2], &v[3]);
10801 +       if (!nx_enabled && cpu_has_nx) {
10802 +               unsigned l, h;
10803  
10804 -               if ((v[3] & (1 << 20)) && !disable_nx) {
10805 -                       rdmsr(MSR_EFER, l, h);
10806 -                       l |= EFER_NX;
10807 -                       wrmsr(MSR_EFER, l, h);
10808 -                       nx_enabled = 1;
10809 -                       __supported_pte_mask |= _PAGE_NX;
10810 -               }
10811 +               __supported_pte_mask &= ~_PAGE_NX;
10812 +               rdmsr(MSR_EFER, l, h);
10813 +               l &= ~EFER_NX;
10814 +               wrmsr(MSR_EFER, l, h);
10815         }
10816  }
10817  #endif
10818 @@ -920,7 +906,7 @@ void __init mem_init(void)
10819         set_highmem_pages_init();
10820  
10821         codesize =  (unsigned long) &_etext - (unsigned long) &_text;
10822 -       datasize =  (unsigned long) &_edata - (unsigned long) &_etext;
10823 +       datasize =  (unsigned long) &_edata - (unsigned long) &_data;
10824         initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;
10825  
10826         kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT);
10827 @@ -966,10 +952,10 @@ void __init mem_init(void)
10828                 ((unsigned long)&__init_end -
10829                  (unsigned long)&__init_begin) >> 10,
10830  
10831 -               (unsigned long)&_etext, (unsigned long)&_edata,
10832 -               ((unsigned long)&_edata - (unsigned long)&_etext) >> 10,
10833 +               (unsigned long)&_data, (unsigned long)&_edata,
10834 +               ((unsigned long)&_edata - (unsigned long)&_data) >> 10,
10835  
10836 -               (unsigned long)&_text, (unsigned long)&_etext,
10837 +               ktla_ktva((unsigned long)&_text), ktla_ktva((unsigned long)&_etext),
10838                 ((unsigned long)&_etext - (unsigned long)&_text) >> 10);
10839  
10840  #ifdef CONFIG_HIGHMEM
10841 @@ -1099,6 +1085,46 @@ void free_init_pages(char *what, unsigne
10842  
10843  void free_initmem(void)
10844  {
10845 +
10846 +#ifdef CONFIG_PAX_KERNEXEC
10847 +       /* PaX: limit KERNEL_CS to actual size */
10848 +       unsigned long addr, limit;
10849 +       struct desc_struct d;
10850 +       int cpu;
10851 +       pgd_t *pgd;
10852 +       pud_t *pud;
10853 +       pmd_t *pmd;
10854 +
10855 +#ifdef CONFIG_MODULES
10856 +       limit = ktva_ktla((unsigned long)&MODULES_END);
10857 +#else
10858 +       limit = (unsigned long)&_etext;
10859 +#endif
10860 +       limit = (limit - 1UL) >> PAGE_SHIFT;
10861 +
10862 +       for (cpu = 0; cpu < NR_CPUS; cpu++) {
10863 +               pack_descriptor(&d, get_desc_base(&get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_CS]), limit, 0x9B, 0xC);
10864 +               write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_KERNEL_CS, &d, DESCTYPE_S);
10865 +       }
10866 +
10867 +       /* PaX: make KERNEL_CS read-only */
10868 +       for (addr = ktla_ktva((unsigned long)&_text); addr < (unsigned long)&_data; addr += PMD_SIZE) {
10869 +               pgd = pgd_offset_k(addr);
10870 +               pud = pud_offset(pgd, addr);
10871 +               pmd = pmd_offset(pud, addr);
10872 +               set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10873 +       }
10874 +#ifdef CONFIG_X86_PAE
10875 +       for (addr = (unsigned long)&__init_begin; addr < (unsigned long)&__init_end; addr += PMD_SIZE) {
10876 +               pgd = pgd_offset_k(addr);
10877 +               pud = pud_offset(pgd, addr);
10878 +               pmd = pmd_offset(pud, addr);
10879 +               set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10880 +       }
10881 +#endif
10882 +       flush_tlb_all();
10883 +#endif
10884 +
10885         free_init_pages("unused kernel memory",
10886                         (unsigned long)(&__init_begin),
10887                         (unsigned long)(&__init_end));
10888 diff -urNp linux-2.6.27.10/arch/x86/mm/init_64.c linux-2.6.27.10/arch/x86/mm/init_64.c
10889 --- linux-2.6.27.10/arch/x86/mm/init_64.c       2008-12-21 01:16:51.000000000 -0500
10890 +++ linux-2.6.27.10/arch/x86/mm/init_64.c       2008-12-21 01:13:45.000000000 -0500
10891 @@ -118,6 +118,10 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10892         pmd_t *pmd;
10893         pte_t *pte;
10894  
10895 +#ifdef CONFIG_PAX_KERNEXEC
10896 +       unsigned long cr0;
10897 +#endif
10898 +
10899         pud = pud_page + pud_index(vaddr);
10900         if (pud_none(*pud)) {
10901                 pmd = (pmd_t *) spp_getpage();
10902 @@ -142,8 +146,17 @@ set_pte_vaddr_pud(pud_t *pud_page, unsig
10903         if (!pte_none(*pte) && pte_val(new_pte) &&
10904             pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
10905                 pte_ERROR(*pte);
10906 +
10907 +#ifdef CONFIG_PAX_KERNEXEC
10908 +       pax_open_kernel(cr0);
10909 +#endif
10910 +
10911         set_pte(pte, new_pte);
10912  
10913 +#ifdef CONFIG_PAX_KERNEXEC
10914 +       pax_close_kernel(cr0);
10915 +#endif
10916 +
10917         /*
10918          * It's enough to flush this one mapping.
10919          * (PGE mappings get flushed as well)
10920 @@ -184,14 +197,12 @@ static void __init __init_extra_mapping(
10921                 pgd = pgd_offset_k((unsigned long)__va(phys));
10922                 if (pgd_none(*pgd)) {
10923                         pud = (pud_t *) spp_getpage();
10924 -                       set_pgd(pgd, __pgd(__pa(pud) | _KERNPG_TABLE |
10925 -                                               _PAGE_USER));
10926 +                       set_pgd(pgd, __pgd(__pa(pud) | _PAGE_TABLE));
10927                 }
10928                 pud = pud_offset(pgd, (unsigned long)__va(phys));
10929                 if (pud_none(*pud)) {
10930                         pmd = (pmd_t *) spp_getpage();
10931 -                       set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE |
10932 -                                               _PAGE_USER));
10933 +                       set_pud(pud, __pud(__pa(pmd) | _PAGE_TABLE));
10934                 }
10935                 pmd = pmd_offset(pud, phys);
10936                 BUG_ON(!pmd_none(*pmd));
10937 @@ -754,7 +765,9 @@ EXPORT_SYMBOL_GPL(memory_add_physaddr_to
10938   */
10939  int devmem_is_allowed(unsigned long pagenr)
10940  {
10941 -       if (pagenr <= 256)
10942 +       if (!pagenr)
10943 +               return 1;
10944 +       if ((ISA_START_ADDRESS >> PAGE_SHIFT) <= pagenr && pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
10945                 return 1;
10946         if (!page_is_ram(pagenr))
10947                 return 1;
10948 @@ -842,6 +855,39 @@ void free_init_pages(char *what, unsigne
10949  
10950  void free_initmem(void)
10951  {
10952 +
10953 +#ifdef CONFIG_PAX_KERNEXEC
10954 +       unsigned long addr, end;
10955 +       pgd_t *pgd;
10956 +       pud_t *pud;
10957 +       pmd_t *pmd;
10958 +
10959 +       /* PaX: make kernel code/rodata read-only, rest non-executable */
10960 +       for (addr = __START_KERNEL_map; addr < __START_KERNEL_map + KERNEL_IMAGE_SIZE; addr += PMD_SIZE) {
10961 +               pgd = pgd_offset_k(addr);
10962 +               pud = pud_offset(pgd, addr);
10963 +               pmd = pmd_offset(pud, addr);
10964 +               if ((unsigned long)_text <= addr && addr < (unsigned long)_data)
10965 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10966 +               else
10967 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10968 +       }
10969 +
10970 +       addr = (unsigned long)__va(__pa(__START_KERNEL_map));
10971 +       end = addr + KERNEL_IMAGE_SIZE;
10972 +       for (; addr < end; addr += PMD_SIZE) {
10973 +               pgd = pgd_offset_k(addr);
10974 +               pud = pud_offset(pgd, addr);
10975 +               pmd = pmd_offset(pud, addr);
10976 +               if ((unsigned long)__va(__pa(_text)) <= addr && addr < (unsigned long)__va(__pa(_data)))
10977 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_RW));
10978 +               else
10979 +                       set_pmd(pmd, __pmd(pmd_val(*pmd) | (_PAGE_NX & __supported_pte_mask)));
10980 +       }
10981 +
10982 +       flush_tlb_all();
10983 +#endif
10984 +
10985         free_init_pages("unused kernel memory",
10986                         (unsigned long)(&__init_begin),
10987                         (unsigned long)(&__init_end));
10988 @@ -1014,7 +1060,7 @@ int in_gate_area_no_task(unsigned long a
10989  
10990  const char *arch_vma_name(struct vm_area_struct *vma)
10991  {
10992 -       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
10993 +       if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
10994                 return "[vdso]";
10995         if (vma == &gate_vma)
10996                 return "[vsyscall]";
10997 diff -urNp linux-2.6.27.10/arch/x86/mm/ioremap.c linux-2.6.27.10/arch/x86/mm/ioremap.c
10998 --- linux-2.6.27.10/arch/x86/mm/ioremap.c       2008-11-07 12:55:34.000000000 -0500
10999 +++ linux-2.6.27.10/arch/x86/mm/ioremap.c       2008-11-18 03:38:44.000000000 -0500
11000 @@ -63,8 +63,8 @@ int page_is_ram(unsigned long pagenr)
11001          * Second special case: Some BIOSen report the PC BIOS
11002          * area (640->1Mb) as ram even though it is not.
11003          */
11004 -       if (pagenr >= (BIOS_BEGIN >> PAGE_SHIFT) &&
11005 -                   pagenr < (BIOS_END >> PAGE_SHIFT))
11006 +       if (pagenr >= (ISA_START_ADDRESS >> PAGE_SHIFT) &&
11007 +                   pagenr < (ISA_END_ADDRESS >> PAGE_SHIFT))
11008                 return 0;
11009  
11010         for (i = 0; i < e820.nr_map; i++) {
11011 @@ -217,6 +217,8 @@ static void __iomem *__ioremap_caller(re
11012                 break;
11013         }
11014  
11015 +       prot = canon_pgprot(prot);
11016 +
11017         /*
11018          * Ok, go for it..
11019          */
11020 diff -urNp linux-2.6.27.10/arch/x86/mm/mmap.c linux-2.6.27.10/arch/x86/mm/mmap.c
11021 --- linux-2.6.27.10/arch/x86/mm/mmap.c  2008-11-07 12:55:34.000000000 -0500
11022 +++ linux-2.6.27.10/arch/x86/mm/mmap.c  2008-11-18 03:38:44.000000000 -0500
11023 @@ -36,7 +36,7 @@
11024   * Leave an at least ~128 MB hole.
11025   */
11026  #define MIN_GAP (128*1024*1024)
11027 -#define MAX_GAP (TASK_SIZE/6*5)
11028 +#define MAX_GAP (pax_task_size/6*5)
11029  
11030  /*
11031   * True on X86_32 or when emulating IA32 on X86_64
11032 @@ -81,27 +81,40 @@ static unsigned long mmap_rnd(void)
11033         return rnd << PAGE_SHIFT;
11034  }
11035  
11036 -static unsigned long mmap_base(void)
11037 +static unsigned long mmap_base(struct mm_struct *mm)
11038  {
11039         unsigned long gap = current->signal->rlim[RLIMIT_STACK].rlim_cur;
11040 +       unsigned long pax_task_size = TASK_SIZE;
11041 +
11042 +#ifdef CONFIG_PAX_SEGMEXEC
11043 +       if (mm->pax_flags & MF_PAX_SEGMEXEC)
11044 +               pax_task_size = SEGMEXEC_TASK_SIZE;
11045 +#endif
11046  
11047         if (gap < MIN_GAP)
11048                 gap = MIN_GAP;
11049         else if (gap > MAX_GAP)
11050                 gap = MAX_GAP;
11051  
11052 -       return PAGE_ALIGN(TASK_SIZE - gap - mmap_rnd());
11053 +       return PAGE_ALIGN(pax_task_size - gap - mmap_rnd());
11054  }
11055  
11056  /*
11057   * Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
11058   * does, but not when emulating X86_32
11059   */
11060 -static unsigned long mmap_legacy_base(void)
11061 +static unsigned long mmap_legacy_base(struct mm_struct *mm)
11062  {
11063 -       if (mmap_is_ia32())
11064 +       if (mmap_is_ia32()) {
11065 +
11066 +#ifdef CONFIG_PAX_SEGMEXEC
11067 +               if (mm->pax_flags & MF_PAX_SEGMEXEC)
11068 +                       return SEGMEXEC_TASK_UNMAPPED_BASE;
11069 +               else
11070 +#endif
11071 +
11072                 return TASK_UNMAPPED_BASE;
11073 -       else
11074 +       } else
11075                 return TASK_UNMAPPED_BASE + mmap_rnd();
11076  }
11077  
11078 @@ -112,11 +125,23 @@ static unsigned long mmap_legacy_base(vo
11079  void arch_pick_mmap_layout(struct mm_struct *mm)
11080  {
11081         if (mmap_is_legacy()) {
11082 -               mm->mmap_base = mmap_legacy_base();
11083 +               mm->mmap_base = mmap_legacy_base(mm);
11084 +
11085 +#ifdef CONFIG_PAX_RANDMMAP
11086 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
11087 +                       mm->mmap_base += mm->delta_mmap;
11088 +#endif
11089 +
11090                 mm->get_unmapped_area = arch_get_unmapped_area;
11091                 mm->unmap_area = arch_unmap_area;
11092         } else {
11093 -               mm->mmap_base = mmap_base();
11094 +               mm->mmap_base = mmap_base(mm);
11095 +
11096 +#ifdef CONFIG_PAX_RANDMMAP
11097 +               if (mm->pax_flags & MF_PAX_RANDMMAP)
11098 +                       mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
11099 +#endif
11100 +
11101                 mm->get_unmapped_area = arch_get_unmapped_area_topdown;
11102                 mm->unmap_area = arch_unmap_area_topdown;
11103         }
11104 diff -urNp linux-2.6.27.10/arch/x86/mm/pageattr.c linux-2.6.27.10/arch/x86/mm/pageattr.c
11105 --- linux-2.6.27.10/arch/x86/mm/pageattr.c      2008-11-07 12:55:34.000000000 -0500
11106 +++ linux-2.6.27.10/arch/x86/mm/pageattr.c      2008-11-18 03:38:44.000000000 -0500
11107 @@ -20,6 +20,7 @@
11108  #include <asm/pgalloc.h>
11109  #include <asm/proto.h>
11110  #include <asm/pat.h>
11111 +#include <asm/desc.h>
11112  
11113  /*
11114   * The current flushing context - we pass it instead of 5 arguments:
11115 @@ -213,7 +214,7 @@ static inline pgprot_t static_protection
11116          * Does not cover __inittext since that is gone later on. On
11117          * 64bit we do not enforce !NX on the low mapping
11118          */
11119 -       if (within(address, (unsigned long)_text, (unsigned long)_etext))
11120 +       if (within(address, ktla_ktva((unsigned long)_text), ktla_ktva((unsigned long)_etext)))
11121                 pgprot_val(forbidden) |= _PAGE_NX;
11122  
11123         /*
11124 @@ -275,8 +276,20 @@ EXPORT_SYMBOL_GPL(lookup_address);
11125   */
11126  static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
11127  {
11128 +
11129 +#ifdef CONFIG_PAX_KERNEXEC
11130 +       unsigned long cr0;
11131 +
11132 +       pax_open_kernel(cr0);
11133 +#endif
11134 +
11135         /* change init_mm */
11136         set_pte_atomic(kpte, pte);
11137 +
11138 +#ifdef CONFIG_PAX_KERNEXEC
11139 +       pax_close_kernel(cr0);
11140 +#endif
11141 +
11142  #ifdef CONFIG_X86_32
11143         if (!SHARED_KERNEL_PMD) {
11144                 struct page *page;
11145 diff -urNp linux-2.6.27.10/arch/x86/mm/pat.c linux-2.6.27.10/arch/x86/mm/pat.c
11146 --- linux-2.6.27.10/arch/x86/mm/pat.c   2008-11-07 12:55:34.000000000 -0500
11147 +++ linux-2.6.27.10/arch/x86/mm/pat.c   2008-11-18 03:38:44.000000000 -0500
11148 @@ -396,7 +396,7 @@ pgprot_t phys_mem_access_prot(struct fil
11149         return vma_prot;
11150  }
11151  
11152 -#ifdef CONFIG_STRICT_DEVMEM
11153 +#ifndef CONFIG_STRICT_DEVMEM
11154  /* This check is done in drivers/char/mem.c in case of STRICT_DEVMEM*/
11155  static inline int range_is_allowed(unsigned long pfn, unsigned long size)
11156  {
11157 diff -urNp linux-2.6.27.10/arch/x86/mm/pgtable_32.c linux-2.6.27.10/arch/x86/mm/pgtable_32.c
11158 --- linux-2.6.27.10/arch/x86/mm/pgtable_32.c    2008-11-07 12:55:34.000000000 -0500
11159 +++ linux-2.6.27.10/arch/x86/mm/pgtable_32.c    2008-11-18 03:38:44.000000000 -0500
11160 @@ -31,6 +31,10 @@ void set_pte_vaddr(unsigned long vaddr, 
11161         pmd_t *pmd;
11162         pte_t *pte;
11163  
11164 +#ifdef CONFIG_PAX_KERNEXEC
11165 +       unsigned long cr0;
11166 +#endif
11167 +
11168         pgd = swapper_pg_dir + pgd_index(vaddr);
11169         if (pgd_none(*pgd)) {
11170                 BUG();
11171 @@ -47,11 +51,20 @@ void set_pte_vaddr(unsigned long vaddr, 
11172                 return;
11173         }
11174         pte = pte_offset_kernel(pmd, vaddr);
11175 +
11176 +#ifdef CONFIG_PAX_KERNEXEC
11177 +       pax_open_kernel(cr0);
11178 +#endif
11179 +
11180         if (pte_val(pteval))
11181                 set_pte_present(&init_mm, vaddr, pte, pteval);
11182         else
11183                 pte_clear(&init_mm, vaddr, pte);
11184  
11185 +#ifdef CONFIG_PAX_KERNEXEC
11186 +       pax_close_kernel(cr0);
11187 +#endif
11188 +
11189         /*
11190          * It's enough to flush this one mapping.
11191          * (PGE mappings get flushed as well)
11192 diff -urNp linux-2.6.27.10/arch/x86/oprofile/backtrace.c linux-2.6.27.10/arch/x86/oprofile/backtrace.c
11193 --- linux-2.6.27.10/arch/x86/oprofile/backtrace.c       2008-11-07 12:55:34.000000000 -0500
11194 +++ linux-2.6.27.10/arch/x86/oprofile/backtrace.c       2008-11-18 03:38:44.000000000 -0500
11195 @@ -37,7 +37,7 @@ static void backtrace_address(void *data
11196         unsigned int *depth = data;
11197  
11198         if ((*depth)--)
11199 -               oprofile_add_trace(addr);
11200 +               oprofile_add_trace(ktla_ktva(addr));
11201  }
11202  
11203  static struct stacktrace_ops backtrace_ops = {
11204 @@ -79,7 +79,7 @@ x86_backtrace(struct pt_regs * const reg
11205         struct frame_head *head = (struct frame_head *)frame_pointer(regs);
11206         unsigned long stack = kernel_trap_sp(regs);
11207  
11208 -       if (!user_mode_vm(regs)) {
11209 +       if (!user_mode(regs)) {
11210                 if (depth)
11211                         dump_trace(NULL, regs, (unsigned long *)stack, 0,
11212                                    &backtrace_ops, &depth);
11213 diff -urNp linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c
11214 --- linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c     2008-11-07 12:55:34.000000000 -0500
11215 +++ linux-2.6.27.10/arch/x86/oprofile/op_model_p4.c     2008-11-18 03:38:44.000000000 -0500
11216 @@ -47,7 +47,7 @@ static inline void setup_num_counters(vo
11217  #endif
11218  }
11219  
11220 -static int inline addr_increment(void)
11221 +static inline int addr_increment(void)
11222  {
11223  #ifdef CONFIG_SMP
11224         return smp_num_siblings == 2 ? 2 : 1;
11225 diff -urNp linux-2.6.27.10/arch/x86/pci/common.c linux-2.6.27.10/arch/x86/pci/common.c
11226 --- linux-2.6.27.10/arch/x86/pci/common.c       2008-11-07 12:55:34.000000000 -0500
11227 +++ linux-2.6.27.10/arch/x86/pci/common.c       2008-11-18 03:38:44.000000000 -0500
11228 @@ -362,7 +362,7 @@ static struct dmi_system_id __devinitdat
11229                         DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
11230                 },
11231         },
11232 -       {}
11233 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
11234  };
11235  
11236  void __init dmi_check_pciprobe(void)
11237 diff -urNp linux-2.6.27.10/arch/x86/pci/fixup.c linux-2.6.27.10/arch/x86/pci/fixup.c
11238 --- linux-2.6.27.10/arch/x86/pci/fixup.c        2008-11-07 12:55:34.000000000 -0500
11239 +++ linux-2.6.27.10/arch/x86/pci/fixup.c        2008-11-18 03:38:44.000000000 -0500
11240 @@ -365,7 +365,7 @@ static struct dmi_system_id __devinitdat
11241                         DMI_MATCH(DMI_PRODUCT_NAME, "MS-6702E"),
11242                 },
11243         },
11244 -       {}
11245 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11246  };
11247  
11248  /*
11249 @@ -436,7 +436,7 @@ static struct dmi_system_id __devinitdat
11250                         DMI_MATCH(DMI_PRODUCT_VERSION, "PSA40U"),
11251                 },
11252         },
11253 -       { }
11254 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11255  };
11256  
11257  static void __devinit pci_pre_fixup_toshiba_ohci1394(struct pci_dev *dev)
11258 diff -urNp linux-2.6.27.10/arch/x86/pci/irq.c linux-2.6.27.10/arch/x86/pci/irq.c
11259 --- linux-2.6.27.10/arch/x86/pci/irq.c  2008-11-07 12:55:34.000000000 -0500
11260 +++ linux-2.6.27.10/arch/x86/pci/irq.c  2008-11-18 03:38:44.000000000 -0500
11261 @@ -544,7 +544,7 @@ static __init int intel_router_probe(str
11262         static struct pci_device_id __initdata pirq_440gx[] = {
11263                 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_0) },
11264                 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443GX_2) },
11265 -               { },
11266 +               { PCI_DEVICE(0, 0) }
11267         };
11268  
11269         /* 440GX has a proprietary PIRQ router -- don't use it */
11270 @@ -1131,7 +1131,7 @@ static struct dmi_system_id __initdata p
11271                         DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"),
11272                 },
11273         },
11274 -       { }
11275 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
11276  };
11277  
11278  int __init pcibios_irq_init(void)
11279 diff -urNp linux-2.6.27.10/arch/x86/pci/pcbios.c linux-2.6.27.10/arch/x86/pci/pcbios.c
11280 --- linux-2.6.27.10/arch/x86/pci/pcbios.c       2008-11-07 12:55:34.000000000 -0500
11281 +++ linux-2.6.27.10/arch/x86/pci/pcbios.c       2008-11-18 03:38:44.000000000 -0500
11282 @@ -57,50 +57,120 @@ union bios32 {
11283  static struct {
11284         unsigned long address;
11285         unsigned short segment;
11286 -} bios32_indirect = { 0, __KERNEL_CS };
11287 +} bios32_indirect __read_only = { 0, __PCIBIOS_CS };
11288  
11289  /*
11290   * Returns the entry point for the given service, NULL on error
11291   */
11292  
11293 -static unsigned long bios32_service(unsigned long service)
11294 +static unsigned long __devinit bios32_service(unsigned long service)
11295  {
11296         unsigned char return_code;      /* %al */
11297         unsigned long address;          /* %ebx */
11298         unsigned long length;           /* %ecx */
11299         unsigned long entry;            /* %edx */
11300         unsigned long flags;
11301 +       struct desc_struct d, *gdt;
11302 +
11303 +#ifdef CONFIG_PAX_KERNEXEC
11304 +       unsigned long cr0;
11305 +#endif
11306  
11307         local_irq_save(flags);
11308 -       __asm__("lcall *(%%edi); cld"
11309 +
11310 +       gdt = get_cpu_gdt_table(smp_processor_id());
11311 +
11312 +#ifdef CONFIG_PAX_KERNEXEC
11313 +       pax_open_kernel(cr0);
11314 +#endif
11315 +
11316 +       pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x9B, 0xC);
11317 +       write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11318 +       pack_descriptor(&d, 0UL, 0xFFFFFUL, 0x93, 0xC);
11319 +       write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11320 +
11321 +#ifdef CONFIG_PAX_KERNEXEC
11322 +       pax_close_kernel(cr0);
11323 +#endif
11324 +
11325 +       __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld"
11326                 : "=a" (return_code),
11327                   "=b" (address),
11328                   "=c" (length),
11329                   "=d" (entry)
11330                 : "0" (service),
11331                   "1" (0),
11332 -                 "D" (&bios32_indirect));
11333 +                 "D" (&bios32_indirect),
11334 +                 "r"(__PCIBIOS_DS)
11335 +               : "memory");
11336 +
11337 +#ifdef CONFIG_PAX_KERNEXEC
11338 +       pax_open_kernel(cr0);
11339 +#endif
11340 +
11341 +       gdt[GDT_ENTRY_PCIBIOS_CS].a = 0;
11342 +       gdt[GDT_ENTRY_PCIBIOS_CS].b = 0;
11343 +       gdt[GDT_ENTRY_PCIBIOS_DS].a = 0;
11344 +       gdt[GDT_ENTRY_PCIBIOS_DS].b = 0;
11345 +
11346 +#ifdef CONFIG_PAX_KERNEXEC
11347 +       pax_close_kernel(cr0);
11348 +#endif
11349 +
11350         local_irq_restore(flags);
11351  
11352         switch (return_code) {
11353 -               case 0:
11354 -                       return address + entry;
11355 -               case 0x80:      /* Not present */
11356 -                       printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11357 -                       return 0;
11358 -               default: /* Shouldn't happen */
11359 -                       printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11360 -                               service, return_code);
11361 +       case 0: {
11362 +               int cpu;
11363 +               unsigned char flags;
11364 +
11365 +               printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry);
11366 +               if (address >= 0xFFFF0 || length > 0x100000 - address || length <= entry) {
11367 +                       printk(KERN_WARNING "bios32_service: not valid\n");
11368                         return 0;
11369 +               }
11370 +               address = address + PAGE_OFFSET;
11371 +               length += 16UL; /* some BIOSs underreport this... */
11372 +               flags = 4;
11373 +               if (length >= 64*1024*1024) {
11374 +                       length >>= PAGE_SHIFT;
11375 +                       flags |= 8;
11376 +               }
11377 +
11378 +#ifdef CONFIG_PAX_KERNEXEC
11379 +               pax_open_kernel(cr0);
11380 +#endif
11381 +
11382 +               for (cpu = 0; cpu < NR_CPUS; cpu++) {
11383 +                       gdt = get_cpu_gdt_table(cpu);
11384 +                       pack_descriptor(&d, address, length, 0x9b, flags);
11385 +                       write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_CS, &d, DESCTYPE_S);
11386 +                       pack_descriptor(&d, address, length, 0x93, flags);
11387 +                       write_gdt_entry(gdt, GDT_ENTRY_PCIBIOS_DS, &d, DESCTYPE_S);
11388 +               }
11389 +
11390 +#ifdef CONFIG_PAX_KERNEXEC
11391 +               pax_close_kernel(cr0);
11392 +#endif
11393 +
11394 +               return entry;
11395 +       }
11396 +       case 0x80:      /* Not present */
11397 +               printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service);
11398 +               return 0;
11399 +       default: /* Shouldn't happen */
11400 +               printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n",
11401 +                       service, return_code);
11402 +               return 0;
11403         }
11404  }
11405  
11406  static struct {
11407         unsigned long address;
11408         unsigned short segment;
11409 -} pci_indirect = { 0, __KERNEL_CS };
11410 +} pci_indirect __read_only = { 0, __PCIBIOS_CS };
11411  
11412 -static int pci_bios_present;
11413 +static int pci_bios_present __read_only;
11414  
11415  static int __devinit check_pcibios(void)
11416  {
11417 @@ -109,11 +179,13 @@ static int __devinit check_pcibios(void)
11418         unsigned long flags, pcibios_entry;
11419  
11420         if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
11421 -               pci_indirect.address = pcibios_entry + PAGE_OFFSET;
11422 +               pci_indirect.address = pcibios_entry;
11423  
11424                 local_irq_save(flags);
11425 -               __asm__(
11426 -                       "lcall *(%%edi); cld\n\t"
11427 +               __asm__("movw %w6, %%ds\n\t"
11428 +                       "lcall *%%ss:(%%edi); cld\n\t"
11429 +                       "push %%ss\n\t"
11430 +                       "pop %%ds\n\t"
11431                         "jc 1f\n\t"
11432                         "xor %%ah, %%ah\n"
11433                         "1:"
11434 @@ -122,7 +194,8 @@ static int __devinit check_pcibios(void)
11435                           "=b" (ebx),
11436                           "=c" (ecx)
11437                         : "1" (PCIBIOS_PCI_BIOS_PRESENT),
11438 -                         "D" (&pci_indirect)
11439 +                         "D" (&pci_indirect),
11440 +                         "r" (__PCIBIOS_DS)
11441                         : "memory");
11442                 local_irq_restore(flags);
11443  
11444 @@ -166,7 +239,10 @@ static int pci_bios_read(unsigned int se
11445  
11446         switch (len) {
11447         case 1:
11448 -               __asm__("lcall *(%%esi); cld\n\t"
11449 +               __asm__("movw %w6, %%ds\n\t"
11450 +                       "lcall *%%ss:(%%esi); cld\n\t"
11451 +                       "push %%ss\n\t"
11452 +                       "pop %%ds\n\t"
11453                         "jc 1f\n\t"
11454                         "xor %%ah, %%ah\n"
11455                         "1:"
11456 @@ -175,7 +251,8 @@ static int pci_bios_read(unsigned int se
11457                         : "1" (PCIBIOS_READ_CONFIG_BYTE),
11458                           "b" (bx),
11459                           "D" ((long)reg),
11460 -                         "S" (&pci_indirect));
11461 +                         "S" (&pci_indirect),
11462 +                         "r" (__PCIBIOS_DS));
11463                 /*
11464                  * Zero-extend the result beyond 8 bits, do not trust the
11465                  * BIOS having done it:
11466 @@ -183,7 +260,10 @@ static int pci_bios_read(unsigned int se
11467                 *value &= 0xff;
11468                 break;
11469         case 2:
11470 -               __asm__("lcall *(%%esi); cld\n\t"
11471 +               __asm__("movw %w6, %%ds\n\t"
11472 +                       "lcall *%%ss:(%%esi); cld\n\t"
11473 +                       "push %%ss\n\t"
11474 +                       "pop %%ds\n\t"
11475                         "jc 1f\n\t"
11476                         "xor %%ah, %%ah\n"
11477                         "1:"
11478 @@ -192,7 +272,8 @@ static int pci_bios_read(unsigned int se
11479                         : "1" (PCIBIOS_READ_CONFIG_WORD),
11480                           "b" (bx),
11481                           "D" ((long)reg),
11482 -                         "S" (&pci_indirect));
11483 +                         "S" (&pci_indirect),
11484 +                         "r" (__PCIBIOS_DS));
11485                 /*
11486                  * Zero-extend the result beyond 16 bits, do not trust the
11487                  * BIOS having done it:
11488 @@ -200,7 +281,10 @@ static int pci_bios_read(unsigned int se
11489                 *value &= 0xffff;
11490                 break;
11491         case 4:
11492 -               __asm__("lcall *(%%esi); cld\n\t"
11493 +               __asm__("movw %w6, %%ds\n\t"
11494 +                       "lcall *%%ss:(%%esi); cld\n\t"
11495 +                       "push %%ss\n\t"
11496 +                       "pop %%ds\n\t"
11497                         "jc 1f\n\t"
11498                         "xor %%ah, %%ah\n"
11499                         "1:"
11500 @@ -209,7 +293,8 @@ static int pci_bios_read(unsigned int se
11501                         : "1" (PCIBIOS_READ_CONFIG_DWORD),
11502                           "b" (bx),
11503                           "D" ((long)reg),
11504 -                         "S" (&pci_indirect));
11505 +                         "S" (&pci_indirect),
11506 +                         "r" (__PCIBIOS_DS));
11507                 break;
11508         }
11509  
11510 @@ -232,7 +317,10 @@ static int pci_bios_write(unsigned int s
11511  
11512         switch (len) {
11513         case 1:
11514 -               __asm__("lcall *(%%esi); cld\n\t"
11515 +               __asm__("movw %w6, %%ds\n\t"
11516 +                       "lcall *%%ss:(%%esi); cld\n\t"
11517 +                       "push %%ss\n\t"
11518 +                       "pop %%ds\n\t"
11519                         "jc 1f\n\t"
11520                         "xor %%ah, %%ah\n"
11521                         "1:"
11522 @@ -241,10 +329,14 @@ static int pci_bios_write(unsigned int s
11523                           "c" (value),
11524                           "b" (bx),
11525                           "D" ((long)reg),
11526 -                         "S" (&pci_indirect));
11527 +                         "S" (&pci_indirect),
11528 +                         "r" (__PCIBIOS_DS));
11529                 break;
11530         case 2:
11531 -               __asm__("lcall *(%%esi); cld\n\t"
11532 +               __asm__("movw %w6, %%ds\n\t"
11533 +                       "lcall *%%ss:(%%esi); cld\n\t"
11534 +                       "push %%ss\n\t"
11535 +                       "pop %%ds\n\t"
11536                         "jc 1f\n\t"
11537                         "xor %%ah, %%ah\n"
11538                         "1:"
11539 @@ -253,10 +345,14 @@ static int pci_bios_write(unsigned int s
11540                           "c" (value),
11541                           "b" (bx),
11542                           "D" ((long)reg),
11543 -                         "S" (&pci_indirect));
11544 +                         "S" (&pci_indirect),
11545 +                         "r" (__PCIBIOS_DS));
11546                 break;
11547         case 4:
11548 -               __asm__("lcall *(%%esi); cld\n\t"
11549 +               __asm__("movw %w6, %%ds\n\t"
11550 +                       "lcall *%%ss:(%%esi); cld\n\t"
11551 +                       "push %%ss\n\t"
11552 +                       "pop %%ds\n\t"
11553                         "jc 1f\n\t"
11554                         "xor %%ah, %%ah\n"
11555                         "1:"
11556 @@ -265,7 +361,8 @@ static int pci_bios_write(unsigned int s
11557                           "c" (value),
11558                           "b" (bx),
11559                           "D" ((long)reg),
11560 -                         "S" (&pci_indirect));
11561 +                         "S" (&pci_indirect),
11562 +                         "r" (__PCIBIOS_DS));
11563                 break;
11564         }
11565  
11566 @@ -369,10 +466,13 @@ struct irq_routing_table * pcibios_get_i
11567  
11568         DBG("PCI: Fetching IRQ routing table... ");
11569         __asm__("push %%es\n\t"
11570 +               "movw %w8, %%ds\n\t"
11571                 "push %%ds\n\t"
11572                 "pop  %%es\n\t"
11573 -               "lcall *(%%esi); cld\n\t"
11574 +               "lcall *%%ss:(%%esi); cld\n\t"
11575                 "pop %%es\n\t"
11576 +               "push %%ss\n\t"
11577 +               "pop %%ds\n"
11578                 "jc 1f\n\t"
11579                 "xor %%ah, %%ah\n"
11580                 "1:"
11581 @@ -383,7 +483,8 @@ struct irq_routing_table * pcibios_get_i
11582                   "1" (0),
11583                   "D" ((long) &opt),
11584                   "S" (&pci_indirect),
11585 -                 "m" (opt)
11586 +                 "m" (opt),
11587 +                 "r" (__PCIBIOS_DS)
11588                 : "memory");
11589         DBG("OK  ret=%d, size=%d, map=%x\n", ret, opt.size, map);
11590         if (ret & 0xff00)
11591 @@ -407,7 +508,10 @@ int pcibios_set_irq_routing(struct pci_d
11592  {
11593         int ret;
11594  
11595 -       __asm__("lcall *(%%esi); cld\n\t"
11596 +       __asm__("movw %w5, %%ds\n\t"
11597 +               "lcall *%%ss:(%%esi); cld\n\t"
11598 +               "push %%ss\n\t"
11599 +               "pop %%ds\n"
11600                 "jc 1f\n\t"
11601                 "xor %%ah, %%ah\n"
11602                 "1:"
11603 @@ -415,7 +519,8 @@ int pcibios_set_irq_routing(struct pci_d
11604                 : "0" (PCIBIOS_SET_PCI_HW_INT),
11605                   "b" ((dev->bus->number << 8) | dev->devfn),
11606                   "c" ((irq << 8) | (pin + 10)),
11607 -                 "S" (&pci_indirect));
11608 +                 "S" (&pci_indirect),
11609 +                 "r" (__PCIBIOS_DS));
11610         return !(ret & 0xff00);
11611  }
11612  EXPORT_SYMBOL(pcibios_set_irq_routing);
11613 diff -urNp linux-2.6.27.10/arch/x86/power/cpu_32.c linux-2.6.27.10/arch/x86/power/cpu_32.c
11614 --- linux-2.6.27.10/arch/x86/power/cpu_32.c     2008-11-07 12:55:34.000000000 -0500
11615 +++ linux-2.6.27.10/arch/x86/power/cpu_32.c     2008-11-18 03:38:44.000000000 -0500
11616 @@ -66,7 +66,7 @@ static void do_fpu_end(void)
11617  static void fix_processor_context(void)
11618  {
11619         int cpu = smp_processor_id();
11620 -       struct tss_struct *t = &per_cpu(init_tss, cpu);
11621 +       struct tss_struct *t = init_tss + cpu;
11622  
11623         set_tss_desc(cpu, t);   /*
11624                                  * This just modifies memory; should not be
11625 diff -urNp linux-2.6.27.10/arch/x86/power/cpu_64.c linux-2.6.27.10/arch/x86/power/cpu_64.c
11626 --- linux-2.6.27.10/arch/x86/power/cpu_64.c     2008-11-07 12:55:34.000000000 -0500
11627 +++ linux-2.6.27.10/arch/x86/power/cpu_64.c     2008-11-18 03:38:44.000000000 -0500
11628 @@ -136,7 +136,11 @@ void restore_processor_state(void)
11629  static void fix_processor_context(void)
11630  {
11631         int cpu = smp_processor_id();
11632 -       struct tss_struct *t = &per_cpu(init_tss, cpu);
11633 +       struct tss_struct *t = init_tss + cpu;
11634 +
11635 +#ifdef CONFIG_PAX_KERNEXEC
11636 +       unsigned long cr0;
11637 +#endif
11638  
11639         /*
11640          * This just modifies memory; should not be necessary. But... This
11641 @@ -145,8 +149,16 @@ static void fix_processor_context(void)
11642          */
11643         set_tss_desc(cpu, t);
11644  
11645 +#ifdef CONFIG_PAX_KERNEXEC
11646 +       pax_open_kernel(cr0);
11647 +#endif
11648 +
11649         get_cpu_gdt_table(cpu)[GDT_ENTRY_TSS].type = 9;
11650  
11651 +#ifdef CONFIG_PAX_KERNEXEC
11652 +       pax_close_kernel(cr0);
11653 +#endif
11654 +
11655         syscall_init();                         /* This sets MSR_*STAR and related */
11656         load_TR_desc();                         /* This does ltr */
11657         load_LDT(&current->active_mm->context); /* This does lldt */
11658 diff -urNp linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c
11659 --- linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c        2008-11-07 12:55:34.000000000 -0500
11660 +++ linux-2.6.27.10/arch/x86/vdso/vdso32-setup.c        2008-11-18 03:38:44.000000000 -0500
11661 @@ -226,7 +226,7 @@ static inline void map_compat_vdso(int m
11662  void enable_sep_cpu(void)
11663  {
11664         int cpu = get_cpu();
11665 -       struct tss_struct *tss = &per_cpu(init_tss, cpu);
11666 +       struct tss_struct *tss = init_tss + cpu;
11667  
11668         if (!boot_cpu_has(X86_FEATURE_SEP)) {
11669                 put_cpu();
11670 @@ -249,7 +249,7 @@ static int __init gate_vma_init(void)
11671         gate_vma.vm_start = FIXADDR_USER_START;
11672         gate_vma.vm_end = FIXADDR_USER_END;
11673         gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
11674 -       gate_vma.vm_page_prot = __P101;
11675 +       gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
11676         /*
11677          * Make sure the vDSO gets into every core dump.
11678          * Dumping its contents makes post-mortem fully interpretable later
11679 @@ -331,7 +331,7 @@ int arch_setup_additional_pages(struct l
11680         if (compat)
11681                 addr = VDSO_HIGH_BASE;
11682         else {
11683 -               addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
11684 +               addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, MAP_EXECUTABLE);
11685                 if (IS_ERR_VALUE(addr)) {
11686                         ret = addr;
11687                         goto up_fail;
11688 @@ -358,7 +358,7 @@ int arch_setup_additional_pages(struct l
11689                         goto up_fail;
11690         }
11691  
11692 -       current->mm->context.vdso = (void *)addr;
11693 +       current->mm->context.vdso = addr;
11694         current_thread_info()->sysenter_return =
11695                 VDSO32_SYMBOL(addr, SYSENTER_RETURN);
11696  
11697 @@ -384,7 +384,7 @@ static ctl_table abi_table2[] = {
11698                 .mode           = 0644,
11699                 .proc_handler   = proc_dointvec
11700         },
11701 -       {}
11702 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11703  };
11704  
11705  static ctl_table abi_root_table2[] = {
11706 @@ -394,7 +394,7 @@ static ctl_table abi_root_table2[] = {
11707                 .mode = 0555,
11708                 .child = abi_table2
11709         },
11710 -       {}
11711 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
11712  };
11713  
11714  static __init int ia32_binfmt_init(void)
11715 @@ -409,8 +409,14 @@ __initcall(ia32_binfmt_init);
11716  
11717  const char *arch_vma_name(struct vm_area_struct *vma)
11718  {
11719 -       if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
11720 +       if (vma->vm_mm && vma->vm_start == vma->vm_mm->context.vdso)
11721                 return "[vdso]";
11722 +
11723 +#ifdef CONFIG_PAX_SEGMEXEC
11724 +       if (vma->vm_mm && vma->vm_mirror && vma->vm_mirror->vm_start == vma->vm_mm->context.vdso)
11725 +               return "[vdso]";
11726 +#endif
11727 +
11728         return NULL;
11729  }
11730  
11731 @@ -419,7 +425,7 @@ struct vm_area_struct *get_gate_vma(stru
11732         struct mm_struct *mm = tsk->mm;
11733  
11734         /* Check to see if this task was created in compat vdso mode */
11735 -       if (mm && mm->context.vdso == (void *)VDSO_HIGH_BASE)
11736 +       if (mm && mm->context.vdso == VDSO_HIGH_BASE)
11737                 return &gate_vma;
11738         return NULL;
11739  }
11740 diff -urNp linux-2.6.27.10/arch/x86/vdso/vma.c linux-2.6.27.10/arch/x86/vdso/vma.c
11741 --- linux-2.6.27.10/arch/x86/vdso/vma.c 2008-11-07 12:55:34.000000000 -0500
11742 +++ linux-2.6.27.10/arch/x86/vdso/vma.c 2008-11-18 03:38:44.000000000 -0500
11743 @@ -123,7 +123,7 @@ int arch_setup_additional_pages(struct l
11744         if (ret)
11745                 goto up_fail;
11746  
11747 -       current->mm->context.vdso = (void *)addr;
11748 +       current->mm->context.vdso = addr;
11749  up_fail:
11750         up_write(&mm->mmap_sem);
11751         return ret;
11752 diff -urNp linux-2.6.27.10/arch/x86/xen/enlighten.c linux-2.6.27.10/arch/x86/xen/enlighten.c
11753 --- linux-2.6.27.10/arch/x86/xen/enlighten.c    2008-12-10 22:35:37.000000000 -0500
11754 +++ linux-2.6.27.10/arch/x86/xen/enlighten.c    2008-12-10 22:35:46.000000000 -0500
11755 @@ -343,7 +343,7 @@ static void xen_set_ldt(const void *addr
11756  static void xen_load_gdt(const struct desc_ptr *dtr)
11757  {
11758         unsigned long *frames;
11759 -       unsigned long va = dtr->address;
11760 +       unsigned long va = (unsigned long)dtr->address;
11761         unsigned int size = dtr->size + 1;
11762         unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
11763         int f;
11764 @@ -358,7 +358,7 @@ static void xen_load_gdt(const struct de
11765         mcs = xen_mc_entry(sizeof(*frames) * pages);
11766         frames = mcs.args;
11767  
11768 -       for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) {
11769 +       for (f = 0; va < (unsigned long)dtr->address + size; va += PAGE_SIZE, f++) {
11770                 frames[f] = virt_to_mfn(va);
11771                 make_lowmem_page_readonly((void *)va);
11772         }
11773 @@ -467,7 +467,7 @@ static void xen_write_idt_entry(gate_des
11774  
11775         preempt_disable();
11776  
11777 -       start = __get_cpu_var(idt_desc).address;
11778 +       start = (unsigned long)__get_cpu_var(idt_desc).address;
11779         end = start + __get_cpu_var(idt_desc).size + 1;
11780  
11781         xen_mc_flush();
11782 @@ -1574,6 +1574,8 @@ static __init pgd_t *xen_setup_kernel_pa
11783         convert_pfn_mfn(init_level4_pgt);
11784         convert_pfn_mfn(level3_ident_pgt);
11785         convert_pfn_mfn(level3_kernel_pgt);
11786 +       convert_pfn_mfn(level3_vmalloc_pgt);
11787 +       convert_pfn_mfn(level3_vmemmap_pgt);
11788  
11789         l3 = m2v(pgd[pgd_index(__START_KERNEL_map)].pgd);
11790         l2 = m2v(l3[pud_index(__START_KERNEL_map)].pud);
11791 @@ -1592,9 +1594,12 @@ static __init pgd_t *xen_setup_kernel_pa
11792         set_page_prot(init_level4_pgt, PAGE_KERNEL_RO);
11793         set_page_prot(level3_ident_pgt, PAGE_KERNEL_RO);
11794         set_page_prot(level3_kernel_pgt, PAGE_KERNEL_RO);
11795 +       set_page_prot(level3_vmalloc_pgt, PAGE_KERNEL_RO);
11796 +       set_page_prot(level3_vmemmap_pgt, PAGE_KERNEL_RO);
11797         set_page_prot(level3_user_vsyscall, PAGE_KERNEL_RO);
11798         set_page_prot(level2_kernel_pgt, PAGE_KERNEL_RO);
11799         set_page_prot(level2_fixmap_pgt, PAGE_KERNEL_RO);
11800 +       set_page_prot(level1_fixmap_pgt, PAGE_KERNEL_RO);
11801  
11802         /* Pin down new L4 */
11803         pin_pagetable_pfn(MMUEXT_PIN_L4_TABLE,
11804 diff -urNp linux-2.6.27.10/arch/x86/xen/smp.c linux-2.6.27.10/arch/x86/xen/smp.c
11805 --- linux-2.6.27.10/arch/x86/xen/smp.c  2008-11-07 12:55:34.000000000 -0500
11806 +++ linux-2.6.27.10/arch/x86/xen/smp.c  2008-11-18 03:38:44.000000000 -0500
11807 @@ -170,11 +170,6 @@ static void __init xen_smp_prepare_boot_
11808  {
11809         BUG_ON(smp_processor_id() != 0);
11810         native_smp_prepare_boot_cpu();
11811 -
11812 -       /* We've switched to the "real" per-cpu gdt, so make sure the
11813 -          old memory can be recycled */
11814 -       make_lowmem_page_readwrite(&per_cpu_var(gdt_page));
11815 -
11816         xen_setup_vcpu_info_placement();
11817  }
11818  
11819 @@ -232,8 +227,8 @@ cpu_initialize_context(unsigned int cpu,
11820         gdt = get_cpu_gdt_table(cpu);
11821  
11822         ctxt->flags = VGCF_IN_KERNEL;
11823 -       ctxt->user_regs.ds = __USER_DS;
11824 -       ctxt->user_regs.es = __USER_DS;
11825 +       ctxt->user_regs.ds = __KERNEL_DS;
11826 +       ctxt->user_regs.es = __KERNEL_DS;
11827         ctxt->user_regs.ss = __KERNEL_DS;
11828  #ifdef CONFIG_X86_32
11829         ctxt->user_regs.fs = __KERNEL_PERCPU;
11830 diff -urNp linux-2.6.27.10/crypto/async_tx/async_tx.c linux-2.6.27.10/crypto/async_tx/async_tx.c
11831 --- linux-2.6.27.10/crypto/async_tx/async_tx.c  2008-11-07 12:55:34.000000000 -0500
11832 +++ linux-2.6.27.10/crypto/async_tx/async_tx.c  2008-11-18 03:38:44.000000000 -0500
11833 @@ -358,8 +358,8 @@ async_tx_init(void)
11834  err:
11835         printk(KERN_ERR "async_tx: initialization failure\n");
11836  
11837 -       while (--cap >= 0)
11838 -               free_percpu(channel_table[cap]);
11839 +       while (cap)
11840 +               free_percpu(channel_table[--cap]);
11841  
11842         return 1;
11843  }
11844 diff -urNp linux-2.6.27.10/crypto/lrw.c linux-2.6.27.10/crypto/lrw.c
11845 --- linux-2.6.27.10/crypto/lrw.c        2008-11-07 12:55:34.000000000 -0500
11846 +++ linux-2.6.27.10/crypto/lrw.c        2008-11-18 03:38:44.000000000 -0500
11847 @@ -54,7 +54,7 @@ static int setkey(struct crypto_tfm *par
11848         struct priv *ctx = crypto_tfm_ctx(parent);
11849         struct crypto_cipher *child = ctx->child;
11850         int err, i;
11851 -       be128 tmp = { 0 };
11852 +       be128 tmp = { 0, 0 };
11853         int bsize = crypto_cipher_blocksize(child);
11854  
11855         crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
11856 diff -urNp linux-2.6.27.10/Documentation/dontdiff linux-2.6.27.10/Documentation/dontdiff
11857 --- linux-2.6.27.10/Documentation/dontdiff      2008-11-07 12:55:34.000000000 -0500
11858 +++ linux-2.6.27.10/Documentation/dontdiff      2008-11-18 03:39:50.000000000 -0500
11859 @@ -3,6 +3,7 @@
11860  *.bin
11861  *.cpio
11862  *.css
11863 +*.dbg
11864  *.dvi
11865  *.eps
11866  *.fw.gen.S
11867 @@ -53,9 +54,14 @@ COPYING
11868  CREDITS
11869  CVS
11870  ChangeSet
11871 +GPATH
11872 +GRTAGS
11873 +GSYMS
11874 +GTAGS
11875  Image
11876  Kerntypes
11877  MODS.txt
11878 +Module.markers
11879  Module.symvers
11880  PENDING
11881  SCCS
11882 @@ -66,7 +72,6 @@ aic7*reg_print.c*
11883  aic7*seq.h*
11884  aicasm
11885  aicdb.h*
11886 -asm
11887  asm-offsets.h
11888  asm_offsets.h
11889  autoconf.h*
11890 @@ -74,6 +79,7 @@ bbootsect
11891  bin2c
11892  binkernel.spec
11893  bootsect
11894 +bounds.h
11895  bsetup
11896  btfixupprep
11897  build
11898 @@ -90,6 +96,7 @@ config_data.gz*
11899  conmakehash
11900  consolemap_deftbl.c*
11901  crc32table.h*
11902 +cpustr.h
11903  cscope.*
11904  defkeymap.c*
11905  devlist.h*
11906 @@ -138,6 +145,7 @@ miboot*
11907  mk_elfconfig
11908  mkboot
11909  mkbugboot
11910 +mkcpustr
11911  mkdep
11912  mkprep
11913  mktables
11914 @@ -179,16 +187,21 @@ times.h*
11915  tkparse
11916  trix_boot.h
11917  utsrelease.h*
11918 -vdso.lds
11919 +vdso*.lds
11920  version.h*
11921  vmlinux
11922  vmlinux-*
11923  vmlinux.aout
11924 -vmlinux*.lds*
11925 +vmlinux.bin.all
11926 +vmlinux*.lds
11927 +vmlinux.relocs
11928  vmlinux*.scr
11929 -vsyscall.lds
11930 +vsyscall*.lds
11931 +wakeup.elf
11932 +wakeup.lds
11933  wanxlfw.inc
11934  uImage
11935  unifdef
11936 +utsrelease.h
11937  zImage*
11938  zconf.hash.c
11939 diff -urNp linux-2.6.27.10/drivers/acpi/blacklist.c linux-2.6.27.10/drivers/acpi/blacklist.c
11940 --- linux-2.6.27.10/drivers/acpi/blacklist.c    2008-11-07 12:55:34.000000000 -0500
11941 +++ linux-2.6.27.10/drivers/acpi/blacklist.c    2008-11-18 03:38:44.000000000 -0500
11942 @@ -71,7 +71,7 @@ static struct acpi_blacklist_item acpi_b
11943         {"IBM   ", "TP600E  ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
11944          "Incorrect _ADR", 1},
11945  
11946 -       {""}
11947 +       {"", "", 0, 0, 0, all_versions, 0}
11948  };
11949  
11950  #if    CONFIG_ACPI_BLACKLIST_YEAR
11951 diff -urNp linux-2.6.27.10/drivers/acpi/osl.c linux-2.6.27.10/drivers/acpi/osl.c
11952 --- linux-2.6.27.10/drivers/acpi/osl.c  2008-12-21 01:16:51.000000000 -0500
11953 +++ linux-2.6.27.10/drivers/acpi/osl.c  2008-12-21 01:13:45.000000000 -0500
11954 @@ -494,6 +494,8 @@ acpi_os_read_memory(acpi_physical_addres
11955         void __iomem *virt_addr;
11956  
11957         virt_addr = ioremap(phys_addr, width);
11958 +       if (!virt_addr)
11959 +               return AE_NO_MEMORY;
11960         if (!value)
11961                 value = &dummy;
11962  
11963 @@ -522,6 +524,8 @@ acpi_os_write_memory(acpi_physical_addre
11964         void __iomem *virt_addr;
11965  
11966         virt_addr = ioremap(phys_addr, width);
11967 +       if (!virt_addr)
11968 +               return AE_NO_MEMORY;
11969  
11970         switch (width) {
11971         case 8:
11972 diff -urNp linux-2.6.27.10/drivers/acpi/processor_core.c linux-2.6.27.10/drivers/acpi/processor_core.c
11973 --- linux-2.6.27.10/drivers/acpi/processor_core.c       2008-11-07 12:55:34.000000000 -0500
11974 +++ linux-2.6.27.10/drivers/acpi/processor_core.c       2008-11-18 03:38:44.000000000 -0500
11975 @@ -667,7 +667,7 @@ static int __cpuinit acpi_processor_star
11976                 return 0;
11977         }
11978  
11979 -       BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0));
11980 +       BUG_ON(pr->id >= nr_cpu_ids);
11981  
11982         /*
11983          * Buggy BIOS check
11984 diff -urNp linux-2.6.27.10/drivers/acpi/processor_idle.c linux-2.6.27.10/drivers/acpi/processor_idle.c
11985 --- linux-2.6.27.10/drivers/acpi/processor_idle.c       2008-11-07 12:55:34.000000000 -0500
11986 +++ linux-2.6.27.10/drivers/acpi/processor_idle.c       2008-11-18 03:38:44.000000000 -0500
11987 @@ -182,7 +182,7 @@ static struct dmi_system_id __cpuinitdat
11988           DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
11989           DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
11990          (void *)2},
11991 -       {},
11992 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL},
11993  };
11994  
11995  static inline u32 ticks_elapsed(u32 t1, u32 t2)
11996 diff -urNp linux-2.6.27.10/drivers/acpi/tables/tbfadt.c linux-2.6.27.10/drivers/acpi/tables/tbfadt.c
11997 --- linux-2.6.27.10/drivers/acpi/tables/tbfadt.c        2008-11-07 12:55:34.000000000 -0500
11998 +++ linux-2.6.27.10/drivers/acpi/tables/tbfadt.c        2008-11-18 03:38:44.000000000 -0500
11999 @@ -48,7 +48,7 @@
12000  ACPI_MODULE_NAME("tbfadt")
12001  
12002  /* Local prototypes */
12003 -static void inline
12004 +static inline void
12005  acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12006                              u8 bit_width, u64 address);
12007  
12008 @@ -122,7 +122,7 @@ static struct acpi_fadt_info fadt_info_t
12009   *
12010   ******************************************************************************/
12011  
12012 -static void inline
12013 +static inline void
12014  acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
12015                              u8 bit_width, u64 address)
12016  {
12017 diff -urNp linux-2.6.27.10/drivers/ata/ahci.c linux-2.6.27.10/drivers/ata/ahci.c
12018 --- linux-2.6.27.10/drivers/ata/ahci.c  2008-11-07 12:55:34.000000000 -0500
12019 +++ linux-2.6.27.10/drivers/ata/ahci.c  2008-11-18 03:38:44.000000000 -0500
12020 @@ -591,7 +591,7 @@ static const struct pci_device_id ahci_p
12021         { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
12022           PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
12023  
12024 -       { }     /* terminate list */
12025 +       { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12026  };
12027  
12028  
12029 diff -urNp linux-2.6.27.10/drivers/ata/ata_piix.c linux-2.6.27.10/drivers/ata/ata_piix.c
12030 --- linux-2.6.27.10/drivers/ata/ata_piix.c      2008-11-07 12:55:34.000000000 -0500
12031 +++ linux-2.6.27.10/drivers/ata/ata_piix.c      2008-11-18 03:38:44.000000000 -0500
12032 @@ -284,7 +284,7 @@ static const struct pci_device_id piix_p
12033         /* SATA Controller IDE (PCH) */
12034         { 0x8086, 0x3b2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
12035  
12036 -       { }     /* terminate list */
12037 +       { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */
12038  };
12039  
12040  static struct pci_driver piix_pci_driver = {
12041 @@ -587,7 +587,7 @@ static const struct ich_laptop ich_lapto
12042         { 0x266F, 0x1025, 0x0066 },     /* ICH6 on ACER Aspire 1694WLMi */
12043         { 0x2653, 0x1043, 0x82D8 },     /* ICH6M on Asus Eee 701 */
12044         /* end marker */
12045 -       { 0, }
12046 +       { 0, 0, 0 }
12047  };
12048  
12049  /**
12050 @@ -1143,7 +1143,7 @@ static int piix_broken_suspend(void)
12051                         },
12052                 },
12053  
12054 -               { }     /* terminate list */
12055 +               { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }       /* terminate list */
12056         };
12057         static const char *oemstrs[] = {
12058                 "Tecra M3,",
12059 diff -urNp linux-2.6.27.10/drivers/ata/libata-core.c linux-2.6.27.10/drivers/ata/libata-core.c
12060 --- linux-2.6.27.10/drivers/ata/libata-core.c   2008-12-21 01:18:11.000000000 -0500
12061 +++ linux-2.6.27.10/drivers/ata/libata-core.c   2008-12-21 01:18:21.000000000 -0500
12062 @@ -746,7 +746,7 @@ static const struct ata_xfer_ent {
12063         { ATA_SHIFT_PIO, ATA_NR_PIO_MODES, XFER_PIO_0 },
12064         { ATA_SHIFT_MWDMA, ATA_NR_MWDMA_MODES, XFER_MW_DMA_0 },
12065         { ATA_SHIFT_UDMA, ATA_NR_UDMA_MODES, XFER_UDMA_0 },
12066 -       { -1, },
12067 +       { -1, 0, 0 }
12068  };
12069  
12070  /**
12071 @@ -2917,7 +2917,7 @@ static const struct ata_timing ata_timin
12072         { XFER_UDMA_5,     0,   0,   0,   0,   0,   0,   0,  20 },
12073         { XFER_UDMA_6,     0,   0,   0,   0,   0,   0,   0,  15 },
12074  
12075 -       { 0xFF }
12076 +       { 0xFF, 0, 0, 0, 0, 0, 0, 0, 0 }
12077  };
12078  
12079  #define ENOUGH(v, unit)                (((v)-1)/(unit)+1)
12080 @@ -4073,7 +4073,7 @@ static const struct ata_blacklist_entry 
12081         { "TSSTcorp CDDVDW SH-S202N", "SB01",     ATA_HORKAGE_IVB, },
12082  
12083         /* End Marker */
12084 -       { }
12085 +       { NULL, NULL, 0 }
12086  };
12087  
12088  static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
12089 diff -urNp linux-2.6.27.10/drivers/char/agp/frontend.c linux-2.6.27.10/drivers/char/agp/frontend.c
12090 --- linux-2.6.27.10/drivers/char/agp/frontend.c 2008-11-07 12:55:34.000000000 -0500
12091 +++ linux-2.6.27.10/drivers/char/agp/frontend.c 2008-11-18 03:38:44.000000000 -0500
12092 @@ -824,7 +824,7 @@ static int agpioc_reserve_wrap(struct ag
12093         if (copy_from_user(&reserve, arg, sizeof(struct agp_region)))
12094                 return -EFAULT;
12095  
12096 -       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment))
12097 +       if ((unsigned) reserve.seg_count >= ~0U/sizeof(struct agp_segment_priv))
12098                 return -EFAULT;
12099  
12100         client = agp_find_client_by_pid(reserve.pid);
12101 diff -urNp linux-2.6.27.10/drivers/char/agp/intel-agp.c linux-2.6.27.10/drivers/char/agp/intel-agp.c
12102 --- linux-2.6.27.10/drivers/char/agp/intel-agp.c        2008-11-07 12:55:34.000000000 -0500
12103 +++ linux-2.6.27.10/drivers/char/agp/intel-agp.c        2008-11-18 03:38:44.000000000 -0500
12104 @@ -2332,7 +2332,7 @@ static struct pci_device_id agp_intel_pc
12105         ID(PCI_DEVICE_ID_INTEL_Q45_HB),
12106         ID(PCI_DEVICE_ID_INTEL_G45_HB),
12107         ID(PCI_DEVICE_ID_INTEL_G41_HB),
12108 -       { }
12109 +       { 0, 0, 0, 0, 0, 0, 0 }
12110  };
12111  
12112  MODULE_DEVICE_TABLE(pci, agp_intel_pci_table);
12113 diff -urNp linux-2.6.27.10/drivers/char/hpet.c linux-2.6.27.10/drivers/char/hpet.c
12114 --- linux-2.6.27.10/drivers/char/hpet.c 2008-11-07 12:55:34.000000000 -0500
12115 +++ linux-2.6.27.10/drivers/char/hpet.c 2008-11-18 03:38:44.000000000 -0500
12116 @@ -959,7 +959,7 @@ static struct acpi_driver hpet_acpi_driv
12117                 },
12118  };
12119  
12120 -static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops };
12121 +static struct miscdevice hpet_misc = { HPET_MINOR, "hpet", &hpet_fops, {NULL, NULL}, NULL, NULL };
12122  
12123  static int __init hpet_init(void)
12124  {
12125 diff -urNp linux-2.6.27.10/drivers/char/keyboard.c linux-2.6.27.10/drivers/char/keyboard.c
12126 --- linux-2.6.27.10/drivers/char/keyboard.c     2008-11-07 12:55:34.000000000 -0500
12127 +++ linux-2.6.27.10/drivers/char/keyboard.c     2008-11-18 03:38:44.000000000 -0500
12128 @@ -635,6 +635,16 @@ static void k_spec(struct vc_data *vc, u
12129              kbd->kbdmode == VC_MEDIUMRAW) &&
12130              value != KVAL(K_SAK))
12131                 return;         /* SAK is allowed even in raw mode */
12132 +
12133 +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP)
12134 +       {
12135 +               void *func = fn_handler[value];
12136 +               if (func == fn_show_state || func == fn_show_ptregs ||
12137 +                   func == fn_show_mem)
12138 +                       return;
12139 +       }
12140 +#endif
12141 +
12142         fn_handler[value](vc);
12143  }
12144  
12145 @@ -1388,7 +1398,7 @@ static const struct input_device_id kbd_
12146                  .evbit = { BIT_MASK(EV_SND) },
12147          },
12148  
12149 -       { },    /* Terminating entry */
12150 +       { 0 },    /* Terminating entry */
12151  };
12152  
12153  MODULE_DEVICE_TABLE(input, kbd_ids);
12154 diff -urNp linux-2.6.27.10/drivers/char/mem.c linux-2.6.27.10/drivers/char/mem.c
12155 --- linux-2.6.27.10/drivers/char/mem.c  2008-11-07 12:55:34.000000000 -0500
12156 +++ linux-2.6.27.10/drivers/char/mem.c  2008-11-18 03:38:44.000000000 -0500
12157 @@ -27,6 +27,7 @@
12158  #include <linux/splice.h>
12159  #include <linux/pfn.h>
12160  #include <linux/smp_lock.h>
12161 +#include <linux/grsecurity.h>
12162  
12163  #include <asm/uaccess.h>
12164  #include <asm/io.h>
12165 @@ -35,6 +36,10 @@
12166  # include <linux/efi.h>
12167  #endif
12168  
12169 +#ifdef CONFIG_GRKERNSEC
12170 +extern struct file_operations grsec_fops;
12171 +#endif
12172 +
12173  /*
12174   * Architectures vary in how they handle caching for addresses
12175   * outside of main memory.
12176 @@ -192,6 +197,11 @@ static ssize_t write_mem(struct file * f
12177         if (!valid_phys_addr_range(p, count))
12178                 return -EFAULT;
12179  
12180 +#ifdef CONFIG_GRKERNSEC_KMEM
12181 +       gr_handle_mem_write();
12182 +       return -EPERM;
12183 +#endif
12184 +
12185         written = 0;
12186  
12187  #ifdef __ARCH_HAS_NO_PAGE_ZERO_MAPPED
12188 @@ -350,6 +360,11 @@ static int mmap_mem(struct file * file, 
12189                                                 &vma->vm_page_prot))
12190                 return -EINVAL;
12191  
12192 +#ifdef CONFIG_GRKERNSEC_KMEM
12193 +       if (gr_handle_mem_mmap(vma->vm_pgoff << PAGE_SHIFT, vma))
12194 +               return -EPERM;
12195 +#endif
12196 +
12197         vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
12198                                                  size,
12199                                                  vma->vm_page_prot);
12200 @@ -588,6 +603,11 @@ static ssize_t write_kmem(struct file * 
12201         ssize_t written;
12202         char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
12203  
12204 +#ifdef CONFIG_GRKERNSEC_KMEM
12205 +       gr_handle_kmem_write();
12206 +       return -EPERM;
12207 +#endif
12208 +
12209         if (p < (unsigned long) high_memory) {
12210  
12211                 wrote = count;
12212 @@ -791,6 +811,16 @@ static loff_t memory_lseek(struct file *
12213  
12214  static int open_port(struct inode * inode, struct file * filp)
12215  {
12216 +#ifdef CONFIG_GRKERNSEC_KMEM
12217 +       gr_handle_open_port();
12218 +       return -EPERM;
12219 +#endif
12220 +
12221 +       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12222 +}
12223 +
12224 +static int open_mem(struct inode * inode, struct file * filp)
12225 +{
12226         return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
12227  }
12228  
12229 @@ -798,7 +828,6 @@ static int open_port(struct inode * inod
12230  #define full_lseek      null_lseek
12231  #define write_zero     write_null
12232  #define read_full       read_zero
12233 -#define open_mem       open_port
12234  #define open_kmem      open_mem
12235  #define open_oldmem    open_mem
12236  
12237 @@ -938,6 +967,11 @@ static int memory_open(struct inode * in
12238                         filp->f_op = &oldmem_fops;
12239                         break;
12240  #endif
12241 +#ifdef CONFIG_GRKERNSEC
12242 +               case 13:
12243 +                       filp->f_op = &grsec_fops;
12244 +                       break;
12245 +#endif
12246                 default:
12247                         unlock_kernel();
12248                         return -ENXIO;
12249 @@ -974,6 +1008,9 @@ static const struct {
12250  #ifdef CONFIG_CRASH_DUMP
12251         {12,"oldmem",    S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops},
12252  #endif
12253 +#ifdef CONFIG_GRKERNSEC
12254 +       {13,"grsec",    S_IRUSR | S_IWUGO,          &grsec_fops},
12255 +#endif
12256  };
12257  
12258  static struct class *mem_class;
12259 diff -urNp linux-2.6.27.10/drivers/char/nvram.c linux-2.6.27.10/drivers/char/nvram.c
12260 --- linux-2.6.27.10/drivers/char/nvram.c        2008-11-07 12:55:34.000000000 -0500
12261 +++ linux-2.6.27.10/drivers/char/nvram.c        2008-11-18 03:38:44.000000000 -0500
12262 @@ -433,7 +433,10 @@ static const struct file_operations nvra
12263  static struct miscdevice nvram_dev = {
12264         NVRAM_MINOR,
12265         "nvram",
12266 -       &nvram_fops
12267 +       &nvram_fops,
12268 +       {NULL, NULL},
12269 +       NULL,
12270 +       NULL
12271  };
12272  
12273  static int __init
12274 diff -urNp linux-2.6.27.10/drivers/char/random.c linux-2.6.27.10/drivers/char/random.c
12275 --- linux-2.6.27.10/drivers/char/random.c       2008-11-07 12:55:34.000000000 -0500
12276 +++ linux-2.6.27.10/drivers/char/random.c       2008-11-18 03:38:44.000000000 -0500
12277 @@ -249,8 +249,13 @@
12278  /*
12279   * Configuration information
12280   */
12281 +#ifdef CONFIG_GRKERNSEC_RANDNET
12282 +#define INPUT_POOL_WORDS 512
12283 +#define OUTPUT_POOL_WORDS 128
12284 +#else
12285  #define INPUT_POOL_WORDS 128
12286  #define OUTPUT_POOL_WORDS 32
12287 +#endif
12288  #define SEC_XFER_SIZE 512
12289  
12290  /*
12291 @@ -287,10 +292,17 @@ static struct poolinfo {
12292         int poolwords;
12293         int tap1, tap2, tap3, tap4, tap5;
12294  } poolinfo_table[] = {
12295 +#ifdef CONFIG_GRKERNSEC_RANDNET
12296 +       /* x^512 + x^411 + x^308 + x^208 +x^104 + x + 1 -- 225 */
12297 +       { 512,  411,    308,    208,    104,    1 },
12298 +       /* x^128 + x^103 + x^76 + x^51 + x^25 + x + 1 -- 105 */
12299 +       { 128,  103,    76,     51,     25,     1 },
12300 +#else
12301         /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
12302         { 128,  103,    76,     51,     25,     1 },
12303         /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
12304         { 32,   26,     20,     14,     7,      1 },
12305 +#endif
12306  #if 0
12307         /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
12308         { 2048, 1638,   1231,   819,    411,    1 },
12309 @@ -1166,7 +1178,7 @@ EXPORT_SYMBOL(generate_random_uuid);
12310  #include <linux/sysctl.h>
12311  
12312  static int min_read_thresh = 8, min_write_thresh;
12313 -static int max_read_thresh = INPUT_POOL_WORDS * 32;
12314 +static int max_read_thresh = OUTPUT_POOL_WORDS * 32;
12315  static int max_write_thresh = INPUT_POOL_WORDS * 32;
12316  static char sysctl_bootid[16];
12317  
12318 diff -urNp linux-2.6.27.10/drivers/char/tpm/tpm.c linux-2.6.27.10/drivers/char/tpm/tpm.c
12319 --- linux-2.6.27.10/drivers/char/tpm/tpm.c      2008-11-07 12:55:34.000000000 -0500
12320 +++ linux-2.6.27.10/drivers/char/tpm/tpm.c      2008-11-18 03:38:44.000000000 -0500
12321 @@ -1037,7 +1037,7 @@ ssize_t tpm_write(struct file *file, con
12322  
12323         mutex_lock(&chip->buffer_mutex);
12324  
12325 -       if (in_size > TPM_BUFSIZE)
12326 +       if (in_size > (unsigned int)TPM_BUFSIZE)
12327                 in_size = TPM_BUFSIZE;
12328  
12329         if (copy_from_user
12330 diff -urNp linux-2.6.27.10/drivers/char/vt_ioctl.c linux-2.6.27.10/drivers/char/vt_ioctl.c
12331 --- linux-2.6.27.10/drivers/char/vt_ioctl.c     2008-11-07 12:55:34.000000000 -0500
12332 +++ linux-2.6.27.10/drivers/char/vt_ioctl.c     2008-11-18 03:38:44.000000000 -0500
12333 @@ -96,6 +96,12 @@ do_kdsk_ioctl(int cmd, struct kbentry __
12334         case KDSKBENT:
12335                 if (!perm)
12336                         return -EPERM;
12337 +
12338 +#ifdef CONFIG_GRKERNSEC
12339 +               if (!capable(CAP_SYS_TTY_CONFIG))
12340 +                       return -EPERM;
12341 +#endif
12342 +
12343                 if (!i && v == K_NOSUCHMAP) {
12344                         /* deallocate map */
12345                         key_map = key_maps[s];
12346 @@ -236,6 +242,13 @@ do_kdgkb_ioctl(int cmd, struct kbsentry 
12347                         goto reterr;
12348                 }
12349  
12350 +#ifdef CONFIG_GRKERNSEC
12351 +               if (!capable(CAP_SYS_TTY_CONFIG)) {
12352 +                       ret = -EPERM;
12353 +                       goto reterr;
12354 +               }
12355 +#endif
12356 +
12357                 q = func_table[i];
12358                 first_free = funcbufptr + (funcbufsize - funcbufleft);
12359                 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) 
12360 diff -urNp linux-2.6.27.10/drivers/edac/edac_core.h linux-2.6.27.10/drivers/edac/edac_core.h
12361 --- linux-2.6.27.10/drivers/edac/edac_core.h    2008-11-07 12:55:34.000000000 -0500
12362 +++ linux-2.6.27.10/drivers/edac/edac_core.h    2008-11-18 03:38:44.000000000 -0500
12363 @@ -85,11 +85,11 @@ extern int edac_debug_level;
12364  
12365  #else                          /* !CONFIG_EDAC_DEBUG */
12366  
12367 -#define debugf0( ... )
12368 -#define debugf1( ... )
12369 -#define debugf2( ... )
12370 -#define debugf3( ... )
12371 -#define debugf4( ... )
12372 +#define debugf0( ... ) do {} while (0)
12373 +#define debugf1( ... ) do {} while (0)
12374 +#define debugf2( ... ) do {} while (0)
12375 +#define debugf3( ... ) do {} while (0)
12376 +#define debugf4( ... ) do {} while (0)
12377  
12378  #endif                         /* !CONFIG_EDAC_DEBUG */
12379  
12380 diff -urNp linux-2.6.27.10/drivers/firmware/dmi_scan.c linux-2.6.27.10/drivers/firmware/dmi_scan.c
12381 --- linux-2.6.27.10/drivers/firmware/dmi_scan.c 2008-11-07 12:55:34.000000000 -0500
12382 +++ linux-2.6.27.10/drivers/firmware/dmi_scan.c 2008-11-18 03:38:44.000000000 -0500
12383 @@ -384,11 +384,6 @@ void __init dmi_scan_machine(void)
12384                 }
12385         }
12386         else {
12387 -               /*
12388 -                * no iounmap() for that ioremap(); it would be a no-op, but
12389 -                * it's so early in setup that sucker gets confused into doing
12390 -                * what it shouldn't if we actually call it.
12391 -                */
12392                 p = dmi_ioremap(0xF0000, 0x10000);
12393                 if (p == NULL)
12394                         goto out;
12395 diff -urNp linux-2.6.27.10/drivers/hwmon/fscpos.c linux-2.6.27.10/drivers/hwmon/fscpos.c
12396 --- linux-2.6.27.10/drivers/hwmon/fscpos.c      2008-11-07 12:55:34.000000000 -0500
12397 +++ linux-2.6.27.10/drivers/hwmon/fscpos.c      2008-11-18 03:38:44.000000000 -0500
12398 @@ -240,7 +240,6 @@ static ssize_t set_pwm(struct i2c_client
12399         unsigned long v = simple_strtoul(buf, NULL, 10);
12400  
12401         /* Range: 0..255 */
12402 -       if (v < 0) v = 0;
12403         if (v > 255) v = 255;
12404  
12405         mutex_lock(&data->update_lock);
12406 diff -urNp linux-2.6.27.10/drivers/hwmon/k8temp.c linux-2.6.27.10/drivers/hwmon/k8temp.c
12407 --- linux-2.6.27.10/drivers/hwmon/k8temp.c      2008-11-07 12:55:34.000000000 -0500
12408 +++ linux-2.6.27.10/drivers/hwmon/k8temp.c      2008-11-18 03:38:44.000000000 -0500
12409 @@ -130,7 +130,7 @@ static DEVICE_ATTR(name, S_IRUGO, show_n
12410  
12411  static struct pci_device_id k8temp_ids[] = {
12412         { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
12413 -       { 0 },
12414 +       { 0, 0, 0, 0, 0, 0, 0 },
12415  };
12416  
12417  MODULE_DEVICE_TABLE(pci, k8temp_ids);
12418 diff -urNp linux-2.6.27.10/drivers/hwmon/sis5595.c linux-2.6.27.10/drivers/hwmon/sis5595.c
12419 --- linux-2.6.27.10/drivers/hwmon/sis5595.c     2008-11-07 12:55:34.000000000 -0500
12420 +++ linux-2.6.27.10/drivers/hwmon/sis5595.c     2008-11-18 03:38:44.000000000 -0500
12421 @@ -698,7 +698,7 @@ static struct sis5595_data *sis5595_upda
12422  
12423  static struct pci_device_id sis5595_pci_ids[] = {
12424         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12425 -       { 0, }
12426 +       { 0, 0, 0, 0, 0, 0, 0 }
12427  };
12428  
12429  MODULE_DEVICE_TABLE(pci, sis5595_pci_ids);
12430 diff -urNp linux-2.6.27.10/drivers/hwmon/via686a.c linux-2.6.27.10/drivers/hwmon/via686a.c
12431 --- linux-2.6.27.10/drivers/hwmon/via686a.c     2008-11-07 12:55:34.000000000 -0500
12432 +++ linux-2.6.27.10/drivers/hwmon/via686a.c     2008-11-18 03:38:44.000000000 -0500
12433 @@ -768,7 +768,7 @@ static struct via686a_data *via686a_upda
12434  
12435  static struct pci_device_id via686a_pci_ids[] = {
12436         { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4) },
12437 -       { 0, }
12438 +       { 0, 0, 0, 0, 0, 0, 0 }
12439  };
12440  
12441  MODULE_DEVICE_TABLE(pci, via686a_pci_ids);
12442 diff -urNp linux-2.6.27.10/drivers/hwmon/vt8231.c linux-2.6.27.10/drivers/hwmon/vt8231.c
12443 --- linux-2.6.27.10/drivers/hwmon/vt8231.c      2008-11-07 12:55:34.000000000 -0500
12444 +++ linux-2.6.27.10/drivers/hwmon/vt8231.c      2008-11-18 03:38:44.000000000 -0500
12445 @@ -698,7 +698,7 @@ static struct platform_driver vt8231_dri
12446  
12447  static struct pci_device_id vt8231_pci_ids[] = {
12448         { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231_4) },
12449 -       { 0, }
12450 +       { 0, 0, 0, 0, 0, 0, 0 }
12451  };
12452  
12453  MODULE_DEVICE_TABLE(pci, vt8231_pci_ids);
12454 diff -urNp linux-2.6.27.10/drivers/hwmon/w83791d.c linux-2.6.27.10/drivers/hwmon/w83791d.c
12455 --- linux-2.6.27.10/drivers/hwmon/w83791d.c     2008-11-07 12:55:34.000000000 -0500
12456 +++ linux-2.6.27.10/drivers/hwmon/w83791d.c     2008-11-18 03:38:44.000000000 -0500
12457 @@ -289,8 +289,8 @@ static int w83791d_detect(struct i2c_cli
12458                           struct i2c_board_info *info);
12459  static int w83791d_remove(struct i2c_client *client);
12460  
12461 -static int w83791d_read(struct i2c_client *client, u8 register);
12462 -static int w83791d_write(struct i2c_client *client, u8 register, u8 value);
12463 +static int w83791d_read(struct i2c_client *client, u8 reg);
12464 +static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
12465  static struct w83791d_data *w83791d_update_device(struct device *dev);
12466  
12467  #ifdef DEBUG
12468 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c
12469 --- linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c       2008-11-07 12:55:34.000000000 -0500
12470 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-i801.c       2008-11-18 03:38:44.000000000 -0500
12471 @@ -576,7 +576,7 @@ static struct pci_device_id i801_ids[] =
12472         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TOLAPAI_1) },
12473         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_4) },
12474         { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10_5) },
12475 -       { 0, }
12476 +       { 0, 0, 0, 0, 0, 0, 0 }
12477  };
12478  
12479  MODULE_DEVICE_TABLE (pci, i801_ids);
12480 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c
12481 --- linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c      2008-11-07 12:55:34.000000000 -0500
12482 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-piix4.c      2008-11-18 03:38:44.000000000 -0500
12483 @@ -123,7 +123,7 @@ static struct dmi_system_id __devinitdat
12484                 .ident = "IBM",
12485                 .matches = { DMI_MATCH(DMI_SYS_VENDOR, "IBM"), },
12486         },
12487 -       { },
12488 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL },
12489  };
12490  
12491  static int __devinit piix4_setup(struct pci_dev *PIIX4_dev,
12492 @@ -424,7 +424,7 @@ static struct pci_device_id piix4_ids[] 
12493                      PCI_DEVICE_ID_SERVERWORKS_CSB6) },
12494         { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS,
12495                      PCI_DEVICE_ID_SERVERWORKS_HT1000SB) },
12496 -       { 0, }
12497 +       { 0, 0, 0, 0, 0, 0, 0 }
12498  };
12499  
12500  MODULE_DEVICE_TABLE (pci, piix4_ids);
12501 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c
12502 --- linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c     2008-11-07 12:55:34.000000000 -0500
12503 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-sis630.c     2008-11-18 03:38:44.000000000 -0500
12504 @@ -472,7 +472,7 @@ static struct i2c_adapter sis630_adapter
12505  static struct pci_device_id sis630_ids[] __devinitdata = {
12506         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
12507         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
12508 -       { 0, }
12509 +       { 0, 0, 0, 0, 0, 0, 0 }
12510  };
12511  
12512  MODULE_DEVICE_TABLE (pci, sis630_ids);
12513 diff -urNp linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c
12514 --- linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c     2008-11-07 12:55:34.000000000 -0500
12515 +++ linux-2.6.27.10/drivers/i2c/busses/i2c-sis96x.c     2008-11-18 03:38:44.000000000 -0500
12516 @@ -248,7 +248,7 @@ static struct i2c_adapter sis96x_adapter
12517  
12518  static struct pci_device_id sis96x_ids[] = {
12519         { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
12520 -       { 0, }
12521 +       { 0, 0, 0, 0, 0, 0, 0 }
12522  };
12523  
12524  MODULE_DEVICE_TABLE (pci, sis96x_ids);
12525 diff -urNp linux-2.6.27.10/drivers/ieee1394/dv1394.c linux-2.6.27.10/drivers/ieee1394/dv1394.c
12526 --- linux-2.6.27.10/drivers/ieee1394/dv1394.c   2008-11-07 12:55:34.000000000 -0500
12527 +++ linux-2.6.27.10/drivers/ieee1394/dv1394.c   2008-11-18 03:38:44.000000000 -0500
12528 @@ -739,7 +739,7 @@ static void frame_prepare(struct video_c
12529         based upon DIF section and sequence
12530  */
12531  
12532 -static void inline
12533 +static inline void
12534  frame_put_packet (struct frame *f, struct packet *p)
12535  {
12536         int section_type = p->data[0] >> 5;           /* section type is in bits 5 - 7 */
12537 @@ -918,7 +918,7 @@ static int do_dv1394_init(struct video_c
12538                 /* default SYT offset is 3 cycles */
12539                 init->syt_offset = 3;
12540  
12541 -       if ( (init->channel > 63) || (init->channel < 0) )
12542 +       if (init->channel > 63)
12543                 init->channel = 63;
12544  
12545         chan_mask = (u64)1 << init->channel;
12546 @@ -2174,7 +2174,7 @@ static struct ieee1394_device_id dv1394_
12547                 .specifier_id   = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff,
12548                 .version        = AVC_SW_VERSION_ENTRY & 0xffffff
12549         },
12550 -       { }
12551 +       { 0, 0, 0, 0, 0, 0 }
12552  };
12553  
12554  MODULE_DEVICE_TABLE(ieee1394, dv1394_id_table);
12555 diff -urNp linux-2.6.27.10/drivers/ieee1394/eth1394.c linux-2.6.27.10/drivers/ieee1394/eth1394.c
12556 --- linux-2.6.27.10/drivers/ieee1394/eth1394.c  2008-11-07 12:55:34.000000000 -0500
12557 +++ linux-2.6.27.10/drivers/ieee1394/eth1394.c  2008-11-18 03:38:44.000000000 -0500
12558 @@ -451,7 +451,7 @@ static struct ieee1394_device_id eth1394
12559                 .specifier_id = ETHER1394_GASP_SPECIFIER_ID,
12560                 .version = ETHER1394_GASP_VERSION,
12561         },
12562 -       {}
12563 +       { 0, 0, 0, 0, 0, 0 }
12564  };
12565  
12566  MODULE_DEVICE_TABLE(ieee1394, eth1394_id_table);
12567 diff -urNp linux-2.6.27.10/drivers/ieee1394/hosts.c linux-2.6.27.10/drivers/ieee1394/hosts.c
12568 --- linux-2.6.27.10/drivers/ieee1394/hosts.c    2008-11-07 12:55:34.000000000 -0500
12569 +++ linux-2.6.27.10/drivers/ieee1394/hosts.c    2008-11-18 03:38:44.000000000 -0500
12570 @@ -78,6 +78,7 @@ static int dummy_isoctl(struct hpsb_iso 
12571  }
12572  
12573  static struct hpsb_host_driver dummy_driver = {
12574 +       .name =            "dummy",
12575         .transmit_packet = dummy_transmit_packet,
12576         .devctl =          dummy_devctl,
12577         .isoctl =          dummy_isoctl
12578 diff -urNp linux-2.6.27.10/drivers/ieee1394/ohci1394.c linux-2.6.27.10/drivers/ieee1394/ohci1394.c
12579 --- linux-2.6.27.10/drivers/ieee1394/ohci1394.c 2008-11-07 12:55:34.000000000 -0500
12580 +++ linux-2.6.27.10/drivers/ieee1394/ohci1394.c 2008-11-18 03:38:44.000000000 -0500
12581 @@ -147,9 +147,9 @@ printk(level "%s: " fmt "\n" , OHCI1394_
12582  printk(level "%s: fw-host%d: " fmt "\n" , OHCI1394_DRIVER_NAME, ohci->host->id , ## args)
12583  
12584  /* Module Parameters */
12585 -static int phys_dma = 1;
12586 +static int phys_dma;
12587  module_param(phys_dma, int, 0444);
12588 -MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 1).");
12589 +MODULE_PARM_DESC(phys_dma, "Enable physical DMA (default = 0).");
12590  
12591  static void dma_trm_tasklet(unsigned long data);
12592  static void dma_trm_reset(struct dma_trm_ctx *d);
12593 @@ -3437,7 +3437,7 @@ static struct pci_device_id ohci1394_pci
12594                 .subvendor =    PCI_ANY_ID,
12595                 .subdevice =    PCI_ANY_ID,
12596         },
12597 -       { 0, },
12598 +       { 0, 0, 0, 0, 0, 0, 0 },
12599  };
12600  
12601  MODULE_DEVICE_TABLE(pci, ohci1394_pci_tbl);
12602 diff -urNp linux-2.6.27.10/drivers/ieee1394/raw1394.c linux-2.6.27.10/drivers/ieee1394/raw1394.c
12603 --- linux-2.6.27.10/drivers/ieee1394/raw1394.c  2008-11-07 12:55:34.000000000 -0500
12604 +++ linux-2.6.27.10/drivers/ieee1394/raw1394.c  2008-11-18 03:38:44.000000000 -0500
12605 @@ -2968,7 +2968,7 @@ static struct ieee1394_device_id raw1394
12606          .match_flags = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12607          .specifier_id = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12608          .version = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff},
12609 -       {}
12610 +       { 0, 0, 0, 0, 0, 0 }
12611  };
12612  
12613  MODULE_DEVICE_TABLE(ieee1394, raw1394_id_table);
12614 diff -urNp linux-2.6.27.10/drivers/ieee1394/sbp2.c linux-2.6.27.10/drivers/ieee1394/sbp2.c
12615 --- linux-2.6.27.10/drivers/ieee1394/sbp2.c     2008-12-10 22:35:37.000000000 -0500
12616 +++ linux-2.6.27.10/drivers/ieee1394/sbp2.c     2008-12-10 22:35:46.000000000 -0500
12617 @@ -290,7 +290,7 @@ static struct ieee1394_device_id sbp2_id
12618          .match_flags   = IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION,
12619          .specifier_id  = SBP2_UNIT_SPEC_ID_ENTRY & 0xffffff,
12620          .version       = SBP2_SW_VERSION_ENTRY & 0xffffff},
12621 -       {}
12622 +       { 0, 0, 0, 0, 0, 0 }
12623  };
12624  MODULE_DEVICE_TABLE(ieee1394, sbp2_id_table);
12625  
12626 @@ -2135,7 +2135,7 @@ MODULE_DESCRIPTION("IEEE-1394 SBP-2 prot
12627  MODULE_SUPPORTED_DEVICE(SBP2_DEVICE_NAME);
12628  MODULE_LICENSE("GPL");
12629  
12630 -static int sbp2_module_init(void)
12631 +static int __init sbp2_module_init(void)
12632  {
12633         int ret;
12634  
12635 diff -urNp linux-2.6.27.10/drivers/ieee1394/video1394.c linux-2.6.27.10/drivers/ieee1394/video1394.c
12636 --- linux-2.6.27.10/drivers/ieee1394/video1394.c        2008-11-07 12:55:34.000000000 -0500
12637 +++ linux-2.6.27.10/drivers/ieee1394/video1394.c        2008-11-18 03:38:44.000000000 -0500
12638 @@ -893,7 +893,7 @@ static long video1394_ioctl(struct file 
12639                 if (unlikely(d == NULL))
12640                         return -EFAULT;
12641  
12642 -               if (unlikely((v.buffer<0) || (v.buffer>=d->num_desc - 1))) {
12643 +               if (unlikely(v.buffer>=d->num_desc - 1)) {
12644                         PRINT(KERN_ERR, ohci->host->id,
12645                               "Buffer %d out of range",v.buffer);
12646                         return -EINVAL;
12647 @@ -959,7 +959,7 @@ static long video1394_ioctl(struct file 
12648                 if (unlikely(d == NULL))
12649                         return -EFAULT;
12650  
12651 -               if (unlikely((v.buffer<0) || (v.buffer>d->num_desc - 1))) {
12652 +               if (unlikely(v.buffer>d->num_desc - 1)) {
12653                         PRINT(KERN_ERR, ohci->host->id,
12654                               "Buffer %d out of range",v.buffer);
12655                         return -EINVAL;
12656 @@ -1030,7 +1030,7 @@ static long video1394_ioctl(struct file 
12657                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12658                 if (d == NULL) return -EFAULT;
12659  
12660 -               if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) {
12661 +               if (v.buffer>=d->num_desc - 1) {
12662                         PRINT(KERN_ERR, ohci->host->id,
12663                               "Buffer %d out of range",v.buffer);
12664                         return -EINVAL;
12665 @@ -1137,7 +1137,7 @@ static long video1394_ioctl(struct file 
12666                 d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel);
12667                 if (d == NULL) return -EFAULT;
12668  
12669 -               if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) {
12670 +               if (v.buffer>=d->num_desc-1) {
12671                         PRINT(KERN_ERR, ohci->host->id,
12672                               "Buffer %d out of range",v.buffer);
12673                         return -EINVAL;
12674 @@ -1310,7 +1310,7 @@ static struct ieee1394_device_id video13
12675                  .specifier_id   = CAMERA_UNIT_SPEC_ID_ENTRY & 0xffffff,
12676                  .version        = (CAMERA_SW_VERSION_ENTRY + 2) & 0xffffff
12677          },
12678 -       { }
12679 +       { 0, 0, 0, 0, 0, 0 }
12680  };
12681  
12682  MODULE_DEVICE_TABLE(ieee1394, video1394_id_table);
12683 diff -urNp linux-2.6.27.10/drivers/input/keyboard/atkbd.c linux-2.6.27.10/drivers/input/keyboard/atkbd.c
12684 --- linux-2.6.27.10/drivers/input/keyboard/atkbd.c      2008-12-10 22:35:37.000000000 -0500
12685 +++ linux-2.6.27.10/drivers/input/keyboard/atkbd.c      2008-12-10 22:35:46.000000000 -0500
12686 @@ -1148,7 +1148,7 @@ static struct serio_device_id atkbd_seri
12687                 .id     = SERIO_ANY,
12688                 .extra  = SERIO_ANY,
12689         },
12690 -       { 0 }
12691 +       { 0, 0, 0, 0 }
12692  };
12693  
12694  MODULE_DEVICE_TABLE(serio, atkbd_serio_ids);
12695 diff -urNp linux-2.6.27.10/drivers/input/mouse/lifebook.c linux-2.6.27.10/drivers/input/mouse/lifebook.c
12696 --- linux-2.6.27.10/drivers/input/mouse/lifebook.c      2008-11-07 12:55:34.000000000 -0500
12697 +++ linux-2.6.27.10/drivers/input/mouse/lifebook.c      2008-11-18 03:38:44.000000000 -0500
12698 @@ -110,7 +110,7 @@ static const struct dmi_system_id lifebo
12699                         DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook B142"),
12700                 },
12701         },
12702 -       { }
12703 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL}
12704  };
12705  
12706  static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse)
12707 diff -urNp linux-2.6.27.10/drivers/input/mouse/psmouse-base.c linux-2.6.27.10/drivers/input/mouse/psmouse-base.c
12708 --- linux-2.6.27.10/drivers/input/mouse/psmouse-base.c  2008-11-07 12:55:34.000000000 -0500
12709 +++ linux-2.6.27.10/drivers/input/mouse/psmouse-base.c  2008-11-18 03:38:44.000000000 -0500
12710 @@ -1328,7 +1328,7 @@ static struct serio_device_id psmouse_se
12711                 .id     = SERIO_ANY,
12712                 .extra  = SERIO_ANY,
12713         },
12714 -       { 0 }
12715 +       { 0, 0, 0, 0 }
12716  };
12717  
12718  MODULE_DEVICE_TABLE(serio, psmouse_serio_ids);
12719 diff -urNp linux-2.6.27.10/drivers/input/mouse/synaptics.c linux-2.6.27.10/drivers/input/mouse/synaptics.c
12720 --- linux-2.6.27.10/drivers/input/mouse/synaptics.c     2008-11-07 12:55:34.000000000 -0500
12721 +++ linux-2.6.27.10/drivers/input/mouse/synaptics.c     2008-11-18 03:38:45.000000000 -0500
12722 @@ -417,7 +417,7 @@ static void synaptics_process_packet(str
12723                                 break;
12724                         case 2:
12725                                 if (SYN_MODEL_PEN(priv->model_id))
12726 -                                       ;   /* Nothing, treat a pen as a single finger */
12727 +                                       break;   /* Nothing, treat a pen as a single finger */
12728                                 break;
12729                         case 4 ... 15:
12730                                 if (SYN_CAP_PALMDETECT(priv->capabilities))
12731 @@ -624,7 +624,7 @@ static const struct dmi_system_id toshib
12732                         DMI_MATCH(DMI_PRODUCT_NAME, "PORTEGE M300"),
12733                 },
12734         },
12735 -       { }
12736 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12737  };
12738  #endif
12739  
12740 diff -urNp linux-2.6.27.10/drivers/input/mousedev.c linux-2.6.27.10/drivers/input/mousedev.c
12741 --- linux-2.6.27.10/drivers/input/mousedev.c    2008-11-07 12:55:34.000000000 -0500
12742 +++ linux-2.6.27.10/drivers/input/mousedev.c    2008-11-18 03:38:45.000000000 -0500
12743 @@ -1064,7 +1064,7 @@ static struct input_handler mousedev_han
12744  
12745  #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
12746  static struct miscdevice psaux_mouse = {
12747 -       PSMOUSE_MINOR, "psaux", &mousedev_fops
12748 +       PSMOUSE_MINOR, "psaux", &mousedev_fops, {NULL, NULL}, NULL, NULL
12749  };
12750  static int psaux_registered;
12751  #endif
12752 diff -urNp linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h
12753 --- linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h       2008-12-21 01:16:51.000000000 -0500
12754 +++ linux-2.6.27.10/drivers/input/serio/i8042-x86ia64io.h       2008-12-21 01:16:00.000000000 -0500
12755 @@ -143,7 +143,7 @@ static struct dmi_system_id __initdata i
12756                         DMI_MATCH(DMI_PRODUCT_VERSION, "M606"),
12757                 },
12758         },
12759 -       { }
12760 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12761  };
12762  
12763  /*
12764 @@ -351,7 +351,7 @@ static struct dmi_system_id __initdata i
12765                         DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
12766                 },
12767         },
12768 -       { }
12769 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12770  };
12771  
12772  #ifdef CONFIG_PNP
12773 @@ -363,7 +363,7 @@ static struct dmi_system_id __initdata i
12774                         DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
12775                 },
12776         },
12777 -       { }
12778 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12779  };
12780  #endif
12781  
12782 @@ -430,7 +430,7 @@ static struct dmi_system_id __initdata i
12783                         DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 4280"),
12784                 },
12785         },
12786 -       { }
12787 +       { NULL, NULL, {DMI_MATCH(DMI_NONE, NULL)}, NULL }
12788  };
12789  
12790  #endif /* CONFIG_X86 */
12791 diff -urNp linux-2.6.27.10/drivers/input/serio/serio_raw.c linux-2.6.27.10/drivers/input/serio/serio_raw.c
12792 --- linux-2.6.27.10/drivers/input/serio/serio_raw.c     2008-11-07 12:55:34.000000000 -0500
12793 +++ linux-2.6.27.10/drivers/input/serio/serio_raw.c     2008-11-18 03:38:45.000000000 -0500
12794 @@ -373,7 +373,7 @@ static struct serio_device_id serio_raw_
12795                 .id     = SERIO_ANY,
12796                 .extra  = SERIO_ANY,
12797         },
12798 -       { 0 }
12799 +       { 0, 0, 0, 0 }
12800  };
12801  
12802  MODULE_DEVICE_TABLE(serio, serio_raw_serio_ids);
12803 diff -urNp linux-2.6.27.10/drivers/md/bitmap.c linux-2.6.27.10/drivers/md/bitmap.c
12804 --- linux-2.6.27.10/drivers/md/bitmap.c 2008-11-07 12:55:34.000000000 -0500
12805 +++ linux-2.6.27.10/drivers/md/bitmap.c 2008-11-18 03:38:45.000000000 -0500
12806 @@ -57,7 +57,7 @@
12807  #  if DEBUG > 0
12808  #    define PRINTK(x...) printk(KERN_DEBUG x)
12809  #  else
12810 -#    define PRINTK(x...)
12811 +#    define PRINTK(x...) do {} while (0)
12812  #  endif
12813  #endif
12814  
12815 diff -urNp linux-2.6.27.10/drivers/mtd/devices/doc2000.c linux-2.6.27.10/drivers/mtd/devices/doc2000.c
12816 --- linux-2.6.27.10/drivers/mtd/devices/doc2000.c       2008-11-07 12:55:34.000000000 -0500
12817 +++ linux-2.6.27.10/drivers/mtd/devices/doc2000.c       2008-11-18 03:38:45.000000000 -0500
12818 @@ -777,7 +777,7 @@ static int doc_write(struct mtd_info *mt
12819  
12820                 /* The ECC will not be calculated correctly if less than 512 is written */
12821  /* DBB-
12822 -               if (len != 0x200 && eccbuf)
12823 +               if (len != 0x200)
12824                         printk(KERN_WARNING
12825                                "ECC needs a full sector write (adr: %lx size %lx)\n",
12826                                (long) to, (long) len);
12827 diff -urNp linux-2.6.27.10/drivers/mtd/devices/doc2001.c linux-2.6.27.10/drivers/mtd/devices/doc2001.c
12828 --- linux-2.6.27.10/drivers/mtd/devices/doc2001.c       2008-11-07 12:55:34.000000000 -0500
12829 +++ linux-2.6.27.10/drivers/mtd/devices/doc2001.c       2008-11-18 03:38:45.000000000 -0500
12830 @@ -396,6 +396,8 @@ static int doc_read (struct mtd_info *mt
12831         /* Don't allow read past end of device */
12832         if (from >= this->totlen)
12833                 return -EINVAL;
12834 +       if (!len)
12835 +               return -EINVAL;
12836  
12837         /* Don't allow a single read to cross a 512-byte block boundary */
12838         if (from + len > ((from | 0x1ff) + 1))
12839 diff -urNp linux-2.6.27.10/drivers/mtd/devices/slram.c linux-2.6.27.10/drivers/mtd/devices/slram.c
12840 --- linux-2.6.27.10/drivers/mtd/devices/slram.c 2008-11-07 12:55:34.000000000 -0500
12841 +++ linux-2.6.27.10/drivers/mtd/devices/slram.c 2008-11-18 03:38:45.000000000 -0500
12842 @@ -273,7 +273,7 @@ static int parse_cmdline(char *devname, 
12843         }
12844         T("slram: devname=%s, devstart=0x%lx, devlength=0x%lx\n",
12845                         devname, devstart, devlength);
12846 -       if ((devstart < 0) || (devlength < 0) || (devlength % SLRAM_BLK_SZ != 0)) {
12847 +       if (devlength % SLRAM_BLK_SZ != 0) {
12848                 E("slram: Illegal start / length parameter.\n");
12849                 return(-EINVAL);
12850         }
12851 diff -urNp linux-2.6.27.10/drivers/mtd/ubi/build.c linux-2.6.27.10/drivers/mtd/ubi/build.c
12852 --- linux-2.6.27.10/drivers/mtd/ubi/build.c     2008-11-07 12:55:34.000000000 -0500
12853 +++ linux-2.6.27.10/drivers/mtd/ubi/build.c     2008-11-18 03:38:45.000000000 -0500
12854 @@ -1104,7 +1104,7 @@ static int __init bytes_str_to_int(const
12855         unsigned long result;
12856  
12857         result = simple_strtoul(str, &endp, 0);
12858 -       if (str == endp || result < 0) {
12859 +       if (str == endp) {
12860                 printk(KERN_ERR "UBI error: incorrect bytes count: \"%s\"\n",
12861                        str);
12862                 return -EINVAL;
12863 diff -urNp linux-2.6.27.10/drivers/net/eepro100.c linux-2.6.27.10/drivers/net/eepro100.c
12864 --- linux-2.6.27.10/drivers/net/eepro100.c      2008-11-07 12:55:34.000000000 -0500
12865 +++ linux-2.6.27.10/drivers/net/eepro100.c      2008-11-18 03:38:45.000000000 -0500
12866 @@ -47,7 +47,7 @@ static int rxdmacount /* = 0 */;
12867  # define rx_align(skb)         skb_reserve((skb), 2)
12868  # define RxFD_ALIGNMENT                __attribute__ ((aligned (2), packed))
12869  #else
12870 -# define rx_align(skb)
12871 +# define rx_align(skb) do {} while (0)
12872  # define RxFD_ALIGNMENT
12873  #endif
12874  
12875 @@ -2334,33 +2334,33 @@ static void __devexit eepro100_remove_on
12876  }
12877  
12878  static struct pci_device_id eepro100_pci_tbl[] = {
12879 -       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, },
12880 -       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, },
12881 -       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, },
12882 -       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, },
12883 -       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, },
12884 -       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, },
12885 -       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, },
12886 -       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, },
12887 -       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, },
12888 -       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
12889 -       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
12890 -       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
12891 -       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
12892 -       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
12893 -       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
12894 -       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
12895 -       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
12896 -       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
12897 -       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, },
12898 -       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, },
12899 -       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
12900 -       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
12901 -       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
12902 -       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
12903 -       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
12904 -       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
12905 -       { 0,}
12906 +       { PCI_VENDOR_ID_INTEL, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12907 +       { PCI_VENDOR_ID_INTEL, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12908 +       { PCI_VENDOR_ID_INTEL, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12909 +       { PCI_VENDOR_ID_INTEL, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12910 +       { PCI_VENDOR_ID_INTEL, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12911 +       { PCI_VENDOR_ID_INTEL, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12912 +       { PCI_VENDOR_ID_INTEL, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12913 +       { PCI_VENDOR_ID_INTEL, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12914 +       { PCI_VENDOR_ID_INTEL, 0x1035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12915 +       { PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12916 +       { PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12917 +       { PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12918 +       { PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12919 +       { PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12920 +       { PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12921 +       { PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12922 +       { PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12923 +       { PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12924 +       { PCI_VENDOR_ID_INTEL, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12925 +       { PCI_VENDOR_ID_INTEL, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12926 +       { PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12927 +       { PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12928 +       { PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12929 +       { PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12930 +       { PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12931 +       { PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
12932 +       { 0, 0, 0, 0, 0, 0, 0 }
12933  };
12934  MODULE_DEVICE_TABLE(pci, eepro100_pci_tbl);
12935  
12936 diff -urNp linux-2.6.27.10/drivers/net/irda/vlsi_ir.c linux-2.6.27.10/drivers/net/irda/vlsi_ir.c
12937 --- linux-2.6.27.10/drivers/net/irda/vlsi_ir.c  2008-11-07 12:55:34.000000000 -0500
12938 +++ linux-2.6.27.10/drivers/net/irda/vlsi_ir.c  2008-11-18 03:38:45.000000000 -0500
12939 @@ -906,13 +906,12 @@ static int vlsi_hard_start_xmit(struct s
12940                         /* no race - tx-ring already empty */
12941                         vlsi_set_baud(idev, iobase);
12942                         netif_wake_queue(ndev);
12943 -               }
12944 -               else
12945 -                       ;
12946 +               } else {
12947                         /* keep the speed change pending like it would
12948                          * for any len>0 packet. tx completion interrupt
12949                          * will apply it when the tx ring becomes empty.
12950                          */
12951 +               }
12952                 spin_unlock_irqrestore(&idev->lock, flags);
12953                 dev_kfree_skb_any(skb);
12954                 return 0;
12955 diff -urNp linux-2.6.27.10/drivers/net/pcnet32.c linux-2.6.27.10/drivers/net/pcnet32.c
12956 --- linux-2.6.27.10/drivers/net/pcnet32.c       2008-11-07 12:55:34.000000000 -0500
12957 +++ linux-2.6.27.10/drivers/net/pcnet32.c       2008-11-18 03:38:45.000000000 -0500
12958 @@ -78,7 +78,7 @@ static int cards_found;
12959  /*
12960   * VLB I/O addresses
12961   */
12962 -static unsigned int pcnet32_portlist[] __initdata =
12963 +static unsigned int pcnet32_portlist[] __devinitdata =
12964      { 0x300, 0x320, 0x340, 0x360, 0 };
12965  
12966  static int pcnet32_debug = 0;
12967 diff -urNp linux-2.6.27.10/drivers/net/tg3.h linux-2.6.27.10/drivers/net/tg3.h
12968 --- linux-2.6.27.10/drivers/net/tg3.h   2008-11-07 12:55:34.000000000 -0500
12969 +++ linux-2.6.27.10/drivers/net/tg3.h   2008-11-18 03:38:45.000000000 -0500
12970 @@ -102,6 +102,7 @@
12971  #define  CHIPREV_ID_5750_A0             0x4000
12972  #define  CHIPREV_ID_5750_A1             0x4001
12973  #define  CHIPREV_ID_5750_A3             0x4003
12974 +#define  CHIPREV_ID_5750_C1             0x4201
12975  #define  CHIPREV_ID_5750_C2             0x4202
12976  #define  CHIPREV_ID_5752_A0_HW          0x5000
12977  #define  CHIPREV_ID_5752_A0             0x6000
12978 diff -urNp linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c
12979 --- linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-11-17 20:03:30.000000000 -0500
12980 +++ linux-2.6.27.10/drivers/net/wireless/iwlwifi/iwl3945-base.c 2008-12-27 13:44:22.000000000 -0500
12981 @@ -785,7 +785,7 @@ static int iwl3945_send_cmd_sync(struct 
12982                 IWL_ERROR("Error: Response NULL in '%s'\n",
12983                           get_cmd_string(cmd->id));
12984                 ret = -EIO;
12985 -               goto out;
12986 +               goto cancel;
12987         }
12988  
12989         ret = 0;
12990 diff -urNp linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c
12991 --- linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c  2008-11-07 12:55:34.000000000 -0500
12992 +++ linux-2.6.27.10/drivers/pci/hotplug/cpqphp_nvram.c  2008-11-18 03:38:45.000000000 -0500
12993 @@ -425,9 +425,13 @@ static u32 store_HRT (void __iomem *rom_
12994  
12995  void compaq_nvram_init (void __iomem *rom_start)
12996  {
12997 +
12998 +#ifndef CONFIG_PAX_KERNEXEC
12999         if (rom_start) {
13000                 compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR);
13001         }
13002 +#endif
13003 +
13004         dbg("int15 entry  = %p\n", compaq_int15_entry_point);
13005  
13006         /* initialize our int15 lock */
13007 diff -urNp linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c
13008 --- linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c       2008-11-07 12:55:34.000000000 -0500
13009 +++ linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv.c       2008-11-18 03:38:45.000000000 -0500
13010 @@ -59,7 +59,7 @@ static struct pcie_port_service_id aer_i
13011         .port_type      = PCIE_RC_PORT,
13012         .service_type   = PCIE_PORT_SERVICE_AER,
13013         },
13014 -       { /* end: all zeroes */ }
13015 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13016  };
13017  
13018  static struct pci_error_handlers aer_error_handlers = {
13019 diff -urNp linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c
13020 --- linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c  2008-11-07 12:55:34.000000000 -0500
13021 +++ linux-2.6.27.10/drivers/pci/pcie/aer/aerdrv_core.c  2008-11-18 03:38:45.000000000 -0500
13022 @@ -663,7 +663,7 @@ static void aer_isr_one_error(struct pci
13023                 struct aer_err_source *e_src)
13024  {
13025         struct device *s_device;
13026 -       struct aer_err_info e_info = {0, 0, 0,};
13027 +       struct aer_err_info e_info = {0, 0, 0, {0, 0, 0, 0}};
13028         int i;
13029         u16 id;
13030  
13031 diff -urNp linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c
13032 --- linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c      2008-11-07 12:55:34.000000000 -0500
13033 +++ linux-2.6.27.10/drivers/pci/pcie/portdrv_pci.c      2008-11-18 03:38:45.000000000 -0500
13034 @@ -264,7 +264,7 @@ static void pcie_portdrv_err_resume(stru
13035  static const struct pci_device_id port_pci_ids[] = { {
13036         /* handle any PCI-Express port */
13037         PCI_DEVICE_CLASS(((PCI_CLASS_BRIDGE_PCI << 8) | 0x00), ~0),
13038 -       }, { /* end: all zeroes */ }
13039 +       }, { 0, 0, 0, 0, 0, 0, 0 }
13040  };
13041  MODULE_DEVICE_TABLE(pci, port_pci_ids);
13042  
13043 diff -urNp linux-2.6.27.10/drivers/pci/proc.c linux-2.6.27.10/drivers/pci/proc.c
13044 --- linux-2.6.27.10/drivers/pci/proc.c  2008-11-07 12:55:34.000000000 -0500
13045 +++ linux-2.6.27.10/drivers/pci/proc.c  2008-11-18 03:38:45.000000000 -0500
13046 @@ -470,7 +470,16 @@ static const struct file_operations proc
13047  static int __init pci_proc_init(void)
13048  {
13049         struct pci_dev *dev = NULL;
13050 +
13051 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
13052 +#ifdef CONFIG_GRKERNSEC_PROC_USER
13053 +       proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR, NULL);
13054 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
13055 +       proc_bus_pci_dir = proc_mkdir_mode("bus/pci", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
13056 +#endif
13057 +#else
13058         proc_bus_pci_dir = proc_mkdir("bus/pci", NULL);
13059 +#endif
13060         proc_create("devices", 0, proc_bus_pci_dir,
13061                     &proc_bus_pci_dev_operations);
13062         proc_initialized = 1;
13063 diff -urNp linux-2.6.27.10/drivers/pcmcia/ti113x.h linux-2.6.27.10/drivers/pcmcia/ti113x.h
13064 --- linux-2.6.27.10/drivers/pcmcia/ti113x.h     2008-11-07 12:55:34.000000000 -0500
13065 +++ linux-2.6.27.10/drivers/pcmcia/ti113x.h     2008-11-18 03:38:45.000000000 -0500
13066 @@ -897,7 +897,7 @@ static struct pci_device_id ene_tune_tbl
13067         DEVID(PCI_VENDOR_ID_MOTOROLA, 0x3410, 0xECC0, PCI_ANY_ID,
13068                 ENE_TEST_C9_TLTENABLE | ENE_TEST_C9_PFENABLE, ENE_TEST_C9_TLTENABLE),
13069  
13070 -       {}
13071 +       { 0, 0, 0, 0, 0, 0, 0 }
13072  };
13073  
13074  static void ene_tune_bridge(struct pcmcia_socket *sock, struct pci_bus *bus)
13075 diff -urNp linux-2.6.27.10/drivers/pcmcia/yenta_socket.c linux-2.6.27.10/drivers/pcmcia/yenta_socket.c
13076 --- linux-2.6.27.10/drivers/pcmcia/yenta_socket.c       2008-11-07 12:55:34.000000000 -0500
13077 +++ linux-2.6.27.10/drivers/pcmcia/yenta_socket.c       2008-11-18 03:38:45.000000000 -0500
13078 @@ -1358,7 +1358,7 @@ static struct pci_device_id yenta_table 
13079  
13080         /* match any cardbus bridge */
13081         CB_ID(PCI_ANY_ID, PCI_ANY_ID, DEFAULT),
13082 -       { /* all zeroes */ }
13083 +       { 0, 0, 0, 0, 0, 0, 0 }
13084  };
13085  MODULE_DEVICE_TABLE(pci, yenta_table);
13086  
13087 diff -urNp linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c
13088 --- linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c     2008-11-07 12:55:34.000000000 -0500
13089 +++ linux-2.6.27.10/drivers/pnp/pnpbios/bioscalls.c     2008-11-18 03:38:45.000000000 -0500
13090 @@ -60,7 +60,7 @@ set_base(gdt[(selname) >> 3], (u32)(addr
13091  set_limit(gdt[(selname) >> 3], size); \
13092  } while(0)
13093  
13094 -static struct desc_struct bad_bios_desc;
13095 +static struct desc_struct bad_bios_desc __read_only;
13096  
13097  /*
13098   * At some point we want to use this stack frame pointer to unwind
13099 @@ -87,6 +87,10 @@ static inline u16 call_pnp_bios(u16 func
13100         struct desc_struct save_desc_40;
13101         int cpu;
13102  
13103 +#ifdef CONFIG_PAX_KERNEXEC
13104 +       unsigned long cr0;
13105 +#endif
13106 +
13107         /*
13108          * PnP BIOSes are generally not terribly re-entrant.
13109          * Also, don't rely on them to save everything correctly.
13110 @@ -96,8 +100,17 @@ static inline u16 call_pnp_bios(u16 func
13111  
13112         cpu = get_cpu();
13113         save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
13114 +
13115 +#ifdef CONFIG_PAX_KERNEXEC
13116 +       pax_open_kernel(cr0);
13117 +#endif
13118 +
13119         get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc;
13120  
13121 +#ifdef CONFIG_PAX_KERNEXEC
13122 +       pax_close_kernel(cr0);
13123 +#endif
13124 +
13125         /* On some boxes IRQ's during PnP BIOS calls are deadly.  */
13126         spin_lock_irqsave(&pnp_bios_lock, flags);
13127  
13128 @@ -134,7 +147,16 @@ static inline u16 call_pnp_bios(u16 func
13129                              :"memory");
13130         spin_unlock_irqrestore(&pnp_bios_lock, flags);
13131  
13132 +#ifdef CONFIG_PAX_KERNEXEC
13133 +       pax_open_kernel(cr0);
13134 +#endif
13135 +
13136         get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
13137 +
13138 +#ifdef CONFIG_PAX_KERNEXEC
13139 +       pax_close_kernel(cr0);
13140 +#endif
13141 +
13142         put_cpu();
13143  
13144         /* If we get here and this is set then the PnP BIOS faulted on us. */
13145 @@ -468,16 +490,24 @@ int pnp_bios_read_escd(char *data, u32 n
13146         return status;
13147  }
13148  
13149 -void pnpbios_calls_init(union pnp_bios_install_struct *header)
13150 +void __init pnpbios_calls_init(union pnp_bios_install_struct *header)
13151  {
13152         int i;
13153  
13154 +#ifdef CONFIG_PAX_KERNEXEC
13155 +       unsigned long cr0;
13156 +#endif
13157 +
13158         spin_lock_init(&pnp_bios_lock);
13159         pnp_bios_callpoint.offset = header->fields.pm16offset;
13160         pnp_bios_callpoint.segment = PNP_CS16;
13161  
13162 +#ifdef CONFIG_PAX_KERNEXEC
13163 +       pax_open_kernel(cr0);
13164 +#endif
13165 +
13166         bad_bios_desc.a = 0;
13167 -       bad_bios_desc.b = 0x00409200;
13168 +       bad_bios_desc.b = 0x00409300;
13169  
13170         set_base(bad_bios_desc, __va((unsigned long)0x40 << 4));
13171         _set_limit((char *)&bad_bios_desc, 4095 - (0x40 << 4));
13172 @@ -491,4 +521,9 @@ void pnpbios_calls_init(union pnp_bios_i
13173                 set_base(gdt[GDT_ENTRY_PNPBIOS_DS],
13174                          __va(header->fields.pm16dseg));
13175         }
13176 +
13177 +#ifdef CONFIG_PAX_KERNEXEC
13178 +       pax_close_kernel(cr0);
13179 +#endif
13180 +
13181  }
13182 diff -urNp linux-2.6.27.10/drivers/pnp/quirks.c linux-2.6.27.10/drivers/pnp/quirks.c
13183 --- linux-2.6.27.10/drivers/pnp/quirks.c        2008-12-21 01:16:51.000000000 -0500
13184 +++ linux-2.6.27.10/drivers/pnp/quirks.c        2008-12-21 01:13:46.000000000 -0500
13185 @@ -327,7 +327,7 @@ static struct pnp_fixup pnp_fixups[] = {
13186         /* PnP resources that might overlap PCI BARs */
13187         {"PNP0c01", quirk_system_pci_resources},
13188         {"PNP0c02", quirk_system_pci_resources},
13189 -       {""}
13190 +       {"", NULL}
13191  };
13192  
13193  void pnp_fixup_device(struct pnp_dev *dev)
13194 diff -urNp linux-2.6.27.10/drivers/pnp/resource.c linux-2.6.27.10/drivers/pnp/resource.c
13195 --- linux-2.6.27.10/drivers/pnp/resource.c      2008-12-21 01:16:51.000000000 -0500
13196 +++ linux-2.6.27.10/drivers/pnp/resource.c      2008-12-21 01:13:46.000000000 -0500
13197 @@ -355,7 +355,7 @@ int pnp_check_irq(struct pnp_dev *dev, s
13198                 return 1;
13199  
13200         /* check if the resource is valid */
13201 -       if (*irq < 0 || *irq > 15)
13202 +       if (*irq > 15)
13203                 return 0;
13204  
13205         /* check if the resource is reserved */
13206 @@ -419,7 +419,7 @@ int pnp_check_dma(struct pnp_dev *dev, s
13207                 return 1;
13208  
13209         /* check if the resource is valid */
13210 -       if (*dma < 0 || *dma == 4 || *dma > 7)
13211 +       if (*dma == 4 || *dma > 7)
13212                 return 0;
13213  
13214         /* check if the resource is reserved */
13215 diff -urNp linux-2.6.27.10/drivers/scsi/scsi_logging.h linux-2.6.27.10/drivers/scsi/scsi_logging.h
13216 --- linux-2.6.27.10/drivers/scsi/scsi_logging.h 2008-11-07 12:55:34.000000000 -0500
13217 +++ linux-2.6.27.10/drivers/scsi/scsi_logging.h 2008-11-18 03:38:45.000000000 -0500
13218 @@ -51,7 +51,7 @@ do {                                                          \
13219                 } while (0);                                    \
13220  } while (0)
13221  #else
13222 -#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD)
13223 +#define SCSI_CHECK_LOGGING(SHIFT, BITS, LEVEL, CMD) do {} while (0)
13224  #endif /* CONFIG_SCSI_LOGGING */
13225  
13226  /*
13227 diff -urNp linux-2.6.27.10/drivers/serial/8250_pci.c linux-2.6.27.10/drivers/serial/8250_pci.c
13228 --- linux-2.6.27.10/drivers/serial/8250_pci.c   2008-11-07 12:55:34.000000000 -0500
13229 +++ linux-2.6.27.10/drivers/serial/8250_pci.c   2008-11-18 03:38:45.000000000 -0500
13230 @@ -2859,7 +2859,7 @@ static struct pci_device_id serial_pci_t
13231                 PCI_ANY_ID, PCI_ANY_ID,
13232                 PCI_CLASS_COMMUNICATION_MULTISERIAL << 8,
13233                 0xffff00, pbn_default },
13234 -       { 0, }
13235 +       { 0, 0, 0, 0, 0, 0, 0 }
13236  };
13237  
13238  static struct pci_driver serial_pci_driver = {
13239 diff -urNp linux-2.6.27.10/drivers/usb/class/cdc-acm.c linux-2.6.27.10/drivers/usb/class/cdc-acm.c
13240 --- linux-2.6.27.10/drivers/usb/class/cdc-acm.c 2008-11-18 11:38:40.000000000 -0500
13241 +++ linux-2.6.27.10/drivers/usb/class/cdc-acm.c 2008-11-18 11:40:52.000000000 -0500
13242 @@ -1381,7 +1381,7 @@ static struct usb_device_id acm_ids[] = 
13243                 USB_CDC_ACM_PROTO_AT_CDMA) },
13244  
13245         /* NOTE:  COMM/ACM/0xff is likely MSFT RNDIS ... NOT a modem!! */
13246 -       { }
13247 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13248  };
13249  
13250  MODULE_DEVICE_TABLE (usb, acm_ids);
13251 diff -urNp linux-2.6.27.10/drivers/usb/class/usblp.c linux-2.6.27.10/drivers/usb/class/usblp.c
13252 --- linux-2.6.27.10/drivers/usb/class/usblp.c   2008-11-07 12:55:34.000000000 -0500
13253 +++ linux-2.6.27.10/drivers/usb/class/usblp.c   2008-11-18 03:38:45.000000000 -0500
13254 @@ -227,7 +227,7 @@ static const struct quirk_printer_struct
13255         { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */
13256         { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */
13257         { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */
13258 -       { 0, 0 }
13259 +       { 0, 0, 0 }
13260  };
13261  
13262  static int usblp_wwait(struct usblp *usblp, int nonblock);
13263 @@ -1401,7 +1401,7 @@ static struct usb_device_id usblp_ids []
13264         { USB_INTERFACE_INFO(7, 1, 2) },
13265         { USB_INTERFACE_INFO(7, 1, 3) },
13266         { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */
13267 -       { }                                             /* Terminating entry */
13268 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }          /* Terminating entry */
13269  };
13270  
13271  MODULE_DEVICE_TABLE (usb, usblp_ids);
13272 diff -urNp linux-2.6.27.10/drivers/usb/core/hub.c linux-2.6.27.10/drivers/usb/core/hub.c
13273 --- linux-2.6.27.10/drivers/usb/core/hub.c      2008-11-07 12:55:34.000000000 -0500
13274 +++ linux-2.6.27.10/drivers/usb/core/hub.c      2008-11-18 03:38:45.000000000 -0500
13275 @@ -3111,7 +3111,7 @@ static struct usb_device_id hub_id_table
13276        .bDeviceClass = USB_CLASS_HUB},
13277      { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
13278        .bInterfaceClass = USB_CLASS_HUB},
13279 -    { }                                                /* Terminating entry */
13280 +    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }                                             /* Terminating entry */
13281  };
13282  
13283  MODULE_DEVICE_TABLE (usb, hub_id_table);
13284 diff -urNp linux-2.6.27.10/drivers/usb/host/ehci-pci.c linux-2.6.27.10/drivers/usb/host/ehci-pci.c
13285 --- linux-2.6.27.10/drivers/usb/host/ehci-pci.c 2008-12-10 22:35:37.000000000 -0500
13286 +++ linux-2.6.27.10/drivers/usb/host/ehci-pci.c 2008-12-10 22:35:46.000000000 -0500
13287 @@ -414,7 +414,7 @@ static const struct pci_device_id pci_id
13288         PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0),
13289         .driver_data =  (unsigned long) &ehci_pci_hc_driver,
13290         },
13291 -       { /* end: all zeroes */ }
13292 +       { 0, 0, 0, 0, 0, 0, 0 }
13293  };
13294  MODULE_DEVICE_TABLE(pci, pci_ids);
13295  
13296 diff -urNp linux-2.6.27.10/drivers/usb/host/uhci-hcd.c linux-2.6.27.10/drivers/usb/host/uhci-hcd.c
13297 --- linux-2.6.27.10/drivers/usb/host/uhci-hcd.c 2008-11-07 12:55:34.000000000 -0500
13298 +++ linux-2.6.27.10/drivers/usb/host/uhci-hcd.c 2008-11-18 03:38:45.000000000 -0500
13299 @@ -928,7 +928,7 @@ static const struct pci_device_id uhci_p
13300         /* handle any USB UHCI controller */
13301         PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_UHCI, ~0),
13302         .driver_data =  (unsigned long) &uhci_driver,
13303 -       }, { /* end: all zeroes */ }
13304 +       }, { 0, 0, 0, 0, 0, 0, 0 }
13305  };
13306  
13307  MODULE_DEVICE_TABLE(pci, uhci_pci_ids);
13308 diff -urNp linux-2.6.27.10/drivers/usb/storage/debug.h linux-2.6.27.10/drivers/usb/storage/debug.h
13309 --- linux-2.6.27.10/drivers/usb/storage/debug.h 2008-11-07 12:55:34.000000000 -0500
13310 +++ linux-2.6.27.10/drivers/usb/storage/debug.h 2008-11-18 03:38:45.000000000 -0500
13311 @@ -54,9 +54,9 @@ void usb_stor_show_sense( unsigned char 
13312  #define US_DEBUGPX(x...) printk( x )
13313  #define US_DEBUG(x) x 
13314  #else
13315 -#define US_DEBUGP(x...)
13316 -#define US_DEBUGPX(x...)
13317 -#define US_DEBUG(x)
13318 +#define US_DEBUGP(x...) do {} while (0)
13319 +#define US_DEBUGPX(x...) do {} while (0)
13320 +#define US_DEBUG(x) do {} while (0)
13321  #endif
13322  
13323  #endif
13324 diff -urNp linux-2.6.27.10/drivers/usb/storage/usb.c linux-2.6.27.10/drivers/usb/storage/usb.c
13325 --- linux-2.6.27.10/drivers/usb/storage/usb.c   2008-11-07 12:55:34.000000000 -0500
13326 +++ linux-2.6.27.10/drivers/usb/storage/usb.c   2008-11-18 03:38:45.000000000 -0500
13327 @@ -136,7 +136,7 @@ static struct usb_device_id storage_usb_
13328  #undef UNUSUAL_DEV
13329  #undef USUAL_DEV
13330         /* Terminating entry */
13331 -       { }
13332 +       { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
13333  };
13334  
13335  MODULE_DEVICE_TABLE (usb, storage_usb_ids);
13336 @@ -176,7 +176,7 @@ static struct us_unusual_dev us_unusual_
13337  #      undef USUAL_DEV
13338  
13339         /* Terminating entry */
13340 -       { NULL }
13341 +       { NULL, NULL, 0, 0, NULL }
13342  };
13343  
13344  
13345 diff -urNp linux-2.6.27.10/drivers/video/fbcmap.c linux-2.6.27.10/drivers/video/fbcmap.c
13346 --- linux-2.6.27.10/drivers/video/fbcmap.c      2008-11-07 12:55:34.000000000 -0500
13347 +++ linux-2.6.27.10/drivers/video/fbcmap.c      2008-11-18 03:38:45.000000000 -0500
13348 @@ -250,8 +250,7 @@ int fb_set_user_cmap(struct fb_cmap_user
13349         int rc, size = cmap->len * sizeof(u16);
13350         struct fb_cmap umap;
13351  
13352 -       if (cmap->start < 0 || (!info->fbops->fb_setcolreg &&
13353 -                               !info->fbops->fb_setcmap))
13354 +       if (!info->fbops->fb_setcolreg && !info->fbops->fb_setcmap)
13355                 return -EINVAL;
13356  
13357         memset(&umap, 0, sizeof(struct fb_cmap));
13358 diff -urNp linux-2.6.27.10/drivers/video/fbmem.c linux-2.6.27.10/drivers/video/fbmem.c
13359 --- linux-2.6.27.10/drivers/video/fbmem.c       2008-12-10 22:35:37.000000000 -0500
13360 +++ linux-2.6.27.10/drivers/video/fbmem.c       2008-12-10 22:35:46.000000000 -0500
13361 @@ -395,7 +395,7 @@ static void fb_do_show_logo(struct fb_in
13362                         image->dx += image->width + 8;
13363                 }
13364         } else if (rotate == FB_ROTATE_UD) {
13365 -               for (x = 0; x < num && image->dx >= 0; x++) {
13366 +               for (x = 0; x < num && (__s32)image->dx >= 0; x++) {
13367                         info->fbops->fb_imageblit(info, image);
13368                         image->dx -= image->width + 8;
13369                 }
13370 @@ -407,7 +407,7 @@ static void fb_do_show_logo(struct fb_in
13371                         image->dy += image->height + 8;
13372                 }
13373         } else if (rotate == FB_ROTATE_CCW) {
13374 -               for (x = 0; x < num && image->dy >= 0; x++) {
13375 +               for (x = 0; x < num && (__s32)image->dy >= 0; x++) {
13376                         info->fbops->fb_imageblit(info, image);
13377                         image->dy -= image->height + 8;
13378                 }
13379 @@ -1083,7 +1083,7 @@ fb_ioctl(struct inode *inode, struct fil
13380                         return - EFAULT;
13381                 if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)
13382                     return -EINVAL;
13383 -               if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX)
13384 +               if (con2fb.framebuffer >= FB_MAX)
13385                     return -EINVAL;
13386  #ifdef CONFIG_KMOD
13387                 if (!registered_fb[con2fb.framebuffer])
13388 diff -urNp linux-2.6.27.10/drivers/video/fbmon.c linux-2.6.27.10/drivers/video/fbmon.c
13389 --- linux-2.6.27.10/drivers/video/fbmon.c       2008-11-07 12:55:34.000000000 -0500
13390 +++ linux-2.6.27.10/drivers/video/fbmon.c       2008-11-18 03:38:45.000000000 -0500
13391 @@ -45,7 +45,7 @@
13392  #ifdef DEBUG
13393  #define DPRINTK(fmt, args...) printk(fmt,## args)
13394  #else
13395 -#define DPRINTK(fmt, args...)
13396 +#define DPRINTK(fmt, args...) do {} while (0)
13397  #endif
13398  
13399  #define FBMON_FIX_HEADER  1
13400 diff -urNp linux-2.6.27.10/drivers/video/i810/i810_accel.c linux-2.6.27.10/drivers/video/i810/i810_accel.c
13401 --- linux-2.6.27.10/drivers/video/i810/i810_accel.c     2008-11-07 12:55:34.000000000 -0500
13402 +++ linux-2.6.27.10/drivers/video/i810/i810_accel.c     2008-11-18 03:38:45.000000000 -0500
13403 @@ -73,6 +73,7 @@ static inline int wait_for_space(struct 
13404                 }
13405         }
13406         printk("ringbuffer lockup!!!\n");
13407 +       printk("head:%u tail:%u iring.size:%u space:%u\n", head, tail, par->iring.size, space);
13408         i810_report_error(mmio); 
13409         par->dev_flags |= LOCKUP;
13410         info->pixmap.scan_align = 1;
13411 diff -urNp linux-2.6.27.10/drivers/video/i810/i810_main.c linux-2.6.27.10/drivers/video/i810/i810_main.c
13412 --- linux-2.6.27.10/drivers/video/i810/i810_main.c      2008-11-07 12:55:34.000000000 -0500
13413 +++ linux-2.6.27.10/drivers/video/i810/i810_main.c      2008-11-18 03:38:45.000000000 -0500
13414 @@ -120,7 +120,7 @@ static struct pci_device_id i810fb_pci_t
13415           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
13416         { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC,
13417           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
13418 -       { 0 },
13419 +       { 0, 0, 0, 0, 0, 0, 0 },
13420  };
13421  
13422  static struct pci_driver i810fb_driver = {
13423 @@ -1509,7 +1509,7 @@ static int i810fb_cursor(struct fb_info 
13424                 int size = ((cursor->image.width + 7) >> 3) *
13425                         cursor->image.height;
13426                 int i;
13427 -               u8 *data = kmalloc(64 * 8, GFP_ATOMIC);
13428 +               u8 *data = kmalloc(64 * 8, GFP_KERNEL);
13429  
13430                 if (data == NULL)
13431                         return -ENOMEM;
13432 diff -urNp linux-2.6.27.10/drivers/video/modedb.c linux-2.6.27.10/drivers/video/modedb.c
13433 --- linux-2.6.27.10/drivers/video/modedb.c      2008-11-07 12:55:34.000000000 -0500
13434 +++ linux-2.6.27.10/drivers/video/modedb.c      2008-11-18 03:38:45.000000000 -0500
13435 @@ -38,232 +38,232 @@ static const struct fb_videomode modedb[
13436      {
13437         /* 640x400 @ 70 Hz, 31.5 kHz hsync */
13438         NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
13439 -       0, FB_VMODE_NONINTERLACED
13440 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13441      }, {
13442         /* 640x480 @ 60 Hz, 31.5 kHz hsync */
13443         NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
13444 -       0, FB_VMODE_NONINTERLACED
13445 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13446      }, {
13447         /* 800x600 @ 56 Hz, 35.15 kHz hsync */
13448         NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
13449 -       0, FB_VMODE_NONINTERLACED
13450 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13451      }, {
13452         /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
13453         NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
13454 -       0, FB_VMODE_INTERLACED
13455 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13456      }, {
13457         /* 640x400 @ 85 Hz, 37.86 kHz hsync */
13458         NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
13459 -       FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13460 +       FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13461      }, {
13462         /* 640x480 @ 72 Hz, 36.5 kHz hsync */
13463         NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
13464 -       0, FB_VMODE_NONINTERLACED
13465 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13466      }, {
13467         /* 640x480 @ 75 Hz, 37.50 kHz hsync */
13468         NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
13469 -       0, FB_VMODE_NONINTERLACED
13470 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13471      }, {
13472         /* 800x600 @ 60 Hz, 37.8 kHz hsync */
13473         NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
13474 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13475 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13476      }, {
13477         /* 640x480 @ 85 Hz, 43.27 kHz hsync */
13478         NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
13479 -       0, FB_VMODE_NONINTERLACED
13480 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13481      }, {
13482         /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
13483         NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
13484 -       0, FB_VMODE_INTERLACED
13485 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13486      }, {
13487         /* 800x600 @ 72 Hz, 48.0 kHz hsync */
13488         NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
13489 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13490 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13491      }, {
13492         /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
13493         NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
13494 -       0, FB_VMODE_NONINTERLACED
13495 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13496      }, {
13497         /* 640x480 @ 100 Hz, 53.01 kHz hsync */
13498         NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
13499 -       0, FB_VMODE_NONINTERLACED
13500 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13501      }, {
13502         /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
13503         NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
13504 -       0, FB_VMODE_NONINTERLACED
13505 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13506      }, {
13507         /* 800x600 @ 85 Hz, 55.84 kHz hsync */
13508         NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
13509 -       0, FB_VMODE_NONINTERLACED
13510 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13511      }, {
13512         /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
13513         NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
13514 -       0, FB_VMODE_NONINTERLACED
13515 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13516      }, {
13517         /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
13518         NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
13519 -       0, FB_VMODE_INTERLACED
13520 +       0, FB_VMODE_INTERLACED, FB_MODE_IS_UNKNOWN
13521      }, {
13522         /* 800x600 @ 100 Hz, 64.02 kHz hsync */
13523         NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
13524 -       0, FB_VMODE_NONINTERLACED
13525 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13526      }, {
13527         /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
13528         NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
13529 -       0, FB_VMODE_NONINTERLACED
13530 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13531      }, {
13532         /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
13533         NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
13534 -       0, FB_VMODE_NONINTERLACED
13535 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13536      }, {
13537         /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
13538         NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
13539 -       0, FB_VMODE_NONINTERLACED
13540 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13541      }, {
13542         /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
13543         NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
13544 -       0, FB_VMODE_NONINTERLACED       
13545 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13546      }, {
13547         /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
13548         NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
13549 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13550 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13551      }, {
13552         /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
13553          NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
13554 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13555 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13556      }, {
13557         /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
13558         NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
13559 -       0, FB_VMODE_NONINTERLACED
13560 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13561      }, {
13562         /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
13563         NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
13564 -       0, FB_VMODE_NONINTERLACED
13565 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13566      }, {
13567         /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
13568         NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
13569 -       0, FB_VMODE_NONINTERLACED
13570 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13571      }, {
13572         /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
13573         NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
13574 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13575 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13576      }, {
13577         /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
13578         NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
13579 -       0, FB_VMODE_NONINTERLACED
13580 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13581      }, {
13582         /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
13583         NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
13584 -       0, FB_VMODE_NONINTERLACED
13585 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13586      }, {
13587         /* 1024x768 @ 100Hz, 80.21 kHz hsync */
13588         NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
13589 -       0, FB_VMODE_NONINTERLACED
13590 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13591      }, {
13592         /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
13593         NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
13594 -       0, FB_VMODE_NONINTERLACED
13595 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13596      }, {
13597         /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
13598         NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
13599 -       0, FB_VMODE_NONINTERLACED
13600 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13601      }, {
13602         /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
13603         NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
13604 -       0, FB_VMODE_NONINTERLACED
13605 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13606      }, {
13607         /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
13608         NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
13609 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13610 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13611      }, {
13612         /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
13613         NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
13614 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13615 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13616      }, {
13617         /* 1680x1050 @ 60 Hz, 65.191 kHz hsync */
13618         NULL, 60, 1680, 1050, 6848, 280, 104, 30, 3, 176, 6,
13619 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13620 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13621      }, {
13622         /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
13623         NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
13624 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13625 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13626      }, {
13627         /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
13628         NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
13629 -       0, FB_VMODE_NONINTERLACED
13630 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13631      }, {
13632         /* 1800x1440 @ 64Hz, 96.15 kHz hsync  */
13633         NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
13634 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13635 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13636      }, {
13637         /* 1800x1440 @ 70Hz, 104.52 kHz hsync  */
13638         NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
13639 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13640 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13641      }, {
13642         /* 512x384 @ 78 Hz, 31.50 kHz hsync */
13643         NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
13644 -       0, FB_VMODE_NONINTERLACED
13645 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13646      }, {
13647         /* 512x384 @ 85 Hz, 34.38 kHz hsync */
13648         NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
13649 -       0, FB_VMODE_NONINTERLACED
13650 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13651      }, {
13652         /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
13653         NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
13654 -       0, FB_VMODE_DOUBLE
13655 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13656      }, {
13657         /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
13658         NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
13659 -       0, FB_VMODE_DOUBLE
13660 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13661      }, {
13662         /* 320x240 @ 72 Hz, 36.5 kHz hsync */
13663         NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
13664 -       0, FB_VMODE_DOUBLE
13665 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13666      }, {
13667         /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
13668         NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
13669 -       0, FB_VMODE_DOUBLE
13670 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13671      }, {
13672         /* 400x300 @ 60 Hz, 37.8 kHz hsync */
13673         NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
13674 -       0, FB_VMODE_DOUBLE
13675 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13676      }, {
13677         /* 400x300 @ 72 Hz, 48.0 kHz hsync */
13678         NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
13679 -       0, FB_VMODE_DOUBLE
13680 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13681      }, {
13682         /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
13683         NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
13684 -       0, FB_VMODE_DOUBLE
13685 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13686      }, {
13687         /* 480x300 @ 60 Hz, 37.8 kHz hsync */
13688         NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
13689 -       0, FB_VMODE_DOUBLE
13690 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13691      }, {
13692         /* 480x300 @ 63 Hz, 39.6 kHz hsync */
13693         NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
13694 -       0, FB_VMODE_DOUBLE
13695 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13696      }, {
13697         /* 480x300 @ 72 Hz, 48.0 kHz hsync */
13698         NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
13699 -       0, FB_VMODE_DOUBLE
13700 +       0, FB_VMODE_DOUBLE, FB_MODE_IS_UNKNOWN
13701      }, {
13702         /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */
13703         NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3,
13704         FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
13705 -       FB_VMODE_NONINTERLACED
13706 +       FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13707      }, {
13708         /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
13709         NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
13710 -       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
13711 +       FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13712      }, {
13713         /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
13714         NULL, 60, 1366, 768, 13806, 120, 10, 14, 3, 32, 5,
13715 -       0, FB_VMODE_NONINTERLACED
13716 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13717     }, {
13718         /* 1280x800, 60 Hz, 47.403 kHz hsync, WXGA 16:10 aspect ratio */
13719         NULL, 60, 1280, 800, 12048, 200, 64, 24, 1, 136, 3,
13720 -       0, FB_VMODE_NONINTERLACED
13721 +       0, FB_VMODE_NONINTERLACED, FB_MODE_IS_UNKNOWN
13722      },
13723  };
13724  
13725 diff -urNp linux-2.6.27.10/drivers/video/uvesafb.c linux-2.6.27.10/drivers/video/uvesafb.c
13726 --- linux-2.6.27.10/drivers/video/uvesafb.c     2008-11-07 12:55:34.000000000 -0500
13727 +++ linux-2.6.27.10/drivers/video/uvesafb.c     2008-11-18 03:38:45.000000000 -0500
13728 @@ -18,6 +18,7 @@
13729  #include <linux/fb.h>
13730  #include <linux/io.h>
13731  #include <linux/mutex.h>
13732 +#include <linux/moduleloader.h>
13733  #include <video/edid.h>
13734  #include <video/uvesafb.h>
13735  #ifdef CONFIG_X86
13736 @@ -117,7 +118,7 @@ static int uvesafb_helper_start(void)
13737                 NULL,
13738         };
13739  
13740 -       return call_usermodehelper(v86d_path, argv, envp, 1);
13741 +       return call_usermodehelper(v86d_path, argv, envp, UMH_WAIT_PROC);
13742  }
13743  
13744  /*
13745 @@ -569,10 +570,34 @@ static int __devinit uvesafb_vbe_getpmi(
13746         if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
13747                 par->pmi_setpal = par->ypan = 0;
13748         } else {
13749 +
13750 +#ifdef CONFIG_PAX_KERNEXEC
13751 +#ifdef CONFIG_MODULES
13752 +               unsigned long cr0;
13753 +
13754 +               par->pmi_code = module_alloc_exec((u16)task->t.regs.ecx);
13755 +#endif
13756 +               if (!par->pmi_code) {
13757 +                       par->pmi_setpal = par->ypan = 0;
13758 +                       return 0;
13759 +               }
13760 +#endif
13761 +
13762                 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
13763                                                 + task->t.regs.edi);
13764 +
13765 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13766 +               pax_open_kernel(cr0);
13767 +               memcpy(par->pmi_code, par->pmi_base, (u16)task->t.regs.ecx);
13768 +               pax_close_kernel(cr0);
13769 +
13770 +               par->pmi_start = ktva_ktla(par->pmi_code + par->pmi_base[1]);
13771 +               par->pmi_pal = ktva_ktla(par->pmi_code + par->pmi_base[2]);
13772 +#else
13773                 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
13774                 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
13775 +#endif
13776 +
13777                 printk(KERN_INFO "uvesafb: protected mode interface info at "
13778                                  "%04x:%04x\n",
13779                                  (u16)task->t.regs.es, (u16)task->t.regs.edi);
13780 @@ -1827,6 +1852,11 @@ out:
13781         if (par->vbe_modes)
13782                 kfree(par->vbe_modes);
13783  
13784 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13785 +       if (par->pmi_code)
13786 +               module_free_exec(NULL, par->pmi_code);
13787 +#endif
13788 +
13789         framebuffer_release(info);
13790         return err;
13791  }
13792 @@ -1853,6 +1883,12 @@ static int uvesafb_remove(struct platfor
13793                                 kfree(par->vbe_state_orig);
13794                         if (par->vbe_state_saved)
13795                                 kfree(par->vbe_state_saved);
13796 +
13797 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13798 +                       if (par->pmi_code)
13799 +                               module_free_exec(NULL, par->pmi_code);
13800 +#endif
13801 +
13802                 }
13803  
13804                 framebuffer_release(info);
13805 diff -urNp linux-2.6.27.10/drivers/video/vesafb.c linux-2.6.27.10/drivers/video/vesafb.c
13806 --- linux-2.6.27.10/drivers/video/vesafb.c      2008-11-07 12:55:34.000000000 -0500
13807 +++ linux-2.6.27.10/drivers/video/vesafb.c      2008-11-18 03:38:45.000000000 -0500
13808 @@ -9,6 +9,7 @@
13809   */
13810  
13811  #include <linux/module.h>
13812 +#include <linux/moduleloader.h>
13813  #include <linux/kernel.h>
13814  #include <linux/errno.h>
13815  #include <linux/string.h>
13816 @@ -53,8 +54,8 @@ static int   vram_remap __initdata;           /* 
13817  static int   vram_total __initdata;            /* Set total amount of memory */
13818  static int   pmi_setpal __read_mostly = 1;     /* pmi for palette changes ??? */
13819  static int   ypan       __read_mostly;         /* 0..nothing, 1..ypan, 2..ywrap */
13820 -static void  (*pmi_start)(void) __read_mostly;
13821 -static void  (*pmi_pal)  (void) __read_mostly;
13822 +static void  (*pmi_start)(void) __read_only;
13823 +static void  (*pmi_pal)  (void) __read_only;
13824  static int   depth      __read_mostly;
13825  static int   vga_compat __read_mostly;
13826  /* --------------------------------------------------------------------- */
13827 @@ -224,6 +225,7 @@ static int __init vesafb_probe(struct pl
13828         unsigned int size_vmode;
13829         unsigned int size_remap;
13830         unsigned int size_total;
13831 +       void *pmi_code = NULL;
13832  
13833         if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
13834                 return -ENODEV;
13835 @@ -266,10 +268,6 @@ static int __init vesafb_probe(struct pl
13836                 size_remap = size_total;
13837         vesafb_fix.smem_len = size_remap;
13838  
13839 -#ifndef __i386__
13840 -       screen_info.vesapm_seg = 0;
13841 -#endif
13842 -
13843         if (!request_mem_region(vesafb_fix.smem_start, size_total, "vesafb")) {
13844                 printk(KERN_WARNING
13845                        "vesafb: cannot reserve video memory at 0x%lx\n",
13846 @@ -302,9 +300,21 @@ static int __init vesafb_probe(struct pl
13847         printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
13848                vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel, vesafb_fix.line_length, screen_info.pages);
13849  
13850 +#ifdef __i386__
13851 +
13852 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13853 +       pmi_code = module_alloc_exec(screen_info.vesapm_size);
13854 +       if (!pmi_code)
13855 +#elif !defined(CONFIG_PAX_KERNEXEC)
13856 +       if (0)
13857 +#endif
13858 +
13859 +#endif
13860 +       screen_info.vesapm_seg = 0;
13861 +
13862         if (screen_info.vesapm_seg) {
13863 -               printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
13864 -                      screen_info.vesapm_seg,screen_info.vesapm_off);
13865 +               printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x %04x bytes\n",
13866 +                      screen_info.vesapm_seg,screen_info.vesapm_off,screen_info.vesapm_size);
13867         }
13868  
13869         if (screen_info.vesapm_seg < 0xc000)
13870 @@ -312,9 +322,29 @@ static int __init vesafb_probe(struct pl
13871  
13872         if (ypan || pmi_setpal) {
13873                 unsigned short *pmi_base;
13874 -               pmi_base  = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13875 -               pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
13876 -               pmi_pal   = (void*)((char*)pmi_base + pmi_base[2]);
13877 +
13878 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13879 +               unsigned long cr0;
13880 +#endif
13881 +
13882 +               pmi_base = (unsigned short*)phys_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
13883 +
13884 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13885 +               pax_open_kernel(cr0);
13886 +               memcpy(pmi_code, pmi_base, screen_info.vesapm_size);
13887 +#else
13888 +               pmi_code = pmi_base;
13889 +#endif
13890 +
13891 +               pmi_start = (void*)((char*)pmi_code + pmi_base[1]);
13892 +               pmi_pal   = (void*)((char*)pmi_code + pmi_base[2]);
13893 +
13894 +#if defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13895 +               pmi_start = ktva_ktla(pmi_start);
13896 +               pmi_pal = ktva_ktla(pmi_pal);
13897 +               pax_close_kernel(cr0);
13898 +#endif
13899 +
13900                 printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
13901                 if (pmi_base[3]) {
13902                         printk(KERN_INFO "vesafb: pmi: ports = ");
13903 @@ -456,6 +486,11 @@ static int __init vesafb_probe(struct pl
13904                info->node, info->fix.id);
13905         return 0;
13906  err:
13907 +
13908 +#if defined(__i386__) && defined(CONFIG_MODULES) && defined(CONFIG_PAX_KERNEXEC)
13909 +       module_free_exec(NULL, pmi_code);
13910 +#endif
13911 +
13912         if (info->screen_base)
13913                 iounmap(info->screen_base);
13914         framebuffer_release(info);
13915 diff -urNp linux-2.6.27.10/fs/9p/vfs_inode.c linux-2.6.27.10/fs/9p/vfs_inode.c
13916 --- linux-2.6.27.10/fs/9p/vfs_inode.c   2008-11-07 12:55:34.000000000 -0500
13917 +++ linux-2.6.27.10/fs/9p/vfs_inode.c   2008-11-18 03:38:45.000000000 -0500
13918 @@ -1021,7 +1021,7 @@ static void *v9fs_vfs_follow_link(struct
13919  static void
13920  v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
13921  {
13922 -       char *s = nd_get_link(nd);
13923 +       const char *s = nd_get_link(nd);
13924  
13925         P9_DPRINTK(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, s);
13926         if (!IS_ERR(s))
13927 diff -urNp linux-2.6.27.10/fs/aio.c linux-2.6.27.10/fs/aio.c
13928 --- linux-2.6.27.10/fs/aio.c    2008-11-07 12:55:34.000000000 -0500
13929 +++ linux-2.6.27.10/fs/aio.c    2008-11-18 03:38:45.000000000 -0500
13930 @@ -114,7 +114,7 @@ static int aio_setup_ring(struct kioctx 
13931         size += sizeof(struct io_event) * nr_events;
13932         nr_pages = (size + PAGE_SIZE-1) >> PAGE_SHIFT;
13933  
13934 -       if (nr_pages < 0)
13935 +       if (nr_pages <= 0)
13936                 return -EINVAL;
13937  
13938         nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring)) / sizeof(struct io_event);
13939 diff -urNp linux-2.6.27.10/fs/autofs4/symlink.c linux-2.6.27.10/fs/autofs4/symlink.c
13940 --- linux-2.6.27.10/fs/autofs4/symlink.c        2008-11-07 12:55:34.000000000 -0500
13941 +++ linux-2.6.27.10/fs/autofs4/symlink.c        2008-11-18 03:38:45.000000000 -0500
13942 @@ -15,7 +15,7 @@
13943  static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
13944  {
13945         struct autofs_info *ino = autofs4_dentry_ino(dentry);
13946 -       nd_set_link(nd, (char *)ino->u.symlink);
13947 +       nd_set_link(nd, ino->u.symlink);
13948         return NULL;
13949  }
13950  
13951 diff -urNp linux-2.6.27.10/fs/befs/linuxvfs.c linux-2.6.27.10/fs/befs/linuxvfs.c
13952 --- linux-2.6.27.10/fs/befs/linuxvfs.c  2008-11-07 12:55:34.000000000 -0500
13953 +++ linux-2.6.27.10/fs/befs/linuxvfs.c  2008-11-18 03:38:45.000000000 -0500
13954 @@ -490,7 +490,7 @@ static void befs_put_link(struct dentry 
13955  {
13956         befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
13957         if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
13958 -               char *link = nd_get_link(nd);
13959 +               const char *link = nd_get_link(nd);
13960                 if (!IS_ERR(link))
13961                         kfree(link);
13962         }
13963 diff -urNp linux-2.6.27.10/fs/binfmt_aout.c linux-2.6.27.10/fs/binfmt_aout.c
13964 --- linux-2.6.27.10/fs/binfmt_aout.c    2008-11-07 12:55:34.000000000 -0500
13965 +++ linux-2.6.27.10/fs/binfmt_aout.c    2008-11-18 03:38:45.000000000 -0500
13966 @@ -24,6 +24,7 @@
13967  #include <linux/personality.h>
13968  #include <linux/init.h>
13969  #include <linux/vs_memory.h>
13970 +#include <linux/grsecurity.h>
13971  
13972  #include <asm/system.h>
13973  #include <asm/uaccess.h>
13974 @@ -124,18 +125,22 @@ static int aout_core_dump(long signr, st
13975  /* If the size of the dump file exceeds the rlimit, then see what would happen
13976     if we wrote the stack, but not the data area.  */
13977  #ifdef __sparc__
13978 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize + dump.u_ssize, 1);
13979         if ((dump.u_dsize + dump.u_ssize) > limit)
13980                 dump.u_dsize = 0;
13981  #else
13982 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE, 1);
13983         if ((dump.u_dsize + dump.u_ssize+1) * PAGE_SIZE > limit)
13984                 dump.u_dsize = 0;
13985  #endif
13986  
13987  /* Make sure we have enough room to write the stack and data areas. */
13988  #ifdef __sparc__
13989 +       gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1);
13990         if (dump.u_ssize > limit)
13991                 dump.u_ssize = 0;
13992  #else
13993 +       gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize + 1) * PAGE_SIZE, 1);
13994         if ((dump.u_ssize + 1) * PAGE_SIZE > limit)
13995                 dump.u_ssize = 0;
13996  #endif
13997 @@ -291,6 +296,8 @@ static int load_aout_binary(struct linux
13998         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
13999         if (rlim >= RLIM_INFINITY)
14000                 rlim = ~0;
14001 +
14002 +       gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1);
14003         if (ex.a_data + ex.a_bss > rlim)
14004                 return -ENOMEM;
14005  
14006 @@ -322,6 +329,28 @@ static int load_aout_binary(struct linux
14007  
14008         compute_creds(bprm);
14009         current->flags &= ~PF_FORKNOEXEC;
14010 +
14011 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14012 +       current->mm->pax_flags = 0UL;
14013 +#endif
14014 +
14015 +#ifdef CONFIG_PAX_PAGEEXEC
14016 +       if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) {
14017 +               current->mm->pax_flags |= MF_PAX_PAGEEXEC;
14018 +
14019 +#ifdef CONFIG_PAX_EMUTRAMP
14020 +               if (N_FLAGS(ex) & F_PAX_EMUTRAMP)
14021 +                       current->mm->pax_flags |= MF_PAX_EMUTRAMP;
14022 +#endif
14023 +
14024 +#ifdef CONFIG_PAX_MPROTECT
14025 +               if (!(N_FLAGS(ex) & F_PAX_MPROTECT))
14026 +                       current->mm->pax_flags |= MF_PAX_MPROTECT;
14027 +#endif
14028 +
14029 +       }
14030 +#endif
14031 +
14032  #ifdef __sparc__
14033         if (N_MAGIC(ex) == NMAGIC) {
14034                 loff_t pos = fd_offset;
14035 @@ -413,7 +442,7 @@ static int load_aout_binary(struct linux
14036  
14037                 down_write(&current->mm->mmap_sem);
14038                 error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
14039 -                               PROT_READ | PROT_WRITE | PROT_EXEC,
14040 +                               PROT_READ | PROT_WRITE,
14041                                 MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
14042                                 fd_offset + ex.a_text);
14043                 up_write(&current->mm->mmap_sem);
14044 diff -urNp linux-2.6.27.10/fs/binfmt_elf.c linux-2.6.27.10/fs/binfmt_elf.c
14045 --- linux-2.6.27.10/fs/binfmt_elf.c     2008-11-07 12:55:34.000000000 -0500
14046 +++ linux-2.6.27.10/fs/binfmt_elf.c     2008-12-21 00:51:06.000000000 -0500
14047 @@ -38,10 +38,16 @@
14048  #include <linux/elf.h>
14049  #include <linux/utsname.h>
14050  #include <linux/vs_memory.h>
14051 +#include <linux/grsecurity.h>
14052 +
14053  #include <asm/uaccess.h>
14054  #include <asm/param.h>
14055  #include <asm/page.h>
14056  
14057 +#ifdef CONFIG_PAX_SEGMEXEC
14058 +#include <asm/desc.h>
14059 +#endif
14060 +
14061  static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
14062  static int load_elf_library(struct file *);
14063  static unsigned long elf_map(struct file *, unsigned long, struct elf_phdr *,
14064 @@ -57,6 +63,10 @@ static int elf_core_dump(long signr, str
14065  #define elf_core_dump  NULL
14066  #endif
14067  
14068 +#ifdef CONFIG_PAX_MPROTECT
14069 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags);
14070 +#endif
14071 +
14072  #if ELF_EXEC_PAGESIZE > PAGE_SIZE
14073  #define ELF_MIN_ALIGN  ELF_EXEC_PAGESIZE
14074  #else
14075 @@ -76,6 +86,11 @@ static struct linux_binfmt elf_format = 
14076                 .load_binary    = load_elf_binary,
14077                 .load_shlib     = load_elf_library,
14078                 .core_dump      = elf_core_dump,
14079 +
14080 +#ifdef CONFIG_PAX_MPROTECT
14081 +               .handle_mprotect= elf_handle_mprotect,
14082 +#endif
14083 +
14084                 .min_coredump   = ELF_EXEC_PAGESIZE,
14085                 .hasvdso        = 1
14086  };
14087 @@ -84,6 +99,8 @@ static struct linux_binfmt elf_format = 
14088  
14089  static int set_brk(unsigned long start, unsigned long end)
14090  {
14091 +       unsigned long e = end;
14092 +
14093         start = ELF_PAGEALIGN(start);
14094         end = ELF_PAGEALIGN(end);
14095         if (end > start) {
14096 @@ -94,7 +111,7 @@ static int set_brk(unsigned long start, 
14097                 if (BAD_ADDR(addr))
14098                         return addr;
14099         }
14100 -       current->mm->start_brk = current->mm->brk = end;
14101 +       current->mm->start_brk = current->mm->brk = e;
14102         return 0;
14103  }
14104  
14105 @@ -380,10 +397,10 @@ static unsigned long load_elf_interp(str
14106  {
14107         struct elf_phdr *elf_phdata;
14108         struct elf_phdr *eppnt;
14109 -       unsigned long load_addr = 0;
14110 +       unsigned long load_addr = 0, pax_task_size = TASK_SIZE;
14111         int load_addr_set = 0;
14112         unsigned long last_bss = 0, elf_bss = 0;
14113 -       unsigned long error = ~0UL;
14114 +       unsigned long error = -EINVAL;
14115         unsigned long total_size;
14116         int retval, i, size;
14117  
14118 @@ -429,6 +446,11 @@ static unsigned long load_elf_interp(str
14119                 goto out_close;
14120         }
14121  
14122 +#ifdef CONFIG_PAX_SEGMEXEC
14123 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
14124 +               pax_task_size = SEGMEXEC_TASK_SIZE;
14125 +#endif
14126 +
14127         eppnt = elf_phdata;
14128         for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
14129                 if (eppnt->p_type == PT_LOAD) {
14130 @@ -472,8 +494,8 @@ static unsigned long load_elf_interp(str
14131                         k = load_addr + eppnt->p_vaddr;
14132                         if (BAD_ADDR(k) ||
14133                             eppnt->p_filesz > eppnt->p_memsz ||
14134 -                           eppnt->p_memsz > TASK_SIZE ||
14135 -                           TASK_SIZE - eppnt->p_memsz < k) {
14136 +                           eppnt->p_memsz > pax_task_size ||
14137 +                           pax_task_size - eppnt->p_memsz < k) {
14138                                 error = -ENOMEM;
14139                                 goto out_close;
14140                         }
14141 @@ -527,6 +549,177 @@ out:
14142         return error;
14143  }
14144  
14145 +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE)
14146 +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata)
14147 +{
14148 +       unsigned long pax_flags = 0UL;
14149 +
14150 +#ifdef CONFIG_PAX_PAGEEXEC
14151 +       if (elf_phdata->p_flags & PF_PAGEEXEC)
14152 +               pax_flags |= MF_PAX_PAGEEXEC;
14153 +#endif
14154 +
14155 +#ifdef CONFIG_PAX_SEGMEXEC
14156 +       if (elf_phdata->p_flags & PF_SEGMEXEC)
14157 +               pax_flags |= MF_PAX_SEGMEXEC;
14158 +#endif
14159 +
14160 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14161 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14162 +               if (nx_enabled)
14163 +                       pax_flags &= ~MF_PAX_SEGMEXEC;
14164 +               else
14165 +                       pax_flags &= ~MF_PAX_PAGEEXEC;
14166 +       }
14167 +#endif
14168 +
14169 +#ifdef CONFIG_PAX_EMUTRAMP
14170 +       if (elf_phdata->p_flags & PF_EMUTRAMP)
14171 +               pax_flags |= MF_PAX_EMUTRAMP;
14172 +#endif
14173 +
14174 +#ifdef CONFIG_PAX_MPROTECT
14175 +       if (elf_phdata->p_flags & PF_MPROTECT)
14176 +               pax_flags |= MF_PAX_MPROTECT;
14177 +#endif
14178 +
14179 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14180 +       if (randomize_va_space && (elf_phdata->p_flags & PF_RANDMMAP))
14181 +               pax_flags |= MF_PAX_RANDMMAP;
14182 +#endif
14183 +
14184 +       return pax_flags;
14185 +}
14186 +#endif
14187 +
14188 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14189 +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata)
14190 +{
14191 +       unsigned long pax_flags = 0UL;
14192 +
14193 +#ifdef CONFIG_PAX_PAGEEXEC
14194 +       if (!(elf_phdata->p_flags & PF_NOPAGEEXEC))
14195 +               pax_flags |= MF_PAX_PAGEEXEC;
14196 +#endif
14197 +
14198 +#ifdef CONFIG_PAX_SEGMEXEC
14199 +       if (!(elf_phdata->p_flags & PF_NOSEGMEXEC))
14200 +               pax_flags |= MF_PAX_SEGMEXEC;
14201 +#endif
14202 +
14203 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14204 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14205 +               if (nx_enabled)
14206 +                       pax_flags &= ~MF_PAX_SEGMEXEC;
14207 +               else
14208 +                       pax_flags &= ~MF_PAX_PAGEEXEC;
14209 +       }
14210 +#endif
14211 +
14212 +#ifdef CONFIG_PAX_EMUTRAMP
14213 +       if (!(elf_phdata->p_flags & PF_NOEMUTRAMP))
14214 +               pax_flags |= MF_PAX_EMUTRAMP;
14215 +#endif
14216 +
14217 +#ifdef CONFIG_PAX_MPROTECT
14218 +       if (!(elf_phdata->p_flags & PF_NOMPROTECT))
14219 +               pax_flags |= MF_PAX_MPROTECT;
14220 +#endif
14221 +
14222 +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)
14223 +       if (randomize_va_space && !(elf_phdata->p_flags & PF_NORANDMMAP))
14224 +               pax_flags |= MF_PAX_RANDMMAP;
14225 +#endif
14226 +
14227 +       return pax_flags;
14228 +}
14229 +#endif
14230 +
14231 +#ifdef CONFIG_PAX_EI_PAX
14232 +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex)
14233 +{
14234 +       unsigned long pax_flags = 0UL;
14235 +
14236 +#ifdef CONFIG_PAX_PAGEEXEC
14237 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC))
14238 +               pax_flags |= MF_PAX_PAGEEXEC;
14239 +#endif
14240 +
14241 +#ifdef CONFIG_PAX_SEGMEXEC
14242 +       if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC))
14243 +               pax_flags |= MF_PAX_SEGMEXEC;
14244 +#endif
14245 +
14246 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_PAX_SEGMEXEC)
14247 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) == (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14248 +               if (nx_enabled)
14249 +                       pax_flags &= ~MF_PAX_SEGMEXEC;
14250 +               else
14251 +                       pax_flags &= ~MF_PAX_PAGEEXEC;
14252 +       }
14253 +#endif
14254 +
14255 +#ifdef CONFIG_PAX_EMUTRAMP
14256 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP))
14257 +               pax_flags |= MF_PAX_EMUTRAMP;
14258 +#endif
14259 +
14260 +#ifdef CONFIG_PAX_MPROTECT
14261 +       if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT))
14262 +               pax_flags |= MF_PAX_MPROTECT;
14263 +#endif
14264 +
14265 +#ifdef CONFIG_PAX_ASLR
14266 +       if (randomize_va_space && !(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP))
14267 +               pax_flags |= MF_PAX_RANDMMAP;
14268 +#endif
14269 +
14270 +       return pax_flags;
14271 +}
14272 +#endif
14273 +
14274 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14275 +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata)
14276 +{
14277 +       unsigned long pax_flags = 0UL;
14278 +
14279 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14280 +       unsigned long i;
14281 +#endif
14282 +
14283 +#ifdef CONFIG_PAX_EI_PAX
14284 +       pax_flags = pax_parse_ei_pax(elf_ex);
14285 +#endif
14286 +
14287 +#ifdef CONFIG_PAX_PT_PAX_FLAGS
14288 +       for (i = 0UL; i < elf_ex->e_phnum; i++)
14289 +               if (elf_phdata[i].p_type == PT_PAX_FLAGS) {
14290 +                       if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) ||
14291 +                           ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) ||
14292 +                           ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) ||
14293 +                           ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) ||
14294 +                           ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP)))
14295 +                               return -EINVAL;
14296 +
14297 +#ifdef CONFIG_PAX_SOFTMODE
14298 +                       if (pax_softmode)
14299 +                               pax_flags = pax_parse_softmode(&elf_phdata[i]);
14300 +                       else
14301 +#endif
14302 +
14303 +                               pax_flags = pax_parse_hardmode(&elf_phdata[i]);
14304 +                       break;
14305 +               }
14306 +#endif
14307 +
14308 +       if (0 > pax_check_flags(&pax_flags))
14309 +               return -EINVAL;
14310 +
14311 +       current->mm->pax_flags = pax_flags;
14312 +       return 0;
14313 +}
14314 +#endif
14315 +
14316  /*
14317   * These are the functions used to load ELF style executables and shared
14318   * libraries.  There is no binary dependent code anywhere else.
14319 @@ -543,6 +736,11 @@ static unsigned long randomize_stack_top
14320  {
14321         unsigned int random_variable = 0;
14322  
14323 +#ifdef CONFIG_PAX_RANDUSTACK
14324 +       if (randomize_va_space)
14325 +               return stack_top - current->mm->delta_stack;
14326 +#endif
14327 +
14328         if ((current->flags & PF_RANDOMIZE) &&
14329                 !(current->personality & ADDR_NO_RANDOMIZE)) {
14330                 random_variable = get_random_int() & STACK_RND_MASK;
14331 @@ -561,7 +759,7 @@ static int load_elf_binary(struct linux_
14332         unsigned long load_addr = 0, load_bias = 0;
14333         int load_addr_set = 0;
14334         char * elf_interpreter = NULL;
14335 -       unsigned long error;
14336 +       unsigned long error = 0;
14337         struct elf_phdr *elf_ppnt, *elf_phdata;
14338         unsigned long elf_bss, elf_brk;
14339         int elf_exec_fileno;
14340 @@ -572,11 +770,11 @@ static int load_elf_binary(struct linux_
14341         unsigned long start_code, end_code, start_data, end_data;
14342         unsigned long reloc_func_desc = 0;
14343         int executable_stack = EXSTACK_DEFAULT;
14344 -       unsigned long def_flags = 0;
14345         struct {
14346                 struct elfhdr elf_ex;
14347                 struct elfhdr interp_elf_ex;
14348         } *loc;
14349 +       unsigned long pax_task_size = TASK_SIZE;
14350  
14351         loc = kmalloc(sizeof(*loc), GFP_KERNEL);
14352         if (!loc) {
14353 @@ -744,11 +942,80 @@ static int load_elf_binary(struct linux_
14354  
14355         /* OK, This is the point of no return */
14356         current->flags &= ~PF_FORKNOEXEC;
14357 -       current->mm->def_flags = def_flags;
14358 +
14359 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
14360 +       current->mm->pax_flags = 0UL;
14361 +#endif
14362 +
14363 +#ifdef CONFIG_PAX_DLRESOLVE
14364 +       current->mm->call_dl_resolve = 0UL;
14365 +#endif
14366 +
14367 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
14368 +       current->mm->call_syscall = 0UL;
14369 +#endif
14370 +
14371 +#ifdef CONFIG_PAX_ASLR
14372 +       current->mm->delta_mmap = 0UL;
14373 +       current->mm->delta_stack = 0UL;
14374 +#endif
14375 +
14376 +       current->mm->def_flags = 0;
14377 +
14378 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)
14379 +       if (0 > pax_parse_elf_flags(&loc->elf_ex, elf_phdata)) {
14380 +               send_sig(SIGKILL, current, 0);
14381 +               goto out_free_dentry;
14382 +       }
14383 +#endif
14384 +
14385 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
14386 +       pax_set_initial_flags(bprm);
14387 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
14388 +       if (pax_set_initial_flags_func)
14389 +               (pax_set_initial_flags_func)(bprm);
14390 +#endif
14391 +
14392 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
14393 +       if ((current->mm->pax_flags & MF_PAX_PAGEEXEC) && !nx_enabled) {
14394 +               current->mm->context.user_cs_limit = PAGE_SIZE;
14395 +               current->mm->def_flags |= VM_PAGEEXEC;
14396 +       }
14397 +#endif
14398 +
14399 +#ifdef CONFIG_PAX_SEGMEXEC
14400 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
14401 +               current->mm->context.user_cs_base = SEGMEXEC_TASK_SIZE;
14402 +               current->mm->context.user_cs_limit = TASK_SIZE-SEGMEXEC_TASK_SIZE;
14403 +               pax_task_size = SEGMEXEC_TASK_SIZE;
14404 +       }
14405 +#endif
14406 +
14407 +#if defined(CONFIG_ARCH_TRACK_EXEC_LIMIT) || defined(CONFIG_PAX_SEGMEXEC)
14408 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14409 +               set_user_cs(current->mm->context.user_cs_base, current->mm->context.user_cs_limit, get_cpu());
14410 +               put_cpu_no_resched();
14411 +       }
14412 +#endif
14413 +
14414 +#ifdef CONFIG_PAX_ASLR
14415 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP) {
14416 +               current->mm->delta_mmap = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT;
14417 +               current->mm->delta_stack = (pax_get_random_long() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT;
14418 +       }
14419 +#endif
14420  
14421         /* Do this immediately, since STACK_TOP as used in setup_arg_pages
14422            may depend on the personality.  */
14423         SET_PERSONALITY(loc->elf_ex, 0);
14424 +
14425 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
14426 +       if (current->mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
14427 +               executable_stack = EXSTACK_DISABLE_X;
14428 +               current->personality &= ~READ_IMPLIES_EXEC;
14429 +       } else
14430 +#endif
14431 +
14432         if (elf_read_implies_exec(loc->elf_ex, executable_stack))
14433                 current->personality |= READ_IMPLIES_EXEC;
14434  
14435 @@ -829,6 +1096,20 @@ static int load_elf_binary(struct linux_
14436  #else
14437                         load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
14438  #endif
14439 +
14440 +#ifdef CONFIG_PAX_RANDMMAP
14441 +                       /* PaX: randomize base address at the default exe base if requested */
14442 +                       if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) {
14443 +#ifdef CONFIG_SPARC64
14444 +                               load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1);
14445 +#else
14446 +                               load_bias = (pax_get_random_long() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT;
14447 +#endif
14448 +                               load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias);
14449 +                               elf_flags |= MAP_FIXED;
14450 +                       }
14451 +#endif
14452 +
14453                 }
14454  
14455                 error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt,
14456 @@ -861,9 +1142,9 @@ static int load_elf_binary(struct linux_
14457                  * allowed task size. Note that p_filesz must always be
14458                  * <= p_memsz so it is only necessary to check p_memsz.
14459                  */
14460 -               if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14461 -                   elf_ppnt->p_memsz > TASK_SIZE ||
14462 -                   TASK_SIZE - elf_ppnt->p_memsz < k) {
14463 +               if (k >= pax_task_size || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
14464 +                   elf_ppnt->p_memsz > pax_task_size ||
14465 +                   pax_task_size - elf_ppnt->p_memsz < k) {
14466                         /* set_brk can never work. Avoid overflows. */
14467                         send_sig(SIGKILL, current, 0);
14468                         retval = -EINVAL;
14469 @@ -891,6 +1172,11 @@ static int load_elf_binary(struct linux_
14470         start_data += load_bias;
14471         end_data += load_bias;
14472  
14473 +#ifdef CONFIG_PAX_RANDMMAP
14474 +       if (current->mm->pax_flags & MF_PAX_RANDMMAP)
14475 +               elf_brk += PAGE_SIZE + ((pax_get_random_long() & ~PAGE_MASK) << 4);
14476 +#endif
14477 +
14478         /* Calling set_brk effectively mmaps the pages that we need
14479          * for the bss and break sections.  We must do this before
14480          * mapping in the interpreter, to make sure it doesn't wind
14481 @@ -902,9 +1188,11 @@ static int load_elf_binary(struct linux_
14482                 goto out_free_dentry;
14483         }
14484         if (likely(elf_bss != elf_brk) && unlikely(padzero(elf_bss))) {
14485 -               send_sig(SIGSEGV, current, 0);
14486 -               retval = -EFAULT; /* Nobody gets to see this, but.. */
14487 -               goto out_free_dentry;
14488 +               /*
14489 +                * This bss-zeroing can fail if the ELF
14490 +                * file specifies odd protections. So
14491 +                * we don't check the return value
14492 +                */
14493         }
14494  
14495         if (elf_interpreter) {
14496 @@ -1141,8 +1429,10 @@ static int dump_seek(struct file *file, 
14497                         unsigned long n = off;
14498                         if (n > PAGE_SIZE)
14499                                 n = PAGE_SIZE;
14500 -                       if (!dump_write(file, buf, n))
14501 +                       if (!dump_write(file, buf, n)) {
14502 +                               free_page((unsigned long)buf);
14503                                 return 0;
14504 +                       }
14505                         off -= n;
14506                 }
14507                 free_page((unsigned long)buf);
14508 @@ -1154,7 +1444,7 @@ static int dump_seek(struct file *file, 
14509   * Decide what to dump of a segment, part, all or none.
14510   */
14511  static unsigned long vma_dump_size(struct vm_area_struct *vma,
14512 -                                  unsigned long mm_flags)
14513 +                                  unsigned long mm_flags, long signr)
14514  {
14515         /* The vma can be set up to tell us the answer directly.  */
14516         if (vma->vm_flags & VM_ALWAYSDUMP)
14517 @@ -1180,7 +1470,7 @@ static unsigned long vma_dump_size(struc
14518         if (vma->vm_file == NULL)
14519                 return 0;
14520  
14521 -       if (FILTER(MAPPED_PRIVATE))
14522 +       if (signr == SIGKILL || FILTER(MAPPED_PRIVATE))
14523                 goto whole;
14524  
14525         /*
14526 @@ -1266,8 +1556,11 @@ static int writenote(struct memelfnote *
14527  #undef DUMP_WRITE
14528  
14529  #define DUMP_WRITE(addr, nr)   \
14530 +       do { \
14531 +       gr_learn_resource(current, RLIMIT_CORE, size + (nr), 1); \
14532         if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
14533 -               goto end_coredump;
14534 +               goto end_coredump; \
14535 +       } while (0);
14536  #define DUMP_SEEK(off) \
14537         if (!dump_seek(file, (off))) \
14538                 goto end_coredump;
14539 @@ -1973,7 +2266,7 @@ static int elf_core_dump(long signr, str
14540                 phdr.p_offset = offset;
14541                 phdr.p_vaddr = vma->vm_start;
14542                 phdr.p_paddr = 0;
14543 -               phdr.p_filesz = vma_dump_size(vma, mm_flags);
14544 +               phdr.p_filesz = vma_dump_size(vma, mm_flags, signr);
14545                 phdr.p_memsz = vma->vm_end - vma->vm_start;
14546                 offset += phdr.p_filesz;
14547                 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
14548 @@ -2005,7 +2298,7 @@ static int elf_core_dump(long signr, str
14549                 unsigned long addr;
14550                 unsigned long end;
14551  
14552 -               end = vma->vm_start + vma_dump_size(vma, mm_flags);
14553 +               end = vma->vm_start + vma_dump_size(vma, mm_flags, signr);
14554  
14555                 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
14556                         struct page *page;
14557 @@ -2025,6 +2318,7 @@ static int elf_core_dump(long signr, str
14558                                         flush_cache_page(tmp_vma, addr,
14559                                                          page_to_pfn(page));
14560                                         kaddr = kmap(page);
14561 +                                       gr_learn_resource(current, RLIMIT_CORE, size + PAGE_SIZE, 1);
14562                                         if ((size += PAGE_SIZE) > limit ||
14563                                             !dump_write(file, kaddr,
14564                                             PAGE_SIZE)) {
14565 @@ -2055,6 +2349,99 @@ out:
14566  
14567  #endif         /* USE_ELF_CORE_DUMP */
14568  
14569 +#ifdef CONFIG_PAX_MPROTECT
14570 +/* PaX: non-PIC ELF libraries need relocations on their executable segments
14571 + * therefore we'll grant them VM_MAYWRITE once during their life. Similarly
14572 + * we'll remove VM_MAYWRITE for good on RELRO segments.
14573 + *
14574 + * The checks favour ld-linux.so behaviour which operates on a per ELF segment
14575 + * basis because we want to allow the common case and not the special ones.
14576 + */
14577 +static void elf_handle_mprotect(struct vm_area_struct *vma, unsigned long newflags)
14578 +{
14579 +       struct elfhdr elf_h;
14580 +       struct elf_phdr elf_p;
14581 +       unsigned long i;
14582 +       unsigned long oldflags;
14583 +       bool is_textrel_rw, is_textrel_rx, is_relro;
14584 +
14585 +       if (!(vma->vm_mm->pax_flags & MF_PAX_MPROTECT))
14586 +               return;
14587 +
14588 +       oldflags = vma->vm_flags & (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ);
14589 +       newflags &= VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_EXEC | VM_WRITE | VM_READ;
14590 +
14591 +#ifdef CONFIG_PAX_NOELFRELOCS
14592 +       is_textrel_rw = false;
14593 +       is_textrel_rx = false;
14594 +#else
14595 +       /* possible TEXTREL */
14596 +       is_textrel_rw = vma->vm_file && !vma->anon_vma && !vma->vm_pgoff && oldflags == (VM_MAYEXEC | VM_MAYREAD | VM_EXEC | VM_READ) && newflags == (VM_WRITE | VM_READ);
14597 +       is_textrel_rx = vma->vm_file && vma->anon_vma && !vma->vm_pgoff && oldflags == (VM_MAYEXEC | VM_MAYWRITE | VM_MAYREAD | VM_WRITE | VM_READ) && newflags == (VM_EXEC | VM_READ);
14598 +#endif
14599 +
14600 +       /* possible RELRO */
14601 +       is_relro = vma->vm_file && vma->anon_vma && oldflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ) && newflags == (VM_MAYWRITE | VM_MAYREAD | VM_READ);
14602 +
14603 +       if (!is_textrel_rw && !is_textrel_rx && !is_relro)
14604 +               return;
14605 +
14606 +       if (sizeof(elf_h) != kernel_read(vma->vm_file, 0UL, (char *)&elf_h, sizeof(elf_h)) ||
14607 +           memcmp(elf_h.e_ident, ELFMAG, SELFMAG) ||
14608 +
14609 +#ifdef CONFIG_PAX_ETEXECRELOCS
14610 +           ((is_textrel_rw || is_textrel_rx) && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
14611 +#else
14612 +           ((is_textrel_rw || is_textrel_rx) && elf_h.e_type != ET_DYN) ||
14613 +#endif
14614 +
14615 +           (is_relro && (elf_h.e_type != ET_DYN && elf_h.e_type != ET_EXEC)) ||
14616 +           !elf_check_arch(&elf_h) ||
14617 +           elf_h.e_phentsize != sizeof(struct elf_phdr) ||
14618 +           elf_h.e_phnum > 65536UL / sizeof(struct elf_phdr))
14619 +               return;
14620 +
14621 +       for (i = 0UL; i < elf_h.e_phnum; i++) {
14622 +               if (sizeof(elf_p) != kernel_read(vma->vm_file, elf_h.e_phoff + i*sizeof(elf_p), (char *)&elf_p, sizeof(elf_p)))
14623 +                       return;
14624 +               switch (elf_p.p_type) {
14625 +               case PT_DYNAMIC: {
14626 +                       elf_addr_t dyn_offset = 0UL;
14627 +                       elf_dyn dyn;
14628 +
14629 +                       if (!is_textrel_rw && !is_textrel_rx)
14630 +                               continue;
14631 +                       dyn_offset = elf_p.p_offset;
14632 +                       i = 0UL;
14633 +                       do {
14634 +                               if (sizeof(dyn) != kernel_read(vma->vm_file, dyn_offset + i*sizeof(dyn), (char *)&dyn, sizeof(dyn)))
14635 +                                       return;
14636 +                               if (dyn.d_tag == DT_TEXTREL || (dyn.d_tag == DT_FLAGS && (dyn.d_un.d_val & DF_TEXTREL))) {
14637 +                                       gr_log_textrel(vma);
14638 +                                       if (is_textrel_rw)
14639 +                                               vma->vm_flags |= VM_MAYWRITE;
14640 +                                       else
14641 +                                               /* PaX: disallow write access after relocs are done, hopefully noone else needs it... */
14642 +                                               vma->vm_flags &= ~VM_MAYWRITE;
14643 +                                       return;
14644 +                               }
14645 +                               i++;
14646 +                       } while (dyn.d_tag != DT_NULL);
14647 +                       return;
14648 +               }
14649 +
14650 +               case PT_GNU_RELRO:
14651 +                       if (!is_relro)
14652 +                               continue;
14653 +                       if ((elf_p.p_offset >> PAGE_SHIFT) == vma->vm_pgoff && ELF_PAGEALIGN(elf_p.p_memsz) == vma->vm_end - vma->vm_start) {
14654 +                               vma->vm_flags &= ~VM_MAYWRITE;
14655 +                       }
14656 +                       return;
14657 +               }
14658 +       }
14659 +}
14660 +#endif
14661 +
14662  static int __init init_elf_binfmt(void)
14663  {
14664         return register_binfmt(&elf_format);
14665 diff -urNp linux-2.6.27.10/fs/binfmt_flat.c linux-2.6.27.10/fs/binfmt_flat.c
14666 --- linux-2.6.27.10/fs/binfmt_flat.c    2008-11-07 12:55:34.000000000 -0500
14667 +++ linux-2.6.27.10/fs/binfmt_flat.c    2008-11-18 03:38:45.000000000 -0500
14668 @@ -561,7 +561,9 @@ static int load_flat_file(struct linux_b
14669                                 realdatastart = (unsigned long) -ENOMEM;
14670                         printk("Unable to allocate RAM for process data, errno %d\n",
14671                                         (int)-realdatastart);
14672 +                       down_write(&current->mm->mmap_sem);
14673                         do_munmap(current->mm, textpos, text_len);
14674 +                       up_write(&current->mm->mmap_sem);
14675                         ret = realdatastart;
14676                         goto err;
14677                 }
14678 @@ -583,8 +585,10 @@ static int load_flat_file(struct linux_b
14679                 }
14680                 if (result >= (unsigned long)-4096) {
14681                         printk("Unable to read data+bss, errno %d\n", (int)-result);
14682 +                       down_write(&current->mm->mmap_sem);
14683                         do_munmap(current->mm, textpos, text_len);
14684                         do_munmap(current->mm, realdatastart, data_len + extra);
14685 +                       up_write(&current->mm->mmap_sem);
14686                         ret = result;
14687                         goto err;
14688                 }
14689 @@ -657,8 +661,10 @@ static int load_flat_file(struct linux_b
14690                 }
14691                 if (result >= (unsigned long)-4096) {
14692                         printk("Unable to read code+data+bss, errno %d\n",(int)-result);
14693 +                       down_write(&current->mm->mmap_sem);
14694                         do_munmap(current->mm, textpos, text_len + data_len + extra +
14695                                 MAX_SHARED_LIBS * sizeof(unsigned long));
14696 +                       up_write(&current->mm->mmap_sem);
14697                         ret = result;
14698                         goto err;
14699                 }
14700 diff -urNp linux-2.6.27.10/fs/binfmt_misc.c linux-2.6.27.10/fs/binfmt_misc.c
14701 --- linux-2.6.27.10/fs/binfmt_misc.c    2008-12-21 01:16:51.000000000 -0500
14702 +++ linux-2.6.27.10/fs/binfmt_misc.c    2008-12-21 01:13:46.000000000 -0500
14703 @@ -696,7 +696,7 @@ static int bm_fill_super(struct super_bl
14704         static struct tree_descr bm_files[] = {
14705                 [2] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
14706                 [3] = {"register", &bm_register_operations, S_IWUSR},
14707 -               /* last one */ {""}
14708 +               /* last one */ {"", NULL, 0}
14709         };
14710         int err = simple_fill_super(sb, 0x42494e4d, bm_files);
14711         if (!err)
14712 diff -urNp linux-2.6.27.10/fs/bio.c linux-2.6.27.10/fs/bio.c
14713 --- linux-2.6.27.10/fs/bio.c    2008-11-07 12:55:34.000000000 -0500
14714 +++ linux-2.6.27.10/fs/bio.c    2008-11-18 03:38:45.000000000 -0500
14715 @@ -507,7 +507,7 @@ static int __bio_copy_iov(struct bio *bi
14716  
14717                 while (bv_len && iov_idx < iov_count) {
14718                         unsigned int bytes;
14719 -                       char *iov_addr;
14720 +                       char __user *iov_addr;
14721  
14722                         bytes = min_t(unsigned int,
14723                                       iov[iov_idx].iov_len - iov_off, bv_len);
14724 diff -urNp linux-2.6.27.10/fs/buffer.c linux-2.6.27.10/fs/buffer.c
14725 --- linux-2.6.27.10/fs/buffer.c 2008-11-07 12:55:34.000000000 -0500
14726 +++ linux-2.6.27.10/fs/buffer.c 2008-11-18 03:38:45.000000000 -0500
14727 @@ -41,6 +41,7 @@
14728  #include <linux/bitops.h>
14729  #include <linux/mpage.h>
14730  #include <linux/bit_spinlock.h>
14731 +#include <linux/grsecurity.h>
14732  
14733  static int fsync_buffers_list(spinlock_t *lock, struct list_head *list);
14734  
14735 @@ -2249,6 +2250,7 @@ int generic_cont_expand_simple(struct in
14736  
14737         err = -EFBIG;
14738          limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
14739 +       gr_learn_resource(current, RLIMIT_FSIZE, (unsigned long) size, 1);
14740         if (limit != RLIM_INFINITY && size > (loff_t)limit) {
14741                 send_sig(SIGXFSZ, current, 0);
14742                 goto out;
14743 diff -urNp linux-2.6.27.10/fs/cifs/cifs_uniupr.h linux-2.6.27.10/fs/cifs/cifs_uniupr.h
14744 --- linux-2.6.27.10/fs/cifs/cifs_uniupr.h       2008-11-07 12:55:34.000000000 -0500
14745 +++ linux-2.6.27.10/fs/cifs/cifs_uniupr.h       2008-11-18 03:38:45.000000000 -0500
14746 @@ -132,7 +132,7 @@ const struct UniCaseRange CifsUniUpperRa
14747         {0x0490, 0x04cc, UniCaseRangeU0490},
14748         {0x1e00, 0x1ffc, UniCaseRangeU1e00},
14749         {0xff40, 0xff5a, UniCaseRangeUff40},
14750 -       {0}
14751 +       {0, 0, NULL}
14752  };
14753  #endif
14754  
14755 diff -urNp linux-2.6.27.10/fs/cifs/link.c linux-2.6.27.10/fs/cifs/link.c
14756 --- linux-2.6.27.10/fs/cifs/link.c      2008-11-07 12:55:34.000000000 -0500
14757 +++ linux-2.6.27.10/fs/cifs/link.c      2008-11-18 03:38:45.000000000 -0500
14758 @@ -318,7 +318,7 @@ cifs_readlink(struct dentry *direntry, c
14759  
14760  void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
14761  {
14762 -       char *p = nd_get_link(nd);
14763 +       const char *p = nd_get_link(nd);
14764         if (!IS_ERR(p))
14765                 kfree(p);
14766  }
14767 diff -urNp linux-2.6.27.10/fs/compat.c linux-2.6.27.10/fs/compat.c
14768 --- linux-2.6.27.10/fs/compat.c 2008-11-07 12:55:34.000000000 -0500
14769 +++ linux-2.6.27.10/fs/compat.c 2008-11-18 03:38:45.000000000 -0500
14770 @@ -51,6 +51,7 @@
14771  #include <linux/poll.h>
14772  #include <linux/mm.h>
14773  #include <linux/eventpoll.h>
14774 +#include <linux/grsecurity.h>
14775  
14776  #include <asm/uaccess.h>
14777  #include <asm/mmu_context.h>
14778 @@ -1298,14 +1299,12 @@ static int compat_copy_strings(int argc,
14779                         if (!kmapped_page || kpos != (pos & PAGE_MASK)) {
14780                                 struct page *page;
14781  
14782 -#ifdef CONFIG_STACK_GROWSUP
14783                                 ret = expand_stack_downwards(bprm->vma, pos);
14784                                 if (ret < 0) {
14785                                         /* We've exceed the stack rlimit. */
14786                                         ret = -E2BIG;
14787                                         goto out;
14788                                 }
14789 -#endif
14790                                 ret = get_user_pages(current, bprm->mm, pos,
14791                                                      1, 1, 1, &page, NULL);
14792                                 if (ret <= 0) {
14793 @@ -1351,6 +1350,11 @@ int compat_do_execve(char * filename,
14794         compat_uptr_t __user *envp,
14795         struct pt_regs * regs)
14796  {
14797 +#ifdef CONFIG_GRKERNSEC
14798 +       struct file *old_exec_file;
14799 +       struct acl_subject_label *old_acl;
14800 +       struct rlimit old_rlim[RLIM_NLIMITS];
14801 +#endif
14802         struct linux_binprm *bprm;
14803         struct file *file;
14804         int retval;
14805 @@ -1371,6 +1375,14 @@ int compat_do_execve(char * filename,
14806         bprm->filename = filename;
14807         bprm->interp = filename;
14808  
14809 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
14810 +       retval = -EAGAIN;
14811 +       if (gr_handle_nproc())
14812 +               goto out_file;
14813 +       retval = -EACCES;
14814 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt))
14815 +               goto out_file;
14816 +
14817         retval = bprm_mm_init(bprm);
14818         if (retval)
14819                 goto out_file;
14820 @@ -1404,8 +1416,36 @@ int compat_do_execve(char * filename,
14821         if (retval < 0)
14822                 goto out;
14823  
14824 +       if (!gr_tpe_allow(file)) {
14825 +               retval = -EACCES;
14826 +               goto out;
14827 +       }
14828 +
14829 +       if (gr_check_crash_exec(file)) {
14830 +               retval = -EACCES;
14831 +               goto out;
14832 +       }
14833 +
14834 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
14835 +
14836 +       gr_handle_exec_args(bprm, (char __user * __user *)argv);
14837 +
14838 +#ifdef CONFIG_GRKERNSEC
14839 +       old_acl = current->acl;
14840 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
14841 +       old_exec_file = current->exec_file;
14842 +       get_file(file);
14843 +       current->exec_file = file;
14844 +#endif
14845 +
14846 +       gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
14847 +
14848         retval = search_binary_handler(bprm, regs);
14849         if (retval >= 0) {
14850 +#ifdef CONFIG_GRKERNSEC
14851 +               if (old_exec_file)
14852 +                       fput(old_exec_file);
14853 +#endif
14854                 /* execve success */
14855                 security_bprm_free(bprm);
14856                 acct_update_integrals(current);
14857 @@ -1413,6 +1453,13 @@ int compat_do_execve(char * filename,
14858                 return retval;
14859         }
14860  
14861 +#ifdef CONFIG_GRKERNSEC
14862 +       current->acl = old_acl;
14863 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
14864 +       fput(current->exec_file);
14865 +       current->exec_file = old_exec_file;
14866 +#endif
14867 +
14868  out:
14869         if (bprm->security)
14870                 security_bprm_free(bprm);
14871 diff -urNp linux-2.6.27.10/fs/compat_ioctl.c linux-2.6.27.10/fs/compat_ioctl.c
14872 --- linux-2.6.27.10/fs/compat_ioctl.c   2008-11-07 12:55:34.000000000 -0500
14873 +++ linux-2.6.27.10/fs/compat_ioctl.c   2008-11-18 03:38:45.000000000 -0500
14874 @@ -1831,15 +1831,15 @@ struct ioctl_trans {
14875  };
14876  
14877  #define HANDLE_IOCTL(cmd,handler) \
14878 -       { (cmd), (ioctl_trans_handler_t)(handler) },
14879 +       { (cmd), (ioctl_trans_handler_t)(handler), NULL },
14880  
14881  /* pointer to compatible structure or no argument */
14882  #define COMPATIBLE_IOCTL(cmd) \
14883 -       { (cmd), do_ioctl32_pointer },
14884 +       { (cmd), do_ioctl32_pointer, NULL },
14885  
14886  /* argument is an unsigned long integer, not a pointer */
14887  #define ULONG_IOCTL(cmd) \
14888 -       { (cmd), (ioctl_trans_handler_t)sys_ioctl },
14889 +       { (cmd), (ioctl_trans_handler_t)sys_ioctl, NULL },
14890  
14891  /* ioctl should not be warned about even if it's not implemented.
14892     Valid reasons to use this:
14893 diff -urNp linux-2.6.27.10/fs/debugfs/inode.c linux-2.6.27.10/fs/debugfs/inode.c
14894 --- linux-2.6.27.10/fs/debugfs/inode.c  2008-11-07 12:55:34.000000000 -0500
14895 +++ linux-2.6.27.10/fs/debugfs/inode.c  2008-11-18 03:38:45.000000000 -0500
14896 @@ -121,7 +121,7 @@ static inline int debugfs_positive(struc
14897  
14898  static int debug_fill_super(struct super_block *sb, void *data, int silent)
14899  {
14900 -       static struct tree_descr debug_files[] = {{""}};
14901 +       static struct tree_descr debug_files[] = {{"", NULL, 0}};
14902  
14903         return simple_fill_super(sb, DEBUGFS_MAGIC, debug_files);
14904  }
14905 diff -urNp linux-2.6.27.10/fs/exec.c linux-2.6.27.10/fs/exec.c
14906 --- linux-2.6.27.10/fs/exec.c   2008-12-21 01:16:51.000000000 -0500
14907 +++ linux-2.6.27.10/fs/exec.c   2008-12-21 01:13:46.000000000 -0500
14908 @@ -50,6 +50,13 @@
14909  #include <linux/cn_proc.h>
14910  #include <linux/audit.h>
14911  #include <linux/tracehook.h>
14912 +#include <linux/random.h>
14913 +#include <linux/grsecurity.h>
14914 +
14915 +#ifdef CONFIG_PAX_REFCOUNT
14916 +#include <linux/kallsyms.h>
14917 +#include <linux/kdebug.h>
14918 +#endif
14919  
14920  #include <asm/uaccess.h>
14921  #include <asm/mmu_context.h>
14922 @@ -64,6 +71,11 @@
14923  #include <linux/a.out.h>
14924  #endif
14925  
14926 +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS
14927 +void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
14928 +EXPORT_SYMBOL(pax_set_initial_flags_func);
14929 +#endif
14930 +
14931  int core_uses_pid;
14932  char core_pattern[CORENAME_MAX_SIZE] = "core";
14933  int suid_dumpable = 0;
14934 @@ -172,18 +184,10 @@ static struct page *get_arg_page(struct 
14935                 int write)
14936  {
14937         struct page *page;
14938 -       int ret;
14939  
14940 -#ifdef CONFIG_STACK_GROWSUP
14941 -       if (write) {
14942 -               ret = expand_stack_downwards(bprm->vma, pos);
14943 -               if (ret < 0)
14944 -                       return NULL;
14945 -       }
14946 -#endif
14947 -       ret = get_user_pages(current, bprm->mm, pos,
14948 -                       1, write, 1, &page, NULL);
14949 -       if (ret <= 0)
14950 +       if (0 > expand_stack_downwards(bprm->vma, pos))
14951 +               return NULL;
14952 +       if (0 >= get_user_pages(current, bprm->mm, pos, 1, write, 1, &page, NULL))
14953                 return NULL;
14954  
14955         if (write) {
14956 @@ -256,6 +260,11 @@ static int __bprm_mm_init(struct linux_b
14957         vma->vm_start = vma->vm_end - PAGE_SIZE;
14958  
14959         vma->vm_flags = VM_STACK_FLAGS;
14960 +
14961 +#ifdef CONFIG_PAX_SEGMEXEC
14962 +       vma->vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
14963 +#endif
14964 +
14965         vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
14966         err = insert_vm_struct(mm, vma);
14967         if (err) {
14968 @@ -268,6 +277,11 @@ static int __bprm_mm_init(struct linux_b
14969  
14970         bprm->p = vma->vm_end - sizeof(void *);
14971  
14972 +#ifdef CONFIG_PAX_RANDUSTACK
14973 +       if (randomize_va_space)
14974 +               bprm->p ^= (pax_get_random_long() & ~15) & ~PAGE_MASK;
14975 +#endif
14976 +
14977         return 0;
14978  
14979  err:
14980 @@ -391,7 +405,7 @@ static int count(char __user * __user * 
14981                         if (!p)
14982                                 break;
14983                         argv++;
14984 -                       if(++i > max)
14985 +                       if (++i > max)
14986                                 return -E2BIG;
14987                         cond_resched();
14988                 }
14989 @@ -531,6 +545,10 @@ static int shift_arg_pages(struct vm_are
14990         if (vma != find_vma(mm, new_start))
14991                 return -EFAULT;
14992  
14993 +#ifdef CONFIG_PAX_SEGMEXEC
14994 +       BUG_ON(pax_find_mirror_vma(vma));
14995 +#endif
14996 +
14997         /*
14998          * cover the whole range: [new_start, old_end)
14999          */
15000 @@ -619,6 +637,14 @@ int setup_arg_pages(struct linux_binprm 
15001         bprm->exec -= stack_shift;
15002  
15003         down_write(&mm->mmap_sem);
15004 +
15005 +       /* Move stack pages down in memory. */
15006 +       if (stack_shift) {
15007 +               ret = shift_arg_pages(vma, stack_shift);
15008 +               if (ret)
15009 +                       goto out_unlock;
15010 +       }
15011 +
15012         vm_flags = VM_STACK_FLAGS;
15013  
15014         /*
15015 @@ -632,21 +658,24 @@ int setup_arg_pages(struct linux_binprm 
15016                 vm_flags &= ~VM_EXEC;
15017         vm_flags |= mm->def_flags;
15018  
15019 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15020 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
15021 +               vm_flags &= ~VM_EXEC;
15022 +
15023 +#ifdef CONFIG_PAX_MPROTECT
15024 +               if (mm->pax_flags & MF_PAX_MPROTECT)
15025 +                       vm_flags &= ~VM_MAYEXEC;
15026 +#endif
15027 +
15028 +       }
15029 +#endif
15030 +
15031         ret = mprotect_fixup(vma, &prev, vma->vm_start, vma->vm_end,
15032                         vm_flags);
15033         if (ret)
15034                 goto out_unlock;
15035         BUG_ON(prev != vma);
15036  
15037 -       /* Move stack pages down in memory. */
15038 -       if (stack_shift) {
15039 -               ret = shift_arg_pages(vma, stack_shift);
15040 -               if (ret) {
15041 -                       up_write(&mm->mmap_sem);
15042 -                       return ret;
15043 -               }
15044 -       }
15045 -
15046  #ifdef CONFIG_STACK_GROWSUP
15047         stack_base = vma->vm_end + EXTRA_STACK_VM_PAGES * PAGE_SIZE;
15048  #else
15049 @@ -658,7 +687,7 @@ int setup_arg_pages(struct linux_binprm 
15050  
15051  out_unlock:
15052         up_write(&mm->mmap_sem);
15053 -       return 0;
15054 +       return ret;
15055  }
15056  EXPORT_SYMBOL(setup_arg_pages);
15057  
15058 @@ -1286,6 +1315,11 @@ int do_execve(char * filename,
15059         char __user *__user *envp,
15060         struct pt_regs * regs)
15061  {
15062 +#ifdef CONFIG_GRKERNSEC
15063 +       struct file *old_exec_file;
15064 +       struct acl_subject_label *old_acl;
15065 +       struct rlimit old_rlim[RLIM_NLIMITS];
15066 +#endif
15067         struct linux_binprm *bprm;
15068         struct file *file;
15069         struct files_struct *displaced;
15070 @@ -1305,6 +1339,20 @@ int do_execve(char * filename,
15071         if (IS_ERR(file))
15072                 goto out_kfree;
15073  
15074 +       gr_learn_resource(current, RLIMIT_NPROC, atomic_read(&current->user->processes), 1);
15075 +
15076 +       if (gr_handle_nproc()) {
15077 +               allow_write_access(file);
15078 +               fput(file);
15079 +               return -EAGAIN;
15080 +       }
15081 +
15082 +       if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) {
15083 +               allow_write_access(file);
15084 +               fput(file);
15085 +               return -EACCES;
15086 +       }
15087 +
15088         sched_exec();
15089  
15090         bprm->file = file;
15091 @@ -1344,9 +1392,39 @@ int do_execve(char * filename,
15092         if (retval < 0)
15093                 goto out;
15094  
15095 +       if (!gr_tpe_allow(file)) {
15096 +               retval = -EACCES;
15097 +               goto out;
15098 +       }
15099 +
15100 +       if (gr_check_crash_exec(file)) {
15101 +               retval = -EACCES;
15102 +               goto out;
15103 +       }
15104 +
15105 +       gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt);
15106 +
15107 +       gr_handle_exec_args(bprm, argv);
15108 +
15109 +#ifdef CONFIG_GRKERNSEC
15110 +       old_acl = current->acl;
15111 +       memcpy(old_rlim, current->signal->rlim, sizeof(old_rlim));
15112 +       old_exec_file = current->exec_file;
15113 +       get_file(file);
15114 +       current->exec_file = file;
15115 +#endif
15116 +
15117 +       retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt);
15118 +       if (retval < 0)
15119 +               goto out_fail;
15120 +
15121         current->flags &= ~PF_KTHREAD;
15122         retval = search_binary_handler(bprm,regs);
15123         if (retval >= 0) {
15124 +#ifdef CONFIG_GRKERNSEC
15125 +               if (old_exec_file)
15126 +                       fput(old_exec_file);
15127 +#endif
15128                 /* execve success */
15129                 security_bprm_free(bprm);
15130                 acct_update_integrals(current);
15131 @@ -1356,6 +1434,14 @@ int do_execve(char * filename,
15132                 return retval;
15133         }
15134  
15135 +out_fail:
15136 +#ifdef CONFIG_GRKERNSEC
15137 +       current->acl = old_acl;
15138 +       memcpy(current->signal->rlim, old_rlim, sizeof(old_rlim));
15139 +       fput(current->exec_file);
15140 +       current->exec_file = old_exec_file;
15141 +#endif
15142 +
15143  out:
15144         if (bprm->security)
15145                 security_bprm_free(bprm);
15146 @@ -1519,6 +1605,125 @@ out:
15147         return ispipe;
15148  }
15149  
15150 +int pax_check_flags(unsigned long *flags)
15151 +{
15152 +       int retval = 0;
15153 +
15154 +#if !defined(CONFIG_X86_32) || !defined(CONFIG_PAX_SEGMEXEC)
15155 +       if (*flags & MF_PAX_SEGMEXEC)
15156 +       {
15157 +               *flags &= ~MF_PAX_SEGMEXEC;
15158 +               retval = -EINVAL;
15159 +       }
15160 +#endif
15161 +
15162 +       if ((*flags & MF_PAX_PAGEEXEC)
15163 +
15164 +#ifdef CONFIG_PAX_PAGEEXEC
15165 +           &&  (*flags & MF_PAX_SEGMEXEC)
15166 +#endif
15167 +
15168 +          )
15169 +       {
15170 +               *flags &= ~MF_PAX_PAGEEXEC;
15171 +               retval = -EINVAL;
15172 +       }
15173 +
15174 +       if ((*flags & MF_PAX_MPROTECT)
15175 +
15176 +#ifdef CONFIG_PAX_MPROTECT
15177 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15178 +#endif
15179 +
15180 +          )
15181 +       {
15182 +               *flags &= ~MF_PAX_MPROTECT;
15183 +               retval = -EINVAL;
15184 +       }
15185 +
15186 +       if ((*flags & MF_PAX_EMUTRAMP)
15187 +
15188 +#ifdef CONFIG_PAX_EMUTRAMP
15189 +           && !(*flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC))
15190 +#endif
15191 +
15192 +          )
15193 +       {
15194 +               *flags &= ~MF_PAX_EMUTRAMP;
15195 +               retval = -EINVAL;
15196 +       }
15197 +
15198 +       return retval;
15199 +}
15200 +
15201 +EXPORT_SYMBOL(pax_check_flags);
15202 +
15203 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
15204 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp)
15205 +{
15206 +       struct task_struct *tsk = current;
15207 +       struct mm_struct *mm = current->mm;
15208 +       char *buffer_exec = (char *)__get_free_page(GFP_KERNEL);
15209 +       char *buffer_fault = (char *)__get_free_page(GFP_KERNEL);
15210 +       char *path_exec = NULL;
15211 +       char *path_fault = NULL;
15212 +       unsigned long start = 0UL, end = 0UL, offset = 0UL;
15213 +
15214 +       if (buffer_exec && buffer_fault) {
15215 +               struct vm_area_struct *vma, *vma_exec = NULL, *vma_fault = NULL;
15216 +
15217 +               down_read(&mm->mmap_sem);
15218 +               vma = mm->mmap;
15219 +               while (vma && (!vma_exec || !vma_fault)) {
15220 +                       if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
15221 +                               vma_exec = vma;
15222 +                       if (vma->vm_start <= (unsigned long)pc && (unsigned long)pc < vma->vm_end)
15223 +                               vma_fault = vma;
15224 +                       vma = vma->vm_next;
15225 +               }
15226 +               if (vma_exec) {
15227 +                       path_exec = d_path(&vma_exec->vm_file->f_path, buffer_exec, PAGE_SIZE);
15228 +                       if (IS_ERR(path_exec))
15229 +                               path_exec = "<path too long>";
15230 +               }
15231 +               if (vma_fault) {
15232 +                       start = vma_fault->vm_start;
15233 +                       end = vma_fault->vm_end;
15234 +                       offset = vma_fault->vm_pgoff << PAGE_SHIFT;
15235 +                       if (vma_fault->vm_file) {
15236 +                               path_fault = d_path(&vma_fault->vm_file->f_path, buffer_fault, PAGE_SIZE);
15237 +                               if (IS_ERR(path_fault))
15238 +                                       path_fault = "<path too long>";
15239 +                       } else
15240 +                               path_fault = "<anonymous mapping>";
15241 +               }
15242 +               up_read(&mm->mmap_sem);
15243 +       }
15244 +       if (tsk->signal->curr_ip)
15245 +               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);
15246 +       else
15247 +               printk(KERN_ERR "PAX: execution attempt in: %s, %08lx-%08lx %08lx\n", path_fault, start, end, offset);
15248 +       printk(KERN_ERR "PAX: terminating task: %s(%s):%d, uid/euid: %u/%u, "
15249 +                       "PC: %p, SP: %p\n", path_exec, tsk->comm, task_pid_nr(tsk),
15250 +                       tsk->uid, tsk->euid, pc, sp);
15251 +       free_page((unsigned long)buffer_exec);
15252 +       free_page((unsigned long)buffer_fault);
15253 +       pax_report_insns(pc, sp);
15254 +       do_coredump(SIGKILL, SIGKILL, regs);
15255 +}
15256 +#endif
15257 +
15258 +#ifdef CONFIG_PAX_REFCOUNT
15259 +void pax_report_refcount_overflow(struct pt_regs *regs)
15260 +{
15261 +       printk(KERN_ERR "PAX: refcount overflow detected in: %s:%d, uid/euid: %u/%u\n",
15262 +                        current->comm, task_pid_nr(current), current->uid, current->euid);
15263 +       print_symbol(KERN_ERR "PAX: refcount overflow occured at: %s\n", instruction_pointer(regs));
15264 +       show_registers(regs);
15265 +       force_sig_specific(SIGKILL, current);
15266 +}
15267 +#endif
15268 +
15269  static int zap_process(struct task_struct *start)
15270  {
15271         struct task_struct *t;
15272 @@ -1765,6 +1970,10 @@ int do_coredump(long signr, int exit_cod
15273          */
15274         clear_thread_flag(TIF_SIGPENDING);
15275  
15276 +       if (signr == SIGKILL || signr == SIGILL)
15277 +               gr_handle_brute_attach(current);
15278 +       gr_learn_resource(current, RLIMIT_CORE, binfmt->min_coredump, 1);
15279 +
15280         /*
15281          * lock_kernel() because format_corename() is controlled by sysctl, which
15282          * uses lock_kernel()
15283 @@ -1785,6 +1994,8 @@ int do_coredump(long signr, int exit_cod
15284  
15285         if (ispipe) {
15286                 helper_argv = argv_split(GFP_KERNEL, corename+1, &helper_argc);
15287 +               if (!helper_argv)
15288 +                       goto fail_unlock;
15289                 /* Terminate the string before the first option */
15290                 delimit = strchr(corename, ' ');
15291                 if (delimit)
15292 diff -urNp linux-2.6.27.10/fs/ext2/balloc.c linux-2.6.27.10/fs/ext2/balloc.c
15293 --- linux-2.6.27.10/fs/ext2/balloc.c    2008-12-10 22:35:37.000000000 -0500
15294 +++ linux-2.6.27.10/fs/ext2/balloc.c    2008-12-10 22:35:46.000000000 -0500
15295 @@ -1192,7 +1192,7 @@ static int ext2_has_free_blocks(struct e
15296  
15297         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15298         root_blocks = le32_to_cpu(sbi->s_es->s_r_blocks_count);
15299 -       if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
15300 +       if (free_blocks < root_blocks + 1 && !capable_nolog(CAP_SYS_RESOURCE) &&
15301                 sbi->s_resuid != current->fsuid &&
15302                 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
15303                 return 0;
15304 diff -urNp linux-2.6.27.10/fs/ext3/balloc.c linux-2.6.27.10/fs/ext3/balloc.c
15305 --- linux-2.6.27.10/fs/ext3/balloc.c    2008-12-10 22:35:37.000000000 -0500
15306 +++ linux-2.6.27.10/fs/ext3/balloc.c    2008-12-10 22:35:46.000000000 -0500
15307 @@ -1435,14 +1435,14 @@ static int ext3_has_free_blocks(struct s
15308         DLIMIT_ADJUST_BLOCK(sb, dx_current_tag(), &free_blocks, &root_blocks);
15309  
15310         cond = (free_blocks < root_blocks + 1 &&
15311 -               !capable(CAP_SYS_RESOURCE) &&
15312 +               !capable_nolog(CAP_SYS_RESOURCE) &&
15313                 sbi->s_resuid != current->fsuid &&
15314                 (sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid)));
15315  
15316         vxdprintk(VXD_CBIT(dlim, 3),
15317                 "ext3_has_free_blocks(%p): %llu<%llu+1, %c, %u!=%u r=%d",
15318                 sb, free_blocks, root_blocks,
15319 -               !capable(CAP_SYS_RESOURCE)?'1':'0',
15320 +               !capable_nolog(CAP_SYS_RESOURCE)?'1':'0',
15321                 sbi->s_resuid, current->fsuid, cond?0:1);
15322  
15323         return (cond ? 0 : 1);
15324 diff -urNp linux-2.6.27.10/fs/ext3/namei.c linux-2.6.27.10/fs/ext3/namei.c
15325 --- linux-2.6.27.10/fs/ext3/namei.c     2008-11-07 12:55:34.000000000 -0500
15326 +++ linux-2.6.27.10/fs/ext3/namei.c     2008-11-18 03:38:45.000000000 -0500
15327 @@ -1173,9 +1173,9 @@ static struct ext3_dir_entry_2 *do_split
15328         u32 hash2;
15329         struct dx_map_entry *map;
15330         char *data1 = (*bh)->b_data, *data2;
15331 -       unsigned split, move, size, i;
15332 +       unsigned split, move, size;
15333         struct ext3_dir_entry_2 *de = NULL, *de2;
15334 -       int     err = 0;
15335 +       int     i, err = 0;
15336  
15337         bh2 = ext3_append (handle, dir, &newblock, &err);
15338         if (!(bh2)) {
15339 diff -urNp linux-2.6.27.10/fs/ext3/xattr.c linux-2.6.27.10/fs/ext3/xattr.c
15340 --- linux-2.6.27.10/fs/ext3/xattr.c     2008-11-07 12:55:34.000000000 -0500
15341 +++ linux-2.6.27.10/fs/ext3/xattr.c     2008-11-18 03:38:45.000000000 -0500
15342 @@ -89,8 +89,8 @@
15343                 printk("\n"); \
15344         } while (0)
15345  #else
15346 -# define ea_idebug(f...)
15347 -# define ea_bdebug(f...)
15348 +# define ea_idebug(f...) do {} while (0)
15349 +# define ea_bdebug(f...) do {} while (0)
15350  #endif
15351  
15352  static void ext3_xattr_cache_insert(struct buffer_head *);
15353 diff -urNp linux-2.6.27.10/fs/ext4/balloc.c linux-2.6.27.10/fs/ext4/balloc.c
15354 --- linux-2.6.27.10/fs/ext4/balloc.c    2008-11-07 12:55:34.000000000 -0500
15355 +++ linux-2.6.27.10/fs/ext4/balloc.c    2008-11-18 03:38:45.000000000 -0500
15356 @@ -1617,7 +1617,7 @@ ext4_fsblk_t ext4_has_free_blocks(struct
15357  
15358         free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
15359  
15360 -       if (!capable(CAP_SYS_RESOURCE) &&
15361 +       if (!capable_nolog(CAP_SYS_RESOURCE) &&
15362                 sbi->s_resuid != current->fsuid &&
15363                 (sbi->s_resgid == 0 || !in_group_p(sbi->s_resgid)))
15364                 root_blocks = ext4_r_blocks_count(sbi->s_es);
15365 diff -urNp linux-2.6.27.10/fs/ext4/namei.c linux-2.6.27.10/fs/ext4/namei.c
15366 --- linux-2.6.27.10/fs/ext4/namei.c     2008-11-07 12:55:34.000000000 -0500
15367 +++ linux-2.6.27.10/fs/ext4/namei.c     2008-11-18 03:38:45.000000000 -0500
15368 @@ -1176,9 +1176,9 @@ static struct ext4_dir_entry_2 *do_split
15369         u32 hash2;
15370         struct dx_map_entry *map;
15371         char *data1 = (*bh)->b_data, *data2;
15372 -       unsigned split, move, size, i;
15373 +       unsigned split, move, size;
15374         struct ext4_dir_entry_2 *de = NULL, *de2;
15375 -       int     err = 0;
15376 +       int     i, err = 0;
15377  
15378         bh2 = ext4_append (handle, dir, &newblock, &err);
15379         if (!(bh2)) {
15380 diff -urNp linux-2.6.27.10/fs/fcntl.c linux-2.6.27.10/fs/fcntl.c
15381 --- linux-2.6.27.10/fs/fcntl.c  2008-12-21 01:16:51.000000000 -0500
15382 +++ linux-2.6.27.10/fs/fcntl.c  2008-12-21 01:14:31.000000000 -0500
15383 @@ -19,6 +19,7 @@
15384  #include <linux/pid_namespace.h>
15385  #include <linux/smp_lock.h>
15386  #include <linux/vs_limit.h>
15387 +#include <linux/grsecurity.h>
15388  
15389  #include <asm/poll.h>
15390  #include <asm/siginfo.h>
15391 @@ -266,6 +267,7 @@ static long do_fcntl(int fd, unsigned in
15392         switch (cmd) {
15393         case F_DUPFD:
15394         case F_DUPFD_CLOEXEC:
15395 +               gr_learn_resource(current, RLIMIT_NOFILE, arg, 0);
15396                 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15397                         break;
15398                 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
15399 @@ -410,7 +412,8 @@ static inline int sigio_perm(struct task
15400         return (((fown->euid == 0) ||
15401                  (fown->euid == p->suid) || (fown->euid == p->uid) ||
15402                  (fown->uid == p->suid) || (fown->uid == p->uid)) &&
15403 -               !security_file_send_sigiotask(p, fown, sig));
15404 +               !security_file_send_sigiotask(p, fown, sig) &&
15405 +               !gr_check_protected_task(p) && !gr_pid_is_chrooted(p));
15406  }
15407  
15408  static void send_sigio_to_task(struct task_struct *p,
15409 diff -urNp linux-2.6.27.10/fs/file.c linux-2.6.27.10/fs/file.c
15410 --- linux-2.6.27.10/fs/file.c   2008-11-07 12:55:34.000000000 -0500
15411 +++ linux-2.6.27.10/fs/file.c   2008-11-18 03:38:45.000000000 -0500
15412 @@ -19,6 +19,7 @@
15413  #include <linux/rcupdate.h>
15414  #include <linux/workqueue.h>
15415  #include <linux/vs_limit.h>
15416 +#include <linux/grsecurity.h>
15417  
15418  struct fdtable_defer {
15419         spinlock_t lock;
15420 @@ -256,6 +257,8 @@ int expand_files(struct files_struct *fi
15421          * N.B. For clone tasks sharing a files structure, this test
15422          * will limit the total number of files that can be opened.
15423          */
15424 +
15425 +       gr_learn_resource(current, RLIMIT_NOFILE, nr, 0);
15426         if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
15427                 return -EMFILE;
15428  
15429 diff -urNp linux-2.6.27.10/fs/fuse/control.c linux-2.6.27.10/fs/fuse/control.c
15430 --- linux-2.6.27.10/fs/fuse/control.c   2008-11-07 12:55:34.000000000 -0500
15431 +++ linux-2.6.27.10/fs/fuse/control.c   2008-11-18 03:38:45.000000000 -0500
15432 @@ -159,7 +159,7 @@ void fuse_ctl_remove_conn(struct fuse_co
15433  
15434  static int fuse_ctl_fill_super(struct super_block *sb, void *data, int silent)
15435  {
15436 -       struct tree_descr empty_descr = {""};
15437 +       struct tree_descr empty_descr = {"", NULL, 0};
15438         struct fuse_conn *fc;
15439         int err;
15440  
15441 diff -urNp linux-2.6.27.10/fs/fuse/dir.c linux-2.6.27.10/fs/fuse/dir.c
15442 --- linux-2.6.27.10/fs/fuse/dir.c       2008-11-07 12:55:34.000000000 -0500
15443 +++ linux-2.6.27.10/fs/fuse/dir.c       2008-11-18 03:38:45.000000000 -0500
15444 @@ -1072,7 +1072,7 @@ static char *read_link(struct dentry *de
15445         return link;
15446  }
15447  
15448 -static void free_link(char *link)
15449 +static void free_link(const char *link)
15450  {
15451         if (!IS_ERR(link))
15452                 free_page((unsigned long) link);
15453 diff -urNp linux-2.6.27.10/fs/hfs/inode.c linux-2.6.27.10/fs/hfs/inode.c
15454 --- linux-2.6.27.10/fs/hfs/inode.c      2008-11-07 12:55:34.000000000 -0500
15455 +++ linux-2.6.27.10/fs/hfs/inode.c      2008-11-18 03:38:45.000000000 -0500
15456 @@ -419,7 +419,7 @@ int hfs_write_inode(struct inode *inode,
15457  
15458         if (S_ISDIR(main_inode->i_mode)) {
15459                 if (fd.entrylength < sizeof(struct hfs_cat_dir))
15460 -                       /* panic? */;
15461 +                       {/* panic? */}
15462                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15463                            sizeof(struct hfs_cat_dir));
15464                 if (rec.type != HFS_CDR_DIR ||
15465 @@ -440,7 +440,7 @@ int hfs_write_inode(struct inode *inode,
15466                                 sizeof(struct hfs_cat_file));
15467         } else {
15468                 if (fd.entrylength < sizeof(struct hfs_cat_file))
15469 -                       /* panic? */;
15470 +                       {/* panic? */}
15471                 hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
15472                            sizeof(struct hfs_cat_file));
15473                 if (rec.type != HFS_CDR_FIL ||
15474 diff -urNp linux-2.6.27.10/fs/hfsplus/inode.c linux-2.6.27.10/fs/hfsplus/inode.c
15475 --- linux-2.6.27.10/fs/hfsplus/inode.c  2008-11-07 12:55:34.000000000 -0500
15476 +++ linux-2.6.27.10/fs/hfsplus/inode.c  2008-11-18 03:38:45.000000000 -0500
15477 @@ -417,7 +417,7 @@ int hfsplus_cat_read_inode(struct inode 
15478                 struct hfsplus_cat_folder *folder = &entry.folder;
15479  
15480                 if (fd->entrylength < sizeof(struct hfsplus_cat_folder))
15481 -                       /* panic? */;
15482 +                       {/* panic? */}
15483                 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15484                                         sizeof(struct hfsplus_cat_folder));
15485                 hfsplus_get_perms(inode, &folder->permissions, 1);
15486 @@ -434,7 +434,7 @@ int hfsplus_cat_read_inode(struct inode 
15487                 struct hfsplus_cat_file *file = &entry.file;
15488  
15489                 if (fd->entrylength < sizeof(struct hfsplus_cat_file))
15490 -                       /* panic? */;
15491 +                       {/* panic? */}
15492                 hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
15493                                         sizeof(struct hfsplus_cat_file));
15494  
15495 @@ -490,7 +490,7 @@ int hfsplus_cat_write_inode(struct inode
15496                 struct hfsplus_cat_folder *folder = &entry.folder;
15497  
15498                 if (fd.entrylength < sizeof(struct hfsplus_cat_folder))
15499 -                       /* panic? */;
15500 +                       {/* panic? */}
15501                 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15502                                         sizeof(struct hfsplus_cat_folder));
15503                 /* simple node checks? */
15504 @@ -512,7 +512,7 @@ int hfsplus_cat_write_inode(struct inode
15505                 struct hfsplus_cat_file *file = &entry.file;
15506  
15507                 if (fd.entrylength < sizeof(struct hfsplus_cat_file))
15508 -                       /* panic? */;
15509 +                       {/* panic? */}
15510                 hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
15511                                         sizeof(struct hfsplus_cat_file));
15512                 hfsplus_inode_write_fork(inode, &file->data_fork);
15513 diff -urNp linux-2.6.27.10/fs/jffs2/debug.h linux-2.6.27.10/fs/jffs2/debug.h
15514 --- linux-2.6.27.10/fs/jffs2/debug.h    2008-11-07 12:55:34.000000000 -0500
15515 +++ linux-2.6.27.10/fs/jffs2/debug.h    2008-11-18 03:38:45.000000000 -0500
15516 @@ -52,13 +52,13 @@
15517  #if CONFIG_JFFS2_FS_DEBUG > 0
15518  #define D1(x) x
15519  #else
15520 -#define D1(x)
15521 +#define D1(x) do {} while (0);
15522  #endif
15523  
15524  #if CONFIG_JFFS2_FS_DEBUG > 1
15525  #define D2(x) x
15526  #else
15527 -#define D2(x)
15528 +#define D2(x) do {} while (0);
15529  #endif
15530  
15531  /* The prefixes of JFFS2 messages */
15532 @@ -114,73 +114,73 @@
15533  #ifdef JFFS2_DBG_READINODE_MESSAGES
15534  #define dbg_readinode(fmt, ...)        JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15535  #else
15536 -#define dbg_readinode(fmt, ...)
15537 +#define dbg_readinode(fmt, ...)        do {} while (0)
15538  #endif
15539  #ifdef JFFS2_DBG_READINODE2_MESSAGES
15540  #define dbg_readinode2(fmt, ...)       JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15541  #else
15542 -#define dbg_readinode2(fmt, ...)
15543 +#define dbg_readinode2(fmt, ...)       do {} while (0)
15544  #endif
15545  
15546  /* Fragtree build debugging messages */
15547  #ifdef JFFS2_DBG_FRAGTREE_MESSAGES
15548  #define dbg_fragtree(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15549  #else
15550 -#define dbg_fragtree(fmt, ...)
15551 +#define dbg_fragtree(fmt, ...) do {} while (0)
15552  #endif
15553  #ifdef JFFS2_DBG_FRAGTREE2_MESSAGES
15554  #define dbg_fragtree2(fmt, ...)        JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15555  #else
15556 -#define dbg_fragtree2(fmt, ...)
15557 +#define dbg_fragtree2(fmt, ...)        do {} while (0)
15558  #endif
15559  
15560  /* Directory entry list manilulation debugging messages */
15561  #ifdef JFFS2_DBG_DENTLIST_MESSAGES
15562  #define dbg_dentlist(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15563  #else
15564 -#define dbg_dentlist(fmt, ...)
15565 +#define dbg_dentlist(fmt, ...) do {} while (0)
15566  #endif
15567  
15568  /* Print the messages about manipulating node_refs */
15569  #ifdef JFFS2_DBG_NODEREF_MESSAGES
15570  #define dbg_noderef(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15571  #else
15572 -#define dbg_noderef(fmt, ...)
15573 +#define dbg_noderef(fmt, ...)  do {} while (0)
15574  #endif
15575  
15576  /* Manipulations with the list of inodes (JFFS2 inocache) */
15577  #ifdef JFFS2_DBG_INOCACHE_MESSAGES
15578  #define dbg_inocache(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15579  #else
15580 -#define dbg_inocache(fmt, ...)
15581 +#define dbg_inocache(fmt, ...) do {} while (0)
15582  #endif
15583  
15584  /* Summary debugging messages */
15585  #ifdef JFFS2_DBG_SUMMARY_MESSAGES
15586  #define dbg_summary(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15587  #else
15588 -#define dbg_summary(fmt, ...)
15589 +#define dbg_summary(fmt, ...)  do {} while (0)
15590  #endif
15591  
15592  /* File system build messages */
15593  #ifdef JFFS2_DBG_FSBUILD_MESSAGES
15594  #define dbg_fsbuild(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15595  #else
15596 -#define dbg_fsbuild(fmt, ...)
15597 +#define dbg_fsbuild(fmt, ...)  do {} while (0)
15598  #endif
15599  
15600  /* Watch the object allocations */
15601  #ifdef JFFS2_DBG_MEMALLOC_MESSAGES
15602  #define dbg_memalloc(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15603  #else
15604 -#define dbg_memalloc(fmt, ...)
15605 +#define dbg_memalloc(fmt, ...) do {} while (0)
15606  #endif
15607  
15608  /* Watch the XATTR subsystem */
15609  #ifdef JFFS2_DBG_XATTR_MESSAGES
15610  #define dbg_xattr(fmt, ...)  JFFS2_DEBUG(fmt, ##__VA_ARGS__)
15611  #else
15612 -#define dbg_xattr(fmt, ...)
15613 +#define dbg_xattr(fmt, ...)    do {} while (0)
15614  #endif 
15615  
15616  /* "Sanity" checks */
15617 diff -urNp linux-2.6.27.10/fs/jffs2/erase.c linux-2.6.27.10/fs/jffs2/erase.c
15618 --- linux-2.6.27.10/fs/jffs2/erase.c    2008-11-07 12:55:34.000000000 -0500
15619 +++ linux-2.6.27.10/fs/jffs2/erase.c    2008-11-18 03:38:45.000000000 -0500
15620 @@ -431,7 +431,8 @@ static void jffs2_mark_erased_block(stru
15621                 struct jffs2_unknown_node marker = {
15622                         .magic =        cpu_to_je16(JFFS2_MAGIC_BITMASK),
15623                         .nodetype =     cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15624 -                       .totlen =       cpu_to_je32(c->cleanmarker_size)
15625 +                       .totlen =       cpu_to_je32(c->cleanmarker_size),
15626 +                       .hdr_crc =      cpu_to_je32(0)
15627                 };
15628  
15629                 jffs2_prealloc_raw_node_refs(c, jeb, 1);
15630 diff -urNp linux-2.6.27.10/fs/jffs2/summary.h linux-2.6.27.10/fs/jffs2/summary.h
15631 --- linux-2.6.27.10/fs/jffs2/summary.h  2008-11-07 12:55:34.000000000 -0500
15632 +++ linux-2.6.27.10/fs/jffs2/summary.h  2008-11-18 03:38:45.000000000 -0500
15633 @@ -194,18 +194,18 @@ int jffs2_sum_scan_sumnode(struct jffs2_
15634  
15635  #define jffs2_sum_active() (0)
15636  #define jffs2_sum_init(a) (0)
15637 -#define jffs2_sum_exit(a)
15638 -#define jffs2_sum_disable_collecting(a)
15639 +#define jffs2_sum_exit(a) do {} while (0)
15640 +#define jffs2_sum_disable_collecting(a) do {} while (0)
15641  #define jffs2_sum_is_disabled(a) (0)
15642 -#define jffs2_sum_reset_collected(a)
15643 +#define jffs2_sum_reset_collected(a) do {} while (0)
15644  #define jffs2_sum_add_kvec(a,b,c,d) (0)
15645 -#define jffs2_sum_move_collected(a,b)
15646 +#define jffs2_sum_move_collected(a,b) do {} while (0)
15647  #define jffs2_sum_write_sumnode(a) (0)
15648 -#define jffs2_sum_add_padding_mem(a,b)
15649 -#define jffs2_sum_add_inode_mem(a,b,c)
15650 -#define jffs2_sum_add_dirent_mem(a,b,c)
15651 -#define jffs2_sum_add_xattr_mem(a,b,c)
15652 -#define jffs2_sum_add_xref_mem(a,b,c)
15653 +#define jffs2_sum_add_padding_mem(a,b) do {} while (0)
15654 +#define jffs2_sum_add_inode_mem(a,b,c) do {} while (0)
15655 +#define jffs2_sum_add_dirent_mem(a,b,c) do {} while (0)
15656 +#define jffs2_sum_add_xattr_mem(a,b,c) do {} while (0)
15657 +#define jffs2_sum_add_xref_mem(a,b,c) do {} while (0)
15658  #define jffs2_sum_scan_sumnode(a,b,c,d,e) (0)
15659  
15660  #endif /* CONFIG_JFFS2_SUMMARY */
15661 diff -urNp linux-2.6.27.10/fs/jffs2/wbuf.c linux-2.6.27.10/fs/jffs2/wbuf.c
15662 --- linux-2.6.27.10/fs/jffs2/wbuf.c     2008-11-07 12:55:34.000000000 -0500
15663 +++ linux-2.6.27.10/fs/jffs2/wbuf.c     2008-11-18 03:38:45.000000000 -0500
15664 @@ -1015,7 +1015,8 @@ static const struct jffs2_unknown_node o
15665  {
15666         .magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
15667         .nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
15668 -       .totlen = constant_cpu_to_je32(8)
15669 +       .totlen = constant_cpu_to_je32(8),
15670 +       .hdr_crc = constant_cpu_to_je32(0)
15671  };
15672  
15673  /*
15674 diff -urNp linux-2.6.27.10/fs/locks.c linux-2.6.27.10/fs/locks.c
15675 --- linux-2.6.27.10/fs/locks.c  2008-11-07 12:55:34.000000000 -0500
15676 +++ linux-2.6.27.10/fs/locks.c  2008-11-18 03:38:45.000000000 -0500
15677 @@ -2005,16 +2005,16 @@ void locks_remove_flock(struct file *fil
15678                 return;
15679  
15680         if (filp->f_op && filp->f_op->flock) {
15681 -               struct file_lock fl = {
15682 +               struct file_lock flock = {
15683                         .fl_pid = current->tgid,
15684                         .fl_file = filp,
15685                         .fl_flags = FL_FLOCK,
15686                         .fl_type = F_UNLCK,
15687                         .fl_end = OFFSET_MAX,
15688                 };
15689 -               filp->f_op->flock(filp, F_SETLKW, &fl);
15690 -               if (fl.fl_ops && fl.fl_ops->fl_release_private)
15691 -                       fl.fl_ops->fl_release_private(&fl);
15692 +               filp->f_op->flock(filp, F_SETLKW, &flock);
15693 +               if (flock.fl_ops && flock.fl_ops->fl_release_private)
15694 +                       flock.fl_ops->fl_release_private(&flock);
15695         }
15696  
15697         lock_kernel();
15698 diff -urNp linux-2.6.27.10/fs/namei.c linux-2.6.27.10/fs/namei.c
15699 --- linux-2.6.27.10/fs/namei.c  2008-11-07 12:55:34.000000000 -0500
15700 +++ linux-2.6.27.10/fs/namei.c  2008-11-18 04:47:57.000000000 -0500
15701 @@ -31,6 +31,8 @@
15702  #include <linux/vs_device.h>
15703  #include <linux/vs_context.h>
15704  #include <linux/pid_namespace.h>
15705 +#include <linux/grsecurity.h>
15706 +
15707  #include <asm/uaccess.h>
15708  
15709  #define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
15710 @@ -646,7 +648,7 @@ static __always_inline int __do_follow_l
15711         cookie = dentry->d_inode->i_op->follow_link(dentry, nd);
15712         error = PTR_ERR(cookie);
15713         if (!IS_ERR(cookie)) {
15714 -               char *s = nd_get_link(nd);
15715 +               const char *s = nd_get_link(nd);
15716                 error = 0;
15717                 if (s)
15718                         error = __vfs_follow_link(nd, s);
15719 @@ -677,6 +679,13 @@ static inline int do_follow_link(struct 
15720         err = security_inode_follow_link(path->dentry, nd);
15721         if (err)
15722                 goto loop;
15723 +
15724 +       if (gr_handle_follow_link(path->dentry->d_parent->d_inode,
15725 +                                 path->dentry->d_inode, path->dentry, nd->path.mnt)) {
15726 +               err = -EACCES;
15727 +               goto loop;
15728 +       }
15729 +
15730         current->link_count++;
15731         current->total_link_count++;
15732         nd->depth++;
15733 @@ -1025,11 +1034,18 @@ return_reval:
15734                                 break;
15735                 }
15736  return_base:
15737 +               if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) {
15738 +                       path_put(&nd->path);
15739 +                       return -ENOENT;
15740 +               }
15741                 return 0;
15742  out_dput:
15743                 path_put_conditional(&next, nd);
15744                 break;
15745         }
15746 +       if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt))
15747 +               err = -ENOENT;
15748 +
15749         path_put(&nd->path);
15750  return_err:
15751         return err;
15752 @@ -1613,9 +1629,17 @@ static int __open_namei_create(struct na
15753         int error;
15754         struct dentry *dir = nd->path.dentry;
15755  
15756 +       if (!gr_acl_handle_creat(path->dentry, nd->path.dentry, nd->path.mnt, flag, mode)) {
15757 +               error = -EACCES;
15758 +               goto out_unlock_dput;
15759 +       }
15760 +
15761         if (!IS_POSIXACL(dir->d_inode))
15762                 mode &= ~current->fs->umask;
15763         error = vfs_create(dir->d_inode, path->dentry, mode, nd);
15764 +       if (!error)
15765 +               gr_handle_create(path->dentry, nd->path.mnt);
15766 +out_unlock_dput:
15767         mutex_unlock(&dir->d_inode->i_mutex);
15768         dput(nd->path.dentry);
15769         nd->path.dentry = path->dentry;
15770 @@ -1696,6 +1720,17 @@ struct file *do_filp_open(int dfd, const
15771                                          &nd, flag);
15772                 if (error)
15773                         return ERR_PTR(error);
15774 +
15775 +               if (gr_handle_rawio(nd.path.dentry->d_inode)) {
15776 +                       error = -EPERM;
15777 +                       goto exit;
15778 +               }
15779 +
15780 +               if (!gr_acl_handle_open(nd.path.dentry, nd.path.mnt, flag)) {
15781 +                       error = -EACCES;
15782 +                       goto exit;
15783 +               }
15784 +
15785                 goto ok;
15786         }
15787  
15788 @@ -1759,6 +1794,20 @@ do_last:
15789         /*
15790          * It already exists.
15791          */
15792 +
15793 +       if (gr_handle_rawio(path.dentry->d_inode)) {
15794 +               error = -EPERM;
15795 +               goto exit_mutex_unlock;
15796 +       }
15797 +       if (!gr_acl_handle_open(path.dentry, nd.path.mnt, flag)) {
15798 +               error = -EACCES;
15799 +               goto exit_mutex_unlock;
15800 +       }
15801 +       if (gr_handle_fifo(path.dentry, nd.path.mnt, dir, flag, acc_mode)) {
15802 +               error = -EACCES;
15803 +               goto exit_mutex_unlock;
15804 +       }
15805 +
15806         mutex_unlock(&dir->d_inode->i_mutex);
15807         audit_inode(pathname, path.dentry);
15808  
15809 @@ -1843,6 +1892,13 @@ do_link:
15810         error = security_inode_follow_link(path.dentry, &nd);
15811         if (error)
15812                 goto exit_dput;
15813 +
15814 +       if (gr_handle_follow_link(path.dentry->d_parent->d_inode, path.dentry->d_inode,
15815 +                                 path.dentry, nd.path.mnt)) {
15816 +               error = -EACCES;
15817 +               goto exit_dput;
15818 +       }
15819 +
15820         error = __do_follow_link(&path, &nd);
15821         if (error) {
15822                 /* Does someone understand code flow here? Or it is only
15823 @@ -2015,9 +2071,21 @@ asmlinkage long sys_mknodat(int dfd, con
15824         error = may_mknod(mode);
15825         if (error)
15826                 goto out_dput;
15827 +
15828 +       if (gr_handle_chroot_mknod(dentry, nd.path.mnt, mode)) {
15829 +               error = -EPERM;
15830 +               goto out_dput;
15831 +       }
15832 +
15833 +       if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
15834 +               error = -EACCES;
15835 +               goto out_dput;
15836 +       }
15837 +
15838         error = mnt_want_write(nd.path.mnt);
15839         if (error)
15840                 goto out_dput;
15841 +
15842         switch (mode & S_IFMT) {
15843                 case 0: case S_IFREG:
15844                         error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
15845 @@ -2031,6 +2099,9 @@ asmlinkage long sys_mknodat(int dfd, con
15846                         break;
15847         }
15848         mnt_drop_write(nd.path.mnt);
15849 +
15850 +       if (!error)
15851 +               gr_handle_create(dentry, nd.path.mnt);
15852  out_dput:
15853         dput(dentry);
15854  out_unlock:
15855 @@ -2084,6 +2155,11 @@ asmlinkage long sys_mkdirat(int dfd, con
15856         if (IS_ERR(dentry))
15857                 goto out_unlock;
15858  
15859 +       if (!gr_acl_handle_mkdir(dentry, nd.path.dentry, nd.path.mnt)) {
15860 +               error = -EACCES;
15861 +               goto out_dput;
15862 +       }
15863 +
15864         if (!IS_POSIXACL(nd.path.dentry->d_inode))
15865                 mode &= ~current->fs->umask;
15866         error = mnt_want_write(nd.path.mnt);
15867 @@ -2091,6 +2167,10 @@ asmlinkage long sys_mkdirat(int dfd, con
15868                 goto out_dput;
15869         error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
15870         mnt_drop_write(nd.path.mnt);
15871 +
15872 +       if (!error)
15873 +               gr_handle_create(dentry, nd.path.mnt);
15874 +
15875  out_dput:
15876         dput(dentry);
15877  out_unlock:
15878 @@ -2172,6 +2252,8 @@ static long do_rmdir(int dfd, const char
15879         char * name;
15880         struct dentry *dentry;
15881         struct nameidata nd;
15882 +       ino_t saved_ino = 0;
15883 +       dev_t saved_dev = 0;
15884  
15885         error = user_path_parent(dfd, pathname, &nd, &name);
15886         if (error)
15887 @@ -2193,11 +2275,26 @@ static long do_rmdir(int dfd, const char
15888         error = PTR_ERR(dentry);
15889         if (IS_ERR(dentry))
15890                 goto exit2;
15891 +
15892 +       if (dentry->d_inode != NULL) {
15893 +               if (dentry->d_inode->i_nlink <= 1) {
15894 +                       saved_ino = dentry->d_inode->i_ino;
15895 +                       saved_dev = dentry->d_inode->i_sb->s_dev;
15896 +               }
15897 +
15898 +               if (!gr_acl_handle_rmdir(dentry, nd.path.mnt)) {
15899 +                       error = -EACCES;
15900 +                       goto exit3;
15901 +               }
15902 +       }
15903 +
15904         error = mnt_want_write(nd.path.mnt);
15905         if (error)
15906                 goto exit3;
15907         error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
15908         mnt_drop_write(nd.path.mnt);
15909 +       if (!error && (saved_dev || saved_ino))
15910 +               gr_handle_delete(saved_ino, saved_dev);
15911  exit3:
15912         dput(dentry);
15913  exit2:
15914 @@ -2257,6 +2354,8 @@ static long do_unlinkat(int dfd, const c
15915         struct dentry *dentry;
15916         struct nameidata nd;
15917         struct inode *inode = NULL;
15918 +       ino_t saved_ino = 0;
15919 +       dev_t saved_dev = 0;
15920  
15921         error = user_path_parent(dfd, pathname, &nd, &name);
15922         if (error)
15923 @@ -2273,12 +2372,25 @@ static long do_unlinkat(int dfd, const c
15924                 if (nd.last.name[nd.last.len])
15925                         goto slashes;
15926                 inode = dentry->d_inode;
15927 -               if (inode)
15928 +               if (inode) {
15929 +                       if (inode->i_nlink <= 1) {
15930 +                               saved_ino = inode->i_ino;
15931 +                               saved_dev = inode->i_sb->s_dev;
15932 +                       }
15933 +
15934                         atomic_inc(&inode->i_count);
15935 +
15936 +                       if (!gr_acl_handle_unlink(dentry, nd.path.mnt)) {
15937 +                               error = -EACCES;
15938 +                               goto exit2;
15939 +                       }
15940 +               }
15941                 error = mnt_want_write(nd.path.mnt);
15942                 if (error)
15943                         goto exit2;
15944                 error = vfs_unlink(nd.path.dentry->d_inode, dentry);
15945 +               if (!error && (saved_ino || saved_dev))
15946 +                       gr_handle_delete(saved_ino, saved_dev);
15947                 mnt_drop_write(nd.path.mnt);
15948         exit2:
15949                 dput(dentry);
15950 @@ -2356,10 +2468,17 @@ asmlinkage long sys_symlinkat(const char
15951         if (IS_ERR(dentry))
15952                 goto out_unlock;
15953  
15954 +       if (!gr_acl_handle_symlink(dentry, nd.path.dentry, nd.path.mnt, from)) {
15955 +               error = -EACCES;
15956 +               goto out_dput;
15957 +       }
15958 +
15959         error = mnt_want_write(nd.path.mnt);
15960         if (error)
15961                 goto out_dput;
15962         error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
15963 +       if (!error)
15964 +               gr_handle_create(dentry, nd.path.mnt);
15965         mnt_drop_write(nd.path.mnt);
15966  out_dput:
15967         dput(dentry);
15968 @@ -2453,10 +2572,26 @@ asmlinkage long sys_linkat(int olddfd, c
15969         error = PTR_ERR(new_dentry);
15970         if (IS_ERR(new_dentry))
15971                 goto out_unlock;
15972 +
15973 +       if (gr_handle_hardlink(old_path.dentry, old_path.mnt,
15974 +                              old_path.dentry->d_inode,
15975 +                              old_path.dentry->d_inode->i_mode, to)) {
15976 +               error = -EACCES;
15977 +               goto out_dput;
15978 +       }
15979 +
15980 +       if (!gr_acl_handle_link(new_dentry, nd.path.dentry, nd.path.mnt,
15981 +                               old_path.dentry, old_path.mnt, to)) {
15982 +               error = -EACCES;
15983 +               goto out_dput;
15984 +       }
15985 +
15986         error = mnt_want_write(nd.path.mnt);
15987         if (error)
15988                 goto out_dput;
15989         error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
15990 +       if (!error)
15991 +               gr_handle_create(new_dentry, nd.path.mnt);
15992         mnt_drop_write(nd.path.mnt);
15993  out_dput:
15994         dput(new_dentry);
15995 @@ -2612,8 +2747,10 @@ int vfs_rename(struct inode *old_dir, st
15996                 error = vfs_rename_dir(old_dir,old_dentry,new_dir,new_dentry);
15997         else
15998                 error = vfs_rename_other(old_dir,old_dentry,new_dir,new_dentry);
15999 +
16000         if (!error) {
16001                 const char *new_name = old_dentry->d_name.name;
16002 +
16003                 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
16004                               new_dentry->d_inode, old_dentry);
16005         }
16006 @@ -2685,11 +2822,21 @@ asmlinkage long sys_renameat(int olddfd,
16007         if (new_dentry == trap)
16008                 goto exit5;
16009  
16010 +       error = gr_acl_handle_rename(new_dentry, new_dir, newnd.path.mnt,
16011 +                                    old_dentry, old_dir->d_inode, oldnd.path.mnt,
16012 +                                    to);
16013 +       if (error)
16014 +               goto exit5;
16015 +
16016         error = mnt_want_write(oldnd.path.mnt);
16017         if (error)
16018                 goto exit5;
16019         error = vfs_rename(old_dir->d_inode, old_dentry,
16020                                    new_dir->d_inode, new_dentry);
16021 +       if (!error)
16022 +               gr_handle_rename(old_dir->d_inode, new_dir->d_inode, old_dentry,
16023 +                                new_dentry, oldnd.path.mnt, new_dentry->d_inode ? 1 : 0);
16024 +
16025         mnt_drop_write(oldnd.path.mnt);
16026  exit5:
16027         dput(new_dentry);
16028 diff -urNp linux-2.6.27.10/fs/namespace.c linux-2.6.27.10/fs/namespace.c
16029 --- linux-2.6.27.10/fs/namespace.c      2008-11-18 11:38:40.000000000 -0500
16030 +++ linux-2.6.27.10/fs/namespace.c      2008-11-18 11:40:53.000000000 -0500
16031 @@ -27,6 +27,7 @@
16032  #include <linux/vs_tag.h>
16033  #include <linux/vserver/space.h>
16034  #include <linux/vserver/global.h>
16035 +#include <linux/grsecurity.h>
16036  #include <asm/uaccess.h>
16037  #include <asm/unistd.h>
16038  #include "pnode.h"
16039 @@ -1094,6 +1095,8 @@ static int do_umount(struct vfsmount *mn
16040                         lock_kernel();
16041                         retval = do_remount_sb(sb, MS_RDONLY, NULL, 0);
16042                         unlock_kernel();
16043 +
16044 +                       gr_log_remount(mnt->mnt_devname, retval);
16045                 }
16046                 up_write(&sb->s_umount);
16047                 return retval;
16048 @@ -1117,6 +1120,9 @@ static int do_umount(struct vfsmount *mn
16049                 security_sb_umount_busy(mnt);
16050         up_write(&namespace_sem);
16051         release_mounts(&umount_list);
16052 +
16053 +       gr_log_unmount(mnt->mnt_devname, retval);
16054 +
16055         return retval;
16056  }
16057  
16058 @@ -1954,6 +1960,11 @@ long do_mount(char *dev_name, char *dir_
16059         if (retval)
16060                 goto dput_out;
16061  
16062 +       if (gr_handle_chroot_mount(nd.path.dentry, nd.path.mnt, dev_name)) {
16063 +               retval = -EPERM;
16064 +               goto dput_out;
16065 +       }
16066 +
16067         if (flags & MS_REMOUNT)
16068                 retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags,
16069                                     data_page);
16070 @@ -1968,6 +1979,9 @@ long do_mount(char *dev_name, char *dir_
16071                                       dev_name, data_page);
16072  dput_out:
16073         path_put(&nd.path);
16074 +
16075 +       gr_log_mount(dev_name, dir_name, retval);
16076 +
16077         return retval;
16078  }
16079  
16080 @@ -2080,6 +2094,9 @@ asmlinkage long sys_mount(char __user * 
16081         if (retval < 0)
16082                 goto out3;
16083  
16084 +       if (gr_handle_chroot_pivot())
16085 +               return -EPERM;
16086 +
16087         lock_kernel();
16088         retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
16089                           flags, (void *)data_page);
16090 diff -urNp linux-2.6.27.10/fs/nfs/nfs4proc.c linux-2.6.27.10/fs/nfs/nfs4proc.c
16091 --- linux-2.6.27.10/fs/nfs/nfs4proc.c   2008-11-07 12:55:34.000000000 -0500
16092 +++ linux-2.6.27.10/fs/nfs/nfs4proc.c   2008-11-18 03:38:45.000000000 -0500
16093 @@ -653,7 +653,7 @@ static int _nfs4_do_open_reclaim(struct 
16094  static int nfs4_do_open_reclaim(struct nfs_open_context *ctx, struct nfs4_state *state)
16095  {
16096         struct nfs_server *server = NFS_SERVER(state->inode);
16097 -       struct nfs4_exception exception = { };
16098 +       struct nfs4_exception exception = {0, 0};
16099         int err;
16100         do {
16101                 err = _nfs4_do_open_reclaim(ctx, state);
16102 @@ -695,7 +695,7 @@ static int _nfs4_open_delegation_recall(
16103  
16104  int nfs4_open_delegation_recall(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid)
16105  {
16106 -       struct nfs4_exception exception = { };
16107 +       struct nfs4_exception exception = {0, 0};
16108         struct nfs_server *server = NFS_SERVER(state->inode);
16109         int err;
16110         do {
16111 @@ -988,7 +988,7 @@ static int _nfs4_open_expired(struct nfs
16112  static inline int nfs4_do_open_expired(struct nfs_open_context *ctx, struct nfs4_state *state)
16113  {
16114         struct nfs_server *server = NFS_SERVER(state->inode);
16115 -       struct nfs4_exception exception = { };
16116 +       struct nfs4_exception exception = {0, 0};
16117         int err;
16118  
16119         do {
16120 @@ -1090,7 +1090,7 @@ out_err:
16121  
16122  static struct nfs4_state *nfs4_do_open(struct inode *dir, struct path *path, int flags, struct iattr *sattr, struct rpc_cred *cred)
16123  {
16124 -       struct nfs4_exception exception = { };
16125 +       struct nfs4_exception exception = {0, 0};
16126         struct nfs4_state *res;
16127         int status;
16128  
16129 @@ -1181,7 +1181,7 @@ static int nfs4_do_setattr(struct inode 
16130                            struct nfs4_state *state)
16131  {
16132         struct nfs_server *server = NFS_SERVER(inode);
16133 -       struct nfs4_exception exception = { };
16134 +       struct nfs4_exception exception = {0, 0};
16135         int err;
16136         do {
16137                 err = nfs4_handle_exception(server,
16138 @@ -1494,7 +1494,7 @@ static int _nfs4_server_capabilities(str
16139  
16140  int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
16141  {
16142 -       struct nfs4_exception exception = { };
16143 +       struct nfs4_exception exception = {0, 0};
16144         int err;
16145         do {
16146                 err = nfs4_handle_exception(server,
16147 @@ -1527,7 +1527,7 @@ static int _nfs4_lookup_root(struct nfs_
16148  static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle,
16149                 struct nfs_fsinfo *info)
16150  {
16151 -       struct nfs4_exception exception = { };
16152 +       struct nfs4_exception exception = {0, 0};
16153         int err;
16154         do {
16155                 err = nfs4_handle_exception(server,
16156 @@ -1616,7 +1616,7 @@ static int _nfs4_proc_getattr(struct nfs
16157  
16158  static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16159  {
16160 -       struct nfs4_exception exception = { };
16161 +       struct nfs4_exception exception = {0, 0};
16162         int err;
16163         do {
16164                 err = nfs4_handle_exception(server,
16165 @@ -1702,7 +1702,7 @@ static int nfs4_proc_lookupfh(struct nfs
16166                               struct qstr *name, struct nfs_fh *fhandle,
16167                               struct nfs_fattr *fattr)
16168  {
16169 -       struct nfs4_exception exception = { };
16170 +       struct nfs4_exception exception = {0, 0};
16171         int err;
16172         do {
16173                 err = _nfs4_proc_lookupfh(server, dirfh, name, fhandle, fattr);
16174 @@ -1731,7 +1731,7 @@ static int _nfs4_proc_lookup(struct inod
16175  
16176  static int nfs4_proc_lookup(struct inode *dir, struct qstr *name, struct nfs_fh *fhandle, struct nfs_fattr *fattr)
16177  {
16178 -       struct nfs4_exception exception = { };
16179 +       struct nfs4_exception exception = {0, 0};
16180         int err;
16181         do {
16182                 err = nfs4_handle_exception(NFS_SERVER(dir),
16183 @@ -1795,7 +1795,7 @@ static int _nfs4_proc_access(struct inod
16184  
16185  static int nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
16186  {
16187 -       struct nfs4_exception exception = { };
16188 +       struct nfs4_exception exception = {0, 0};
16189         int err;
16190         do {
16191                 err = nfs4_handle_exception(NFS_SERVER(inode),
16192 @@ -1850,7 +1850,7 @@ static int _nfs4_proc_readlink(struct in
16193  static int nfs4_proc_readlink(struct inode *inode, struct page *page,
16194                 unsigned int pgbase, unsigned int pglen)
16195  {
16196 -       struct nfs4_exception exception = { };
16197 +       struct nfs4_exception exception = {0, 0};
16198         int err;
16199         do {
16200                 err = nfs4_handle_exception(NFS_SERVER(inode),
16201 @@ -1947,7 +1947,7 @@ static int _nfs4_proc_remove(struct inod
16202  
16203  static int nfs4_proc_remove(struct inode *dir, struct qstr *name)
16204  {
16205 -       struct nfs4_exception exception = { };
16206 +       struct nfs4_exception exception = {0, 0};
16207         int err;
16208         do {
16209                 err = nfs4_handle_exception(NFS_SERVER(dir),
16210 @@ -2019,7 +2019,7 @@ static int _nfs4_proc_rename(struct inod
16211  static int nfs4_proc_rename(struct inode *old_dir, struct qstr *old_name,
16212                 struct inode *new_dir, struct qstr *new_name)
16213  {
16214 -       struct nfs4_exception exception = { };
16215 +       struct nfs4_exception exception = {0, 0};
16216         int err;
16217         do {
16218                 err = nfs4_handle_exception(NFS_SERVER(old_dir),
16219 @@ -2066,7 +2066,7 @@ static int _nfs4_proc_link(struct inode 
16220  
16221  static int nfs4_proc_link(struct inode *inode, struct inode *dir, struct qstr *name)
16222  {
16223 -       struct nfs4_exception exception = { };
16224 +       struct nfs4_exception exception = {0, 0};
16225         int err;
16226         do {
16227                 err = nfs4_handle_exception(NFS_SERVER(inode),
16228 @@ -2157,7 +2157,7 @@ out:
16229  static int nfs4_proc_symlink(struct inode *dir, struct dentry *dentry,
16230                 struct page *page, unsigned int len, struct iattr *sattr)
16231  {
16232 -       struct nfs4_exception exception = { };
16233 +       struct nfs4_exception exception = {0, 0};
16234         int err;
16235         do {
16236                 err = nfs4_handle_exception(NFS_SERVER(dir),
16237 @@ -2188,7 +2188,7 @@ out:
16238  static int nfs4_proc_mkdir(struct inode *dir, struct dentry *dentry,
16239                 struct iattr *sattr)
16240  {
16241 -       struct nfs4_exception exception = { };
16242 +       struct nfs4_exception exception = {0, 0};
16243         int err;
16244         do {
16245                 err = nfs4_handle_exception(NFS_SERVER(dir),
16246 @@ -2237,7 +2237,7 @@ static int _nfs4_proc_readdir(struct den
16247  static int nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred,
16248                    u64 cookie, struct page *page, unsigned int count, int plus)
16249  {
16250 -       struct nfs4_exception exception = { };
16251 +       struct nfs4_exception exception = {0, 0};
16252         int err;
16253         do {
16254                 err = nfs4_handle_exception(NFS_SERVER(dentry->d_inode),
16255 @@ -2285,7 +2285,7 @@ out:
16256  static int nfs4_proc_mknod(struct inode *dir, struct dentry *dentry,
16257                 struct iattr *sattr, dev_t rdev)
16258  {
16259 -       struct nfs4_exception exception = { };
16260 +       struct nfs4_exception exception = {0, 0};
16261         int err;
16262         do {
16263                 err = nfs4_handle_exception(NFS_SERVER(dir),
16264 @@ -2314,7 +2314,7 @@ static int _nfs4_proc_statfs(struct nfs_
16265  
16266  static int nfs4_proc_statfs(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsstat *fsstat)
16267  {
16268 -       struct nfs4_exception exception = { };
16269 +       struct nfs4_exception exception = {0, 0};
16270         int err;
16271         do {
16272                 err = nfs4_handle_exception(server,
16273 @@ -2342,7 +2342,7 @@ static int _nfs4_do_fsinfo(struct nfs_se
16274  
16275  static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fsinfo *fsinfo)
16276  {
16277 -       struct nfs4_exception exception = { };
16278 +       struct nfs4_exception exception = {0, 0};
16279         int err;
16280  
16281         do {
16282 @@ -2385,7 +2385,7 @@ static int _nfs4_proc_pathconf(struct nf
16283  static int nfs4_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
16284                 struct nfs_pathconf *pathconf)
16285  {
16286 -       struct nfs4_exception exception = { };
16287 +       struct nfs4_exception exception = {0, 0};
16288         int err;
16289  
16290         do {
16291 @@ -2672,7 +2672,7 @@ out_free:
16292  
16293  static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
16294  {
16295 -       struct nfs4_exception exception = { };
16296 +       struct nfs4_exception exception = {0, 0};
16297         ssize_t ret;
16298         do {
16299                 ret = __nfs4_get_acl_uncached(inode, buf, buflen);
16300 @@ -2729,7 +2729,7 @@ static int __nfs4_proc_set_acl(struct in
16301  
16302  static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen)
16303  {
16304 -       struct nfs4_exception exception = { };
16305 +       struct nfs4_exception exception = {0, 0};
16306         int err;
16307         do {
16308                 err = nfs4_handle_exception(NFS_SERVER(inode),
16309 @@ -3020,7 +3020,7 @@ out:
16310  int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4_stateid *stateid, int issync)
16311  {
16312         struct nfs_server *server = NFS_SERVER(inode);
16313 -       struct nfs4_exception exception = { };
16314 +       struct nfs4_exception exception = {0, 0};
16315         int err;
16316         do {
16317                 err = _nfs4_proc_delegreturn(inode, cred, stateid, issync);
16318 @@ -3095,7 +3095,7 @@ out:
16319  
16320  static int nfs4_proc_getlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16321  {
16322 -       struct nfs4_exception exception = { };
16323 +       struct nfs4_exception exception = {0, 0};
16324         int err;
16325  
16326         do {
16327 @@ -3445,7 +3445,7 @@ static int _nfs4_do_setlk(struct nfs4_st
16328  static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request)
16329  {
16330         struct nfs_server *server = NFS_SERVER(state->inode);
16331 -       struct nfs4_exception exception = { };
16332 +       struct nfs4_exception exception = {0, 0};
16333         int err;
16334  
16335         do {
16336 @@ -3463,7 +3463,7 @@ static int nfs4_lock_reclaim(struct nfs4
16337  static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request)
16338  {
16339         struct nfs_server *server = NFS_SERVER(state->inode);
16340 -       struct nfs4_exception exception = { };
16341 +       struct nfs4_exception exception = {0, 0};
16342         int err;
16343  
16344         err = nfs4_set_lock_state(state, request);
16345 @@ -3524,7 +3524,7 @@ out:
16346  
16347  static int nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
16348  {
16349 -       struct nfs4_exception exception = { };
16350 +       struct nfs4_exception exception = {0, 0};
16351         int err;
16352  
16353         do {
16354 @@ -3574,7 +3574,7 @@ nfs4_proc_lock(struct file *filp, int cm
16355  int nfs4_lock_delegation_recall(struct nfs4_state *state, struct file_lock *fl)
16356  {
16357         struct nfs_server *server = NFS_SERVER(state->inode);
16358 -       struct nfs4_exception exception = { };
16359 +       struct nfs4_exception exception = {0, 0};
16360         int err;
16361  
16362         err = nfs4_set_lock_state(state, fl);
16363 diff -urNp linux-2.6.27.10/fs/nfsd/export.c linux-2.6.27.10/fs/nfsd/export.c
16364 --- linux-2.6.27.10/fs/nfsd/export.c    2008-11-07 12:55:34.000000000 -0500
16365 +++ linux-2.6.27.10/fs/nfsd/export.c    2008-11-18 03:38:45.000000000 -0500
16366 @@ -473,7 +473,7 @@ static int secinfo_parse(char **mesg, ch
16367                  * probably discover the problem when someone fails to
16368                  * authenticate.
16369                  */
16370 -               if (f->pseudoflavor < 0)
16371 +               if ((s32)f->pseudoflavor < 0)
16372                         return -EINVAL;
16373                 err = get_int(mesg, &f->flags);
16374                 if (err)
16375 diff -urNp linux-2.6.27.10/fs/nls/nls_base.c linux-2.6.27.10/fs/nls/nls_base.c
16376 --- linux-2.6.27.10/fs/nls/nls_base.c   2008-11-07 12:55:34.000000000 -0500
16377 +++ linux-2.6.27.10/fs/nls/nls_base.c   2008-11-18 03:38:45.000000000 -0500
16378 @@ -42,7 +42,7 @@ static const struct utf8_table utf8_tabl
16379      {0xF8,  0xF0,   3*6,    0x1FFFFF,       0x10000,   /* 4 byte sequence */},
16380      {0xFC,  0xF8,   4*6,    0x3FFFFFF,      0x200000,  /* 5 byte sequence */},
16381      {0xFE,  0xFC,   5*6,    0x7FFFFFFF,     0x4000000, /* 6 byte sequence */},
16382 -    {0,                                                       /* end of table    */}
16383 +    {0, 0, 0, 0, 0,                                   /* end of table    */}
16384  };
16385  
16386  int
16387 diff -urNp linux-2.6.27.10/fs/ntfs/file.c linux-2.6.27.10/fs/ntfs/file.c
16388 --- linux-2.6.27.10/fs/ntfs/file.c      2008-11-07 12:55:34.000000000 -0500
16389 +++ linux-2.6.27.10/fs/ntfs/file.c      2008-11-18 03:38:45.000000000 -0500
16390 @@ -2291,6 +2291,6 @@ const struct inode_operations ntfs_file_
16391  #endif /* NTFS_RW */
16392  };
16393  
16394 -const struct file_operations ntfs_empty_file_ops = {};
16395 +const struct file_operations ntfs_empty_file_ops;
16396  
16397 -const struct inode_operations ntfs_empty_inode_ops = {};
16398 +const struct inode_operations ntfs_empty_inode_ops;
16399 diff -urNp linux-2.6.27.10/fs/open.c linux-2.6.27.10/fs/open.c
16400 --- linux-2.6.27.10/fs/open.c   2008-11-07 12:55:34.000000000 -0500
16401 +++ linux-2.6.27.10/fs/open.c   2008-11-18 03:38:45.000000000 -0500
16402 @@ -29,6 +29,7 @@
16403  #include <linux/vs_dlimit.h>
16404  #include <linux/vs_tag.h>
16405  #include <linux/vs_cowbl.h>
16406 +#include <linux/grsecurity.h>
16407  
16408  int vfs_statfs(struct dentry *dentry, struct kstatfs *buf)
16409  {
16410 @@ -207,6 +208,9 @@ int do_truncate(struct dentry *dentry, l
16411         if (length < 0)
16412                 return -EINVAL;
16413  
16414 +       if (filp && !gr_acl_handle_truncate(dentry, filp->f_path.mnt))
16415 +               return -EACCES;
16416 +
16417         newattrs.ia_size = length;
16418         newattrs.ia_valid = ATTR_SIZE | time_attrs;
16419         if (filp) {
16420 @@ -491,6 +495,9 @@ asmlinkage long sys_faccessat(int dfd, c
16421         if (__mnt_is_readonly(path.mnt))
16422                 res = -EROFS;
16423  
16424 +       if (!res && !gr_acl_handle_access(path.dentry, path.mnt, mode))
16425 +               res = -EACCES;
16426 +
16427  out_path_release:
16428         path_put(&path);
16429  out:
16430 @@ -521,6 +528,8 @@ asmlinkage long sys_chdir(const char __u
16431         if (error)
16432                 goto dput_and_out;
16433  
16434 +       gr_log_chdir(path.dentry, path.mnt);
16435 +
16436         set_fs_pwd(current->fs, &path);
16437  
16438  dput_and_out:
16439 @@ -547,6 +556,13 @@ asmlinkage long sys_fchdir(unsigned int 
16440                 goto out_putf;
16441  
16442         error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
16443 +
16444 +       if (!error && !gr_chroot_fchdir(file->f_path.dentry, file->f_path.mnt))
16445 +               error = -EPERM;
16446 +
16447 +       if (!error)
16448 +               gr_log_chdir(file->f_path.dentry, file->f_path.mnt);
16449 +
16450         if (!error)
16451                 set_fs_pwd(current->fs, &file->f_path);
16452  out_putf:
16453 @@ -572,7 +588,14 @@ asmlinkage long sys_chroot(const char __
16454         if (!capable(CAP_SYS_CHROOT))
16455                 goto dput_and_out;
16456  
16457 +       if (gr_handle_chroot_chroot(path.dentry, path.mnt))
16458 +               goto dput_and_out;
16459 +
16460         set_fs_root(current->fs, &path);
16461 +
16462 +       gr_handle_chroot_caps(current);
16463 +       gr_handle_chroot_chdir(&path);
16464 +
16465         error = 0;
16466  dput_and_out:
16467         path_put(&path);
16468 @@ -600,13 +623,28 @@ asmlinkage long sys_fchmod(unsigned int 
16469         err = mnt_want_write(file->f_path.mnt);
16470         if (err)
16471                 goto out_putf;
16472 +
16473 +       if (!gr_acl_handle_fchmod(dentry, file->f_path.mnt, mode)) {
16474 +               err = -EACCES;
16475 +               goto out_drop_write;
16476 +       }
16477 +
16478         mutex_lock(&inode->i_mutex);
16479         if (mode == (mode_t) -1)
16480                 mode = inode->i_mode;
16481 +
16482 +       if (gr_handle_chroot_chmod(dentry, file->f_path.mnt, mode)) {
16483 +               err = -EPERM;
16484 +               mutex_unlock(&inode->i_mutex);
16485 +               goto out_drop_write;
16486 +       }
16487 +
16488         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16489         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16490         err = notify_change(dentry, &newattrs);
16491         mutex_unlock(&inode->i_mutex);
16492 +
16493 +out_drop_write:
16494         mnt_drop_write(file->f_path.mnt);
16495  out_putf:
16496         fput(file);
16497 @@ -630,13 +668,28 @@ asmlinkage long sys_fchmodat(int dfd, co
16498         error = mnt_want_write(path.mnt);
16499         if (error)
16500                 goto dput_and_out;
16501 +
16502 +       if (!gr_acl_handle_chmod(path.dentry, path.mnt, mode)) {
16503 +               error = -EACCES;
16504 +               goto out_drop_write;
16505 +       }
16506 +
16507         mutex_lock(&inode->i_mutex);
16508         if (mode == (mode_t) -1)
16509                 mode = inode->i_mode;
16510 +
16511 +       if (gr_handle_chroot_chmod(path.dentry, path.mnt, mode)) {
16512 +               error = -EACCES;
16513 +               mutex_unlock(&inode->i_mutex);
16514 +               goto out_drop_write;
16515 +       }
16516 +
16517         newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
16518         newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
16519         error = notify_change(path.dentry, &newattrs);
16520         mutex_unlock(&inode->i_mutex);
16521 +
16522 +out_drop_write:
16523         mnt_drop_write(path.mnt);
16524  dput_and_out:
16525         path_put(&path);
16526 @@ -649,12 +702,15 @@ asmlinkage long sys_chmod(const char __u
16527         return sys_fchmodat(AT_FDCWD, filename, mode);
16528  }
16529  
16530 -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
16531 +static int chown_common(struct dentry * dentry, uid_t user, gid_t group, struct vfsmount *mnt)
16532  {
16533         struct inode *inode = dentry->d_inode;
16534         int error;
16535         struct iattr newattrs;
16536  
16537 +       if (!gr_acl_handle_chown(dentry, mnt))
16538 +               return -EACCES;
16539 +
16540         newattrs.ia_valid =  ATTR_CTIME;
16541         if (user != (uid_t) -1) {
16542                 newattrs.ia_valid |= ATTR_UID;
16543 @@ -685,7 +741,7 @@ asmlinkage long sys_chown(const char __u
16544         error = cow_check_and_break(&path);
16545         if (!error)
16546  #endif
16547 -               error = chown_common(path.dentry, user, group);
16548 +               error = chown_common(path.dentry, user, group, path.mnt);
16549         mnt_drop_write(path.mnt);
16550  out_release:
16551         path_put(&path);
16552 @@ -710,7 +766,7 @@ asmlinkage long sys_fchownat(int dfd, co
16553         error = cow_check_and_break(&path);
16554         if (!error)
16555  #endif
16556 -               error = chown_common(path.dentry, user, group);
16557 +               error = chown_common(path.dentry, user, group, path.mnt);
16558         mnt_drop_write(path.mnt);
16559  out_release:
16560         path_put(&path);
16561 @@ -729,7 +785,7 @@ asmlinkage long sys_lchown(const char __
16562         error = cow_check_and_break(&path);
16563         if (!error)
16564  #endif
16565 -               error = chown_common(path.dentry, user, group);
16566 +               error = chown_common(path.dentry, user, group, path.mnt);
16567         mnt_drop_write(path.mnt);
16568  out_release:
16569         path_put(&path);
16570 @@ -753,7 +809,7 @@ asmlinkage long sys_fchown(unsigned int 
16571                 goto out_fput;
16572         dentry = file->f_path.dentry;
16573         audit_inode(NULL, dentry);
16574 -       error = chown_common(dentry, user, group);
16575 +       error = chown_common(dentry, user, group, file->f_path.mnt);
16576         mnt_drop_write(file->f_path.mnt);
16577  out_fput:
16578         fput(file);
16579 diff -urNp linux-2.6.27.10/fs/pipe.c linux-2.6.27.10/fs/pipe.c
16580 --- linux-2.6.27.10/fs/pipe.c   2008-11-07 12:55:34.000000000 -0500
16581 +++ linux-2.6.27.10/fs/pipe.c   2008-11-18 03:38:45.000000000 -0500
16582 @@ -851,7 +851,7 @@ void free_pipe_info(struct inode *inode)
16583         inode->i_pipe = NULL;
16584  }
16585  
16586 -static struct vfsmount *pipe_mnt __read_mostly;
16587 +struct vfsmount *pipe_mnt __read_mostly;
16588  static int pipefs_delete_dentry(struct dentry *dentry)
16589  {
16590         /*
16591 diff -urNp linux-2.6.27.10/fs/proc/array.c linux-2.6.27.10/fs/proc/array.c
16592 --- linux-2.6.27.10/fs/proc/array.c     2008-11-07 12:55:34.000000000 -0500
16593 +++ linux-2.6.27.10/fs/proc/array.c     2008-11-18 03:38:45.000000000 -0500
16594 @@ -315,6 +315,21 @@ static inline void task_context_switch_c
16595                         p->nivcsw);
16596  }
16597  
16598 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16599 +static inline void task_pax(struct seq_file *m, struct task_struct *p)
16600 +{
16601 +       if (p->mm)
16602 +               seq_printf(m, "PaX:\t%c%c%c%c%c\n",
16603 +                          p->mm->pax_flags & MF_PAX_PAGEEXEC ? 'P' : 'p',
16604 +                          p->mm->pax_flags & MF_PAX_EMUTRAMP ? 'E' : 'e',
16605 +                          p->mm->pax_flags & MF_PAX_MPROTECT ? 'M' : 'm',
16606 +                          p->mm->pax_flags & MF_PAX_RANDMMAP ? 'R' : 'r',
16607 +                          p->mm->pax_flags & MF_PAX_SEGMEXEC ? 'S' : 's');
16608 +       else
16609 +               seq_printf(m, "PaX:\t-----\n");
16610 +}
16611 +#endif
16612 +
16613  int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
16614                         struct pid *pid, struct task_struct *task)
16615  {
16616 @@ -334,9 +349,20 @@ int proc_pid_status(struct seq_file *m, 
16617         task_show_regs(m, task);
16618  #endif
16619         task_context_switch_counts(m, task);
16620 +
16621 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
16622 +       task_pax(m, task);
16623 +#endif
16624 +
16625         return 0;
16626  }
16627  
16628 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16629 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
16630 +                            (_mm->pax_flags & MF_PAX_RANDMMAP || \
16631 +                             _mm->pax_flags & MF_PAX_SEGMEXEC))
16632 +#endif
16633 +
16634  static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
16635                         struct pid *pid, struct task_struct *task, int whole)
16636  {
16637 @@ -429,6 +455,19 @@ static int do_task_stat(struct seq_file 
16638                 gtime = task_gtime(task);
16639         }
16640  
16641 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16642 +       if (PAX_RAND_FLAGS(mm)) {
16643 +               eip = 0;
16644 +               esp = 0;
16645 +               wchan = 0;
16646 +       }
16647 +#endif
16648 +#ifdef CONFIG_GRKERNSEC_HIDESYM
16649 +       wchan = 0;
16650 +       eip =0;
16651 +       esp =0;
16652 +#endif
16653 +
16654         /* scale priority and nice values from timeslices to -20..20 */
16655         /* to make it look like a "normal" Unix priority/nice value  */
16656         priority = task_prio(task);
16657 @@ -469,9 +508,15 @@ static int do_task_stat(struct seq_file 
16658                 vsize,
16659                 mm ? get_mm_rss(mm) : 0,
16660                 rsslim,
16661 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
16662 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->start_code : 0),
16663 +               PAX_RAND_FLAGS(mm) ? 1 : (mm ? mm->end_code : 0),
16664 +               PAX_RAND_FLAGS(mm) ? 0 : (mm ? mm->start_stack : 0),
16665 +#else
16666                 mm ? mm->start_code : 0,
16667                 mm ? mm->end_code : 0,
16668                 mm ? mm->start_stack : 0,
16669 +#endif
16670                 esp,
16671                 eip,
16672                 /* The signal information here is obsolete.
16673 @@ -524,3 +569,10 @@ int proc_pid_statm(struct seq_file *m, s
16674  
16675         return 0;
16676  }
16677 +
16678 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16679 +int proc_pid_ipaddr(struct task_struct *task, char *buffer)
16680 +{
16681 +       return sprintf(buffer, "%u.%u.%u.%u\n", NIPQUAD(task->signal->curr_ip));
16682 +}
16683 +#endif
16684 diff -urNp linux-2.6.27.10/fs/proc/base.c linux-2.6.27.10/fs/proc/base.c
16685 --- linux-2.6.27.10/fs/proc/base.c      2008-11-07 12:55:34.000000000 -0500
16686 +++ linux-2.6.27.10/fs/proc/base.c      2008-11-18 03:38:45.000000000 -0500
16687 @@ -79,6 +79,8 @@
16688  #include <linux/pid_namespace.h>
16689  #include <linux/vs_context.h>
16690  #include <linux/vs_network.h>
16691 +#include <linux/grsecurity.h>
16692 +
16693  #include "internal.h"
16694  
16695  /* NOTE:
16696 @@ -148,7 +150,7 @@ static unsigned int pid_entry_count_dirs
16697         return count;
16698  }
16699  
16700 -int maps_protect;
16701 +int maps_protect = 1;
16702  EXPORT_SYMBOL(maps_protect);
16703  
16704  static struct fs_struct *get_fs_struct(struct task_struct *task)
16705 @@ -229,6 +231,9 @@ static int check_mem_permission(struct t
16706         if (task == current)
16707                 return 0;
16708  
16709 +       if (gr_handle_proc_ptrace(task) || gr_acl_handle_procpidmem(task))
16710 +               return -EPERM;
16711 +
16712         /*
16713          * If current is actively ptrace'ing, and would also be
16714          * permitted to freshly attach with ptrace now, permit it.
16715 @@ -312,9 +317,9 @@ static int proc_pid_auxv(struct task_str
16716         struct mm_struct *mm = get_task_mm(task);
16717         if (mm) {
16718                 unsigned int nwords = 0;
16719 -               do
16720 +               do {
16721                         nwords += 2;
16722 -               while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16723 +               } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
16724                 res = nwords * sizeof(mm->saved_auxv[0]);
16725                 if (res > PAGE_SIZE)
16726                         res = PAGE_SIZE;
16727 @@ -1437,7 +1442,11 @@ static struct inode *proc_pid_make_inode
16728         inode->i_gid = 0;
16729         if (task_dumpable(task)) {
16730                 inode->i_uid = task->euid;
16731 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16732 +               inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16733 +#else
16734                 inode->i_gid = task->egid;
16735 +#endif
16736         }
16737         security_task_to_inode(task, inode);
16738  
16739 @@ -1453,17 +1462,45 @@ static int pid_getattr(struct vfsmount *
16740  {
16741         struct inode *inode = dentry->d_inode;
16742         struct task_struct *task;
16743 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16744 +       struct task_struct *tmp = current;
16745 +#endif
16746 +
16747         generic_fillattr(inode, stat);
16748  
16749         rcu_read_lock();
16750         stat->uid = 0;
16751         stat->gid = 0;
16752         task = pid_task(proc_pid(inode), PIDTYPE_PID);
16753 -       if (task) {
16754 +
16755 +       if (task && (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))) {
16756 +               rcu_read_unlock();
16757 +               return -ENOENT;
16758 +       }
16759 +
16760 +
16761 +       if (task
16762 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16763 +           && (!tmp->uid || (tmp->uid == task->uid)
16764 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16765 +           || in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16766 +#endif
16767 +           )
16768 +#endif
16769 +       ) {
16770                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16771 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16772 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16773 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16774 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16775 +#endif
16776                     task_dumpable(task)) {
16777                         stat->uid = task->euid;
16778 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16779 +                       stat->gid = CONFIG_GRKERNSEC_PROC_GID;
16780 +#else
16781                         stat->gid = task->egid;
16782 +#endif
16783                 }
16784         }
16785         rcu_read_unlock();
16786 @@ -1491,11 +1528,21 @@ static int pid_revalidate(struct dentry 
16787  {
16788         struct inode *inode = dentry->d_inode;
16789         struct task_struct *task = get_proc_task(inode);
16790 +
16791         if (task) {
16792                 if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
16793 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16794 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IXUSR)) ||
16795 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16796 +                   (inode->i_mode == (S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP)) ||
16797 +#endif
16798                     task_dumpable(task)) {
16799                         inode->i_uid = task->euid;
16800 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16801 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16802 +#else
16803                         inode->i_gid = task->egid;
16804 +#endif
16805                 } else {
16806                         inode->i_uid = 0;
16807                         inode->i_gid = 0;
16808 @@ -1863,12 +1910,22 @@ static const struct file_operations proc
16809  static int proc_fd_permission(struct inode *inode, int mask)
16810  {
16811         int rv;
16812 +       struct task_struct *task;
16813  
16814         rv = generic_permission(inode, mask, NULL);
16815 -       if (rv == 0)
16816 -               return 0;
16817 +
16818         if (task_pid(current) == proc_pid(inode))
16819                 rv = 0;
16820 +
16821 +       task = get_proc_task(inode);
16822 +       if (task == NULL)
16823 +               return rv;
16824 +
16825 +       if (gr_acl_handle_procpidmem(task))
16826 +               rv = -EACCES;
16827 +
16828 +       put_task_struct(task);
16829 +
16830         return rv;
16831  }
16832  
16833 @@ -1979,6 +2036,9 @@ static struct dentry *proc_pident_lookup
16834         if (!task)
16835                 goto out_no_task;
16836  
16837 +       if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16838 +               goto out;
16839 +
16840         /*
16841          * Yes, it does not scale. And it should not. Don't add
16842          * new entries into /proc/<tgid>/ without very good reasons.
16843 @@ -2023,6 +2083,9 @@ static int proc_pident_readdir(struct fi
16844         if (!task)
16845                 goto out_no_task;
16846  
16847 +       if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16848 +               goto out;
16849 +
16850         ret = 0;
16851         i = filp->f_pos;
16852         switch (i) {
16853 @@ -2385,6 +2448,9 @@ static struct dentry *proc_base_lookup(s
16854         if (p > last)
16855                 goto out;
16856  
16857 +       if (gr_pid_is_chrooted(task) || gr_check_hidden_task(task))
16858 +               goto out;
16859 +
16860         error = proc_base_instantiate(dir, dentry, task, p);
16861  
16862  out:
16863 @@ -2518,6 +2584,9 @@ static const struct pid_entry tgid_base_
16864  #ifdef CONFIG_TASK_IO_ACCOUNTING
16865         INF("io",       S_IRUGO, tgid_io_accounting),
16866  #endif
16867 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16868 +       INF("ipaddr",     S_IRUSR, pid_ipaddr),
16869 +#endif
16870         ONE("nsproxy",  S_IRUGO, pid_nsproxy),
16871  };
16872  
16873 @@ -2647,7 +2716,14 @@ static struct dentry *proc_pid_instantia
16874         if (!inode)
16875                 goto out;
16876  
16877 +#ifdef CONFIG_GRKERNSEC_PROC_USER
16878 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IXUSR;
16879 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16880 +       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16881 +       inode->i_mode = S_IFDIR|S_IRUSR|S_IRGRP|S_IXUSR|S_IXGRP;
16882 +#else
16883         inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO;
16884 +#endif
16885         inode->i_op = &proc_tgid_base_inode_operations;
16886         inode->i_fop = &proc_tgid_base_operations;
16887         inode->i_flags|=S_IMMUTABLE;
16888 @@ -2689,7 +2765,11 @@ struct dentry *proc_pid_lookup(struct in
16889         if (!task)
16890                 goto out;
16891  
16892 +       if (gr_check_hidden_task(task))
16893 +               goto out_put_task;
16894 +
16895         result = proc_pid_instantiate(dir, dentry, task, NULL);
16896 +out_put_task:
16897         put_task_struct(task);
16898  out:
16899         return result;
16900 @@ -2754,6 +2834,9 @@ int proc_pid_readdir(struct file * filp,
16901  {
16902         unsigned int nr = filp->f_pos - FIRST_PROCESS_ENTRY;
16903         struct task_struct *reaper = get_proc_task_real(filp->f_path.dentry->d_inode);
16904 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16905 +       struct task_struct *tmp = current;
16906 +#endif
16907         struct tgid_iter iter;
16908         struct pid_namespace *ns;
16909  
16910 @@ -2772,6 +2855,17 @@ int proc_pid_readdir(struct file * filp,
16911         for (iter = next_tgid(ns, iter);
16912              iter.task;
16913              iter.tgid += 1, iter = next_tgid(ns, iter)) {
16914 +               if (gr_pid_is_chrooted(iter.task) || gr_check_hidden_task(iter.task)
16915 +#if defined(CONFIG_GRKERNSEC_PROC_USER) || defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
16916 +                   || (tmp->uid && (iter.task->uid != tmp->uid)
16917 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16918 +                       && !in_group_p(CONFIG_GRKERNSEC_PROC_GID)
16919 +#endif
16920 +                       )
16921 +#endif
16922 +               )
16923 +                       continue;
16924 +
16925                 filp->f_pos = iter.tgid + TGID_OFFSET;
16926                 if (!vx_proc_task_visible(iter.task))
16927                         continue;
16928 diff -urNp linux-2.6.27.10/fs/proc/inode.c linux-2.6.27.10/fs/proc/inode.c
16929 --- linux-2.6.27.10/fs/proc/inode.c     2008-11-07 12:55:34.000000000 -0500
16930 +++ linux-2.6.27.10/fs/proc/inode.c     2008-11-18 03:38:45.000000000 -0500
16931 @@ -467,7 +467,11 @@ struct inode *proc_get_inode(struct supe
16932                 if (de->mode) {
16933                         inode->i_mode = de->mode;
16934                         inode->i_uid = de->uid;
16935 +#ifdef CONFIG_GRKERNSEC_PROC_USERGROUP
16936 +                       inode->i_gid = CONFIG_GRKERNSEC_PROC_GID;
16937 +#else
16938                         inode->i_gid = de->gid;
16939 +#endif
16940                 }
16941                 if (de->size)
16942                         inode->i_size = de->size;
16943 diff -urNp linux-2.6.27.10/fs/proc/internal.h linux-2.6.27.10/fs/proc/internal.h
16944 --- linux-2.6.27.10/fs/proc/internal.h  2008-11-07 12:55:34.000000000 -0500
16945 +++ linux-2.6.27.10/fs/proc/internal.h  2008-11-18 03:38:45.000000000 -0500
16946 @@ -55,6 +55,9 @@ extern int proc_pid_status(struct seq_fi
16947  extern int proc_pid_nsproxy(struct seq_file *m, struct pid_namespace *ns,
16948                                 struct pid *pid, struct task_struct *task);
16949  
16950 +#ifdef CONFIG_GRKERNSEC_PROC_IPADDR
16951 +extern int proc_pid_ipaddr(struct task_struct *task, char *buffer);
16952 +#endif
16953  extern loff_t mem_lseek(struct file *file, loff_t offset, int orig);
16954  
16955  extern const struct file_operations proc_maps_operations;
16956 diff -urNp linux-2.6.27.10/fs/proc/Kconfig linux-2.6.27.10/fs/proc/Kconfig
16957 --- linux-2.6.27.10/fs/proc/Kconfig     2008-11-07 12:55:34.000000000 -0500
16958 +++ linux-2.6.27.10/fs/proc/Kconfig     2008-11-18 03:38:45.000000000 -0500
16959 @@ -30,12 +30,12 @@ config PROC_FS
16960  
16961  config PROC_KCORE
16962         bool "/proc/kcore support" if !ARM
16963 -       depends on PROC_FS && MMU
16964 +       depends on PROC_FS && MMU && !GRKERNSEC_PROC_ADD
16965  
16966  config PROC_VMCORE
16967          bool "/proc/vmcore support (EXPERIMENTAL)"
16968 -        depends on PROC_FS && CRASH_DUMP
16969 -       default y
16970 +        depends on PROC_FS && CRASH_DUMP && !GRKERNSEC
16971 +       default n
16972          help
16973          Exports the dump image of crashed kernel in ELF format.
16974  
16975 diff -urNp linux-2.6.27.10/fs/proc/proc_misc.c linux-2.6.27.10/fs/proc/proc_misc.c
16976 --- linux-2.6.27.10/fs/proc/proc_misc.c 2008-11-07 12:55:34.000000000 -0500
16977 +++ linux-2.6.27.10/fs/proc/proc_misc.c 2008-11-18 03:38:45.000000000 -0500
16978 @@ -860,6 +860,8 @@ struct proc_dir_entry *proc_root_kcore;
16979  
16980  void __init proc_misc_init(void)
16981  {
16982 +       int gr_mode = 0;
16983 +
16984         static struct {
16985                 char *name;
16986                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
16987 @@ -875,13 +877,24 @@ void __init proc_misc_init(void)
16988                 {"stram",       stram_read_proc},
16989  #endif
16990                 {"filesystems", filesystems_read_proc},
16991 +#ifndef CONFIG_GRKERNSEC_PROC_ADD
16992                 {"cmdline",     cmdline_read_proc},
16993 +#endif
16994                 {"execdomains", execdomains_read_proc},
16995                 {NULL,}
16996         };
16997         for (p = simple_ones; p->name; p++)
16998                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
16999  
17000 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17001 +       gr_mode = S_IRUSR;
17002 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17003 +       gr_mode = S_IRUSR | S_IRGRP;
17004 +#endif
17005 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17006 +       create_proc_read_entry("cmdline", gr_mode, NULL, &cmdline_read_proc, NULL);
17007 +#endif
17008 +
17009         proc_symlink("mounts", NULL, "self/mounts");
17010  
17011         /* And now for trickier ones */
17012 @@ -889,14 +902,18 @@ void __init proc_misc_init(void)
17013         proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
17014  #endif
17015         proc_create("locks", 0, NULL, &proc_locks_operations);
17016 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17017 +       proc_create("devices", gr_mode, NULL, &proc_devinfo_operations);
17018 +#else
17019         proc_create("devices", 0, NULL, &proc_devinfo_operations);
17020 +#endif
17021         proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
17022  #ifdef CONFIG_BLOCK
17023         proc_create("partitions", 0, NULL, &proc_partitions_operations);
17024  #endif
17025         proc_create("stat", 0, NULL, &proc_stat_operations);
17026         proc_create("interrupts", 0, NULL, &proc_interrupts_operations);
17027 -#ifdef CONFIG_SLABINFO
17028 +#if defined(CONFIG_SLABINFO) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
17029         proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
17030  #ifdef CONFIG_DEBUG_SLAB_LEAK
17031         proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
17032 @@ -918,7 +935,7 @@ void __init proc_misc_init(void)
17033  #ifdef CONFIG_SCHEDSTATS
17034         proc_create("schedstat", 0, NULL, &proc_schedstat_operations);
17035  #endif
17036 -#ifdef CONFIG_PROC_KCORE
17037 +#if defined(CONFIG_PROC_KCORE) && !defined(CONFIG_GRKERNSEC_PROC_ADD)
17038         proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &proc_kcore_operations);
17039         if (proc_root_kcore)
17040                 proc_root_kcore->size =
17041 diff -urNp linux-2.6.27.10/fs/proc/proc_net.c linux-2.6.27.10/fs/proc/proc_net.c
17042 --- linux-2.6.27.10/fs/proc/proc_net.c  2008-11-07 12:55:34.000000000 -0500
17043 +++ linux-2.6.27.10/fs/proc/proc_net.c  2008-11-18 03:38:45.000000000 -0500
17044 @@ -106,6 +106,14 @@ static struct net *get_proc_task_net(str
17045         struct nsproxy *ns;
17046         struct net *net = NULL;
17047  
17048 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17049 +       if (current->fsuid)
17050 +               return net;
17051 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17052 +       if (current->fsuid && !in_group_p(CONFIG_GRKERNSEC_PROC_GID))
17053 +               return net;
17054 +#endif
17055 +
17056         rcu_read_lock();
17057         task = pid_task(proc_pid(dir), PIDTYPE_PID);
17058         if (task != NULL) {
17059 diff -urNp linux-2.6.27.10/fs/proc/proc_sysctl.c linux-2.6.27.10/fs/proc/proc_sysctl.c
17060 --- linux-2.6.27.10/fs/proc/proc_sysctl.c       2008-11-18 11:38:40.000000000 -0500
17061 +++ linux-2.6.27.10/fs/proc/proc_sysctl.c       2008-11-18 11:40:53.000000000 -0500
17062 @@ -7,6 +7,8 @@
17063  #include <linux/security.h>
17064  #include "internal.h"
17065  
17066 +extern __u32 gr_handle_sysctl(const struct ctl_table *table, const int op);
17067 +
17068  static struct dentry_operations proc_sys_dentry_operations;
17069  static const struct file_operations proc_sys_file_operations;
17070  static const struct inode_operations proc_sys_inode_operations;
17071 @@ -110,6 +112,9 @@ static struct dentry *proc_sys_lookup(st
17072         if (!p)
17073                 goto out;
17074  
17075 +       if (gr_handle_sysctl(p, MAY_EXEC))
17076 +               goto out;
17077 +
17078         err = ERR_PTR(-ENOMEM);
17079         inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
17080         if (h)
17081 @@ -229,6 +234,9 @@ static int scan(struct ctl_table_header 
17082                 if (*pos < file->f_pos)
17083                         continue;
17084  
17085 +               if (gr_handle_sysctl(table, 0))
17086 +                       continue;
17087 +
17088                 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
17089                 if (res)
17090                         return res;
17091 @@ -339,6 +347,9 @@ static int proc_sys_getattr(struct vfsmo
17092         if (IS_ERR(head))
17093                 return PTR_ERR(head);
17094  
17095 +       if (table && gr_handle_sysctl(table, MAY_EXEC))
17096 +               return -ENOENT;
17097 +
17098         generic_fillattr(inode, stat);
17099         if (table)
17100                 stat->mode = (stat->mode & S_IFMT) | table->mode;
17101 diff -urNp linux-2.6.27.10/fs/proc/root.c linux-2.6.27.10/fs/proc/root.c
17102 --- linux-2.6.27.10/fs/proc/root.c      2008-11-07 12:55:34.000000000 -0500
17103 +++ linux-2.6.27.10/fs/proc/root.c      2008-11-18 03:38:45.000000000 -0500
17104 @@ -135,7 +135,15 @@ void __init proc_root_init(void)
17105  #ifdef CONFIG_PROC_DEVICETREE
17106         proc_device_tree_init();
17107  #endif
17108 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
17109 +#ifdef CONFIG_GRKERNSEC_PROC_USER
17110 +       proc_mkdir_mode("bus", S_IRUSR | S_IXUSR, NULL);
17111 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
17112 +       proc_mkdir_mode("bus", S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP, NULL);
17113 +#endif
17114 +#else
17115         proc_mkdir("bus", NULL);
17116 +#endif
17117         proc_sys_init();
17118  }
17119  
17120 diff -urNp linux-2.6.27.10/fs/proc/task_mmu.c linux-2.6.27.10/fs/proc/task_mmu.c
17121 --- linux-2.6.27.10/fs/proc/task_mmu.c  2008-12-21 01:16:51.000000000 -0500
17122 +++ linux-2.6.27.10/fs/proc/task_mmu.c  2008-12-21 01:13:46.000000000 -0500
17123 @@ -46,15 +46,26 @@ void task_mem(struct seq_file *m, struct
17124                 "VmStk:\t%8lu kB\n"
17125                 "VmExe:\t%8lu kB\n"
17126                 "VmLib:\t%8lu kB\n"
17127 -               "VmPTE:\t%8lu kB\n",
17128 -               hiwater_vm << (PAGE_SHIFT-10),
17129 +               "VmPTE:\t%8lu kB\n"
17130 +
17131 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17132 +               "CsBase:\t%8lx\nCsLim:\t%8lx\n"
17133 +#endif
17134 +
17135 +               ,hiwater_vm << (PAGE_SHIFT-10),
17136                 (total_vm - mm->reserved_vm) << (PAGE_SHIFT-10),
17137                 mm->locked_vm << (PAGE_SHIFT-10),
17138                 hiwater_rss << (PAGE_SHIFT-10),
17139                 total_rss << (PAGE_SHIFT-10),
17140                 data << (PAGE_SHIFT-10),
17141                 mm->stack_vm << (PAGE_SHIFT-10), text, lib,
17142 -               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10);
17143 +               (PTRS_PER_PTE*sizeof(pte_t)*mm->nr_ptes) >> 10
17144 +
17145 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
17146 +               , mm->context.user_cs_base, mm->context.user_cs_limit
17147 +#endif
17148 +
17149 +       );
17150  }
17151  
17152  unsigned long task_vsize(struct mm_struct *mm)
17153 @@ -198,6 +209,12 @@ static int do_maps_open(struct inode *in
17154         return ret;
17155  }
17156  
17157 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17158 +#define PAX_RAND_FLAGS(_mm) (_mm != NULL && _mm != current->mm && \
17159 +                            (_mm->pax_flags & MF_PAX_RANDMMAP || \
17160 +                             _mm->pax_flags & MF_PAX_SEGMEXEC))
17161 +#endif
17162 +
17163  static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma)
17164  {
17165         struct mm_struct *mm = vma->vm_mm;
17166 @@ -214,13 +231,22 @@ static void show_map_vma(struct seq_file
17167         }
17168  
17169         seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n",
17170 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17171 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_start,
17172 +                       PAX_RAND_FLAGS(mm) ? 0UL : vma->vm_end,
17173 +#else
17174                         vma->vm_start,
17175                         vma->vm_end,
17176 +#endif
17177                         flags & VM_READ ? 'r' : '-',
17178                         flags & VM_WRITE ? 'w' : '-',
17179                         flags & VM_EXEC ? 'x' : '-',
17180                         flags & VM_MAYSHARE ? 's' : 'p',
17181 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17182 +                       PAX_RAND_FLAGS(mm) ? 0UL : ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
17183 +#else
17184                         ((loff_t)vma->vm_pgoff) << PAGE_SHIFT,
17185 +#endif
17186                         MAJOR(dev), MINOR(dev), ino, &len);
17187  
17188         /*
17189 @@ -234,11 +260,11 @@ static void show_map_vma(struct seq_file
17190                 const char *name = arch_vma_name(vma);
17191                 if (!name) {
17192                         if (mm) {
17193 -                               if (vma->vm_start <= mm->start_brk &&
17194 -                                               vma->vm_end >= mm->brk) {
17195 +                               if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {
17196                                         name = "[heap]";
17197 -                               } else if (vma->vm_start <= mm->start_stack &&
17198 -                                          vma->vm_end >= mm->start_stack) {
17199 +                               } else if ((vma->vm_flags & (VM_GROWSDOWN | VM_GROWSUP)) ||
17200 +                                          (vma->vm_start <= mm->start_stack &&
17201 +                                           vma->vm_end >= mm->start_stack)) {
17202                                         name = "[stack]";
17203                                 }
17204                         } else {
17205 @@ -387,9 +413,16 @@ static int show_smap(struct seq_file *m,
17206                 return -EACCES;
17207  
17208         memset(&mss, 0, sizeof mss);
17209 -       mss.vma = vma;
17210 -       if (vma->vm_mm && !is_vm_hugetlb_page(vma))
17211 -               walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
17212 +
17213 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17214 +       if (!PAX_RAND_FLAGS(vma->vm_mm)) {
17215 +#endif
17216 +               mss.vma = vma;
17217 +               if (vma->vm_mm && !is_vm_hugetlb_page(vma))
17218 +                       walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk);
17219 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17220 +       }
17221 +#endif
17222  
17223         show_map_vma(m, vma);
17224  
17225 @@ -403,7 +436,11 @@ static int show_smap(struct seq_file *m,
17226                    "Private_Dirty:  %8lu kB\n"
17227                    "Referenced:     %8lu kB\n"
17228                    "Swap:           %8lu kB\n",
17229 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17230 +                  PAX_RAND_FLAGS(vma->vm_mm) ? 0UL : (vma->vm_end - vma->vm_start) >> 10,
17231 +#else
17232                    (vma->vm_end - vma->vm_start) >> 10,
17233 +#endif
17234                    mss.resident >> 10,
17235                    (unsigned long)(mss.pss >> (10 + PSS_SHIFT)),
17236                    mss.shared_clean  >> 10,
17237 @@ -757,6 +794,11 @@ static int show_numa_map_checked(struct 
17238         struct proc_maps_private *priv = m->private;
17239         struct task_struct *task = priv->task;
17240  
17241 +#ifdef CONFIG_GRKERNSEC_PROC_MEMMAP
17242 +       if (!ptrace_may_access(task, PTRACE_MODE_READ))
17243 +               return -EACCES;
17244 +#endif
17245 +
17246         if (maps_protect && !ptrace_may_access(task, PTRACE_MODE_READ))
17247                 return -EACCES;
17248  
17249 diff -urNp linux-2.6.27.10/fs/readdir.c linux-2.6.27.10/fs/readdir.c
17250 --- linux-2.6.27.10/fs/readdir.c        2008-11-07 12:55:34.000000000 -0500
17251 +++ linux-2.6.27.10/fs/readdir.c        2008-11-18 03:38:45.000000000 -0500
17252 @@ -16,6 +16,8 @@
17253  #include <linux/security.h>
17254  #include <linux/syscalls.h>
17255  #include <linux/unistd.h>
17256 +#include <linux/namei.h>
17257 +#include <linux/grsecurity.h>
17258  
17259  #include <asm/uaccess.h>
17260  
17261 @@ -67,6 +69,7 @@ struct old_linux_dirent {
17262  
17263  struct readdir_callback {
17264         struct old_linux_dirent __user * dirent;
17265 +       struct file * file;
17266         int result;
17267  };
17268  
17269 @@ -84,6 +87,10 @@ static int fillonedir(void * __buf, cons
17270                 buf->result = -EOVERFLOW;
17271                 return -EOVERFLOW;
17272         }
17273 +
17274 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17275 +               return 0;
17276 +
17277         buf->result++;
17278         dirent = buf->dirent;
17279         if (!access_ok(VERIFY_WRITE, dirent,
17280 @@ -115,6 +122,7 @@ asmlinkage long old_readdir(unsigned int
17281  
17282         buf.result = 0;
17283         buf.dirent = dirent;
17284 +       buf.file = file;
17285  
17286         error = vfs_readdir(file, fillonedir, &buf);
17287         if (error >= 0)
17288 @@ -141,6 +149,7 @@ struct linux_dirent {
17289  struct getdents_callback {
17290         struct linux_dirent __user * current_dir;
17291         struct linux_dirent __user * previous;
17292 +       struct file * file;
17293         int count;
17294         int error;
17295  };
17296 @@ -161,6 +170,10 @@ static int filldir(void * __buf, const c
17297                 buf->error = -EOVERFLOW;
17298                 return -EOVERFLOW;
17299         }
17300 +
17301 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17302 +               return 0;
17303 +
17304         dirent = buf->previous;
17305         if (dirent) {
17306                 if (__put_user(offset, &dirent->d_off))
17307 @@ -207,6 +220,7 @@ asmlinkage long sys_getdents(unsigned in
17308         buf.previous = NULL;
17309         buf.count = count;
17310         buf.error = 0;
17311 +       buf.file = file;
17312  
17313         error = vfs_readdir(file, filldir, &buf);
17314         if (error < 0)
17315 @@ -229,6 +243,7 @@ out:
17316  struct getdents_callback64 {
17317         struct linux_dirent64 __user * current_dir;
17318         struct linux_dirent64 __user * previous;
17319 +       struct file *file;
17320         int count;
17321         int error;
17322  };
17323 @@ -243,6 +258,10 @@ static int filldir64(void * __buf, const
17324         buf->error = -EINVAL;   /* only used if we fail.. */
17325         if (reclen > buf->count)
17326                 return -EINVAL;
17327 +
17328 +       if (!gr_acl_handle_filldir(buf->file, name, namlen, ino))
17329 +               return 0;
17330 +
17331         dirent = buf->previous;
17332         if (dirent) {
17333                 if (__put_user(offset, &dirent->d_off))
17334 @@ -289,6 +308,7 @@ asmlinkage long sys_getdents64(unsigned 
17335  
17336         buf.current_dir = dirent;
17337         buf.previous = NULL;
17338 +       buf.file = file;
17339         buf.count = count;
17340         buf.error = 0;
17341  
17342 diff -urNp linux-2.6.27.10/fs/select.c linux-2.6.27.10/fs/select.c
17343 --- linux-2.6.27.10/fs/select.c 2008-11-07 12:55:34.000000000 -0500
17344 +++ linux-2.6.27.10/fs/select.c 2008-11-18 03:38:45.000000000 -0500
17345 @@ -24,6 +24,7 @@
17346  #include <linux/fdtable.h>
17347  #include <linux/fs.h>
17348  #include <linux/rcupdate.h>
17349 +#include <linux/grsecurity.h>
17350  
17351  #include <asm/uaccess.h>
17352  
17353 @@ -658,6 +659,7 @@ int do_sys_poll(struct pollfd __user *uf
17354         struct poll_list *walk = head;
17355         unsigned long todo = nfds;
17356  
17357 +       gr_learn_resource(current, RLIMIT_NOFILE, nfds, 1);
17358         if (nfds > current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
17359                 return -EINVAL;
17360  
17361 diff -urNp linux-2.6.27.10/fs/smbfs/symlink.c linux-2.6.27.10/fs/smbfs/symlink.c
17362 --- linux-2.6.27.10/fs/smbfs/symlink.c  2008-11-07 12:55:34.000000000 -0500
17363 +++ linux-2.6.27.10/fs/smbfs/symlink.c  2008-11-18 03:38:45.000000000 -0500
17364 @@ -55,7 +55,7 @@ static void *smb_follow_link(struct dent
17365  
17366  static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
17367  {
17368 -       char *s = nd_get_link(nd);
17369 +       const char *s = nd_get_link(nd);
17370         if (!IS_ERR(s))
17371                 __putname(s);
17372  }
17373 diff -urNp linux-2.6.27.10/fs/sysfs/symlink.c linux-2.6.27.10/fs/sysfs/symlink.c
17374 --- linux-2.6.27.10/fs/sysfs/symlink.c  2008-11-07 12:55:34.000000000 -0500
17375 +++ linux-2.6.27.10/fs/sysfs/symlink.c  2008-11-18 03:38:45.000000000 -0500
17376 @@ -200,7 +200,7 @@ static void *sysfs_follow_link(struct de
17377  
17378  static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
17379  {
17380 -       char *page = nd_get_link(nd);
17381 +       const char *page = nd_get_link(nd);
17382         if (!IS_ERR(page))
17383                 free_page((unsigned long)page);
17384  }
17385 diff -urNp linux-2.6.27.10/fs/udf/balloc.c linux-2.6.27.10/fs/udf/balloc.c
17386 --- linux-2.6.27.10/fs/udf/balloc.c     2008-11-07 12:55:34.000000000 -0500
17387 +++ linux-2.6.27.10/fs/udf/balloc.c     2008-11-18 03:38:45.000000000 -0500
17388 @@ -169,9 +169,7 @@ static void udf_bitmap_free_blocks(struc
17389         unsigned long overflow;
17390  
17391         mutex_lock(&sbi->s_alloc_mutex);
17392 -       if (bloc.logicalBlockNum < 0 ||
17393 -           (bloc.logicalBlockNum + count) >
17394 -               sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17395 +       if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17396                 udf_debug("%d < %d || %d + %d > %d\n",
17397                           bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17398                           sbi->s_partmaps[bloc.partitionReferenceNum].
17399 @@ -239,7 +237,7 @@ static int udf_bitmap_prealloc_blocks(st
17400  
17401         mutex_lock(&sbi->s_alloc_mutex);
17402         part_len = sbi->s_partmaps[partition].s_partition_len;
17403 -       if (first_block < 0 || first_block >= part_len)
17404 +       if (first_block >= part_len)
17405                 goto out;
17406  
17407         if (first_block + block_count > part_len)
17408 @@ -300,7 +298,7 @@ static int udf_bitmap_new_block(struct s
17409         mutex_lock(&sbi->s_alloc_mutex);
17410  
17411  repeat:
17412 -       if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17413 +       if (goal >= sbi->s_partmaps[partition].s_partition_len)
17414                 goal = 0;
17415  
17416         nr_groups = bitmap->s_nr_groups;
17417 @@ -438,9 +436,7 @@ static void udf_table_free_blocks(struct
17418         struct udf_inode_info *iinfo;
17419  
17420         mutex_lock(&sbi->s_alloc_mutex);
17421 -       if (bloc.logicalBlockNum < 0 ||
17422 -           (bloc.logicalBlockNum + count) >
17423 -               sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17424 +       if (bloc.logicalBlockNum + count > sbi->s_partmaps[bloc.partitionReferenceNum].s_partition_len) {
17425                 udf_debug("%d < %d || %d + %d > %d\n",
17426                           bloc.logicalBlockNum, 0, bloc.logicalBlockNum, count,
17427                           sbi->s_partmaps[bloc.partitionReferenceNum].
17428 @@ -671,8 +667,7 @@ static int udf_table_prealloc_blocks(str
17429         int8_t etype = -1;
17430         struct udf_inode_info *iinfo;
17431  
17432 -       if (first_block < 0 ||
17433 -               first_block >= sbi->s_partmaps[partition].s_partition_len)
17434 +       if (first_block >= sbi->s_partmaps[partition].s_partition_len)
17435                 return 0;
17436  
17437         iinfo = UDF_I(table);
17438 @@ -750,7 +745,7 @@ static int udf_table_new_block(struct su
17439                 return newblock;
17440  
17441         mutex_lock(&sbi->s_alloc_mutex);
17442 -       if (goal < 0 || goal >= sbi->s_partmaps[partition].s_partition_len)
17443 +       if (goal >= sbi->s_partmaps[partition].s_partition_len)
17444                 goal = 0;
17445  
17446         /* We search for the closest matching block to goal. If we find
17447 diff -urNp linux-2.6.27.10/fs/ufs/inode.c linux-2.6.27.10/fs/ufs/inode.c
17448 --- linux-2.6.27.10/fs/ufs/inode.c      2008-11-07 12:55:34.000000000 -0500
17449 +++ linux-2.6.27.10/fs/ufs/inode.c      2008-11-18 03:38:45.000000000 -0500
17450 @@ -56,9 +56,7 @@ static int ufs_block_to_path(struct inod
17451  
17452  
17453         UFSD("ptrs=uspi->s_apb = %d,double_blocks=%ld \n",ptrs,double_blocks);
17454 -       if (i_block < 0) {
17455 -               ufs_warning(inode->i_sb, "ufs_block_to_path", "block < 0");
17456 -       } else if (i_block < direct_blocks) {
17457 +       if (i_block < direct_blocks) {
17458                 offsets[n++] = i_block;
17459         } else if ((i_block -= direct_blocks) < indirect_blocks) {
17460                 offsets[n++] = UFS_IND_BLOCK;
17461 @@ -440,8 +438,6 @@ int ufs_getfrag_block(struct inode *inod
17462         lock_kernel();
17463  
17464         UFSD("ENTER, ino %lu, fragment %llu\n", inode->i_ino, (unsigned long long)fragment);
17465 -       if (fragment < 0)
17466 -               goto abort_negative;
17467         if (fragment >
17468             ((UFS_NDADDR + uspi->s_apb + uspi->s_2apb + uspi->s_3apb)
17469              << uspi->s_fpbshift))
17470 @@ -504,10 +500,6 @@ abort:
17471         unlock_kernel();
17472         return err;
17473  
17474 -abort_negative:
17475 -       ufs_warning(sb, "ufs_get_block", "block < 0");
17476 -       goto abort;
17477 -
17478  abort_too_big:
17479         ufs_warning(sb, "ufs_get_block", "block > big");
17480         goto abort;
17481 diff -urNp linux-2.6.27.10/fs/utimes.c linux-2.6.27.10/fs/utimes.c
17482 --- linux-2.6.27.10/fs/utimes.c 2008-11-07 12:55:34.000000000 -0500
17483 +++ linux-2.6.27.10/fs/utimes.c 2008-11-18 03:38:45.000000000 -0500
17484 @@ -8,6 +8,7 @@
17485  #include <linux/syscalls.h>
17486  #include <linux/mount.h>
17487  #include <linux/vs_cowbl.h>
17488 +#include <linux/grsecurity.h>
17489  #include <asm/uaccess.h>
17490  #include <asm/unistd.h>
17491  
17492 @@ -101,6 +102,12 @@ static int utimes_common(struct path *pa
17493                                 goto mnt_drop_write_and_out;
17494                 }
17495         }
17496 +
17497 +       if (!gr_acl_handle_utime(path->dentry, path->mnt)) {
17498 +               error = -EACCES;
17499 +               goto mnt_drop_write_and_out;
17500 +       }
17501 +
17502         mutex_lock(&inode->i_mutex);
17503         error = notify_change(path->dentry, &newattrs);
17504         mutex_unlock(&inode->i_mutex);
17505 diff -urNp linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c
17506 --- linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c 2008-11-07 12:55:34.000000000 -0500
17507 +++ linux-2.6.27.10/fs/xfs/linux-2.6/xfs_iops.c 2008-11-18 03:38:45.000000000 -0500
17508 @@ -500,7 +500,7 @@ xfs_vn_put_link(
17509         struct nameidata *nd,
17510         void            *p)
17511  {
17512 -       char            *s = nd_get_link(nd);
17513 +       const char      *s = nd_get_link(nd);
17514  
17515         if (!IS_ERR(s))
17516                 kfree(s);
17517 diff -urNp linux-2.6.27.10/fs/xfs/xfs_bmap.c linux-2.6.27.10/fs/xfs/xfs_bmap.c
17518 --- linux-2.6.27.10/fs/xfs/xfs_bmap.c   2008-11-07 12:55:34.000000000 -0500
17519 +++ linux-2.6.27.10/fs/xfs/xfs_bmap.c   2008-11-18 03:38:45.000000000 -0500
17520 @@ -360,7 +360,7 @@ xfs_bmap_validate_ret(
17521         int                     nmap,
17522         int                     ret_nmap);
17523  #else
17524 -#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)
17525 +#define        xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap) do {} while (0)
17526  #endif /* DEBUG */
17527  
17528  #if defined(XFS_RW_TRACE)
17529 diff -urNp linux-2.6.27.10/grsecurity/gracl_alloc.c linux-2.6.27.10/grsecurity/gracl_alloc.c
17530 --- linux-2.6.27.10/grsecurity/gracl_alloc.c    1969-12-31 19:00:00.000000000 -0500
17531 +++ linux-2.6.27.10/grsecurity/gracl_alloc.c    2008-11-18 03:38:45.000000000 -0500
17532 @@ -0,0 +1,91 @@
17533 +#include <linux/kernel.h>
17534 +#include <linux/mm.h>
17535 +#include <linux/slab.h>
17536 +#include <linux/vmalloc.h>
17537 +#include <linux/gracl.h>
17538 +#include <linux/grsecurity.h>
17539 +
17540 +static unsigned long alloc_stack_next = 1;
17541 +static unsigned long alloc_stack_size = 1;
17542 +static void **alloc_stack;
17543 +
17544 +static __inline__ int
17545 +alloc_pop(void)
17546 +{
17547 +       if (alloc_stack_next == 1)
17548 +               return 0;
17549 +
17550 +       kfree(alloc_stack[alloc_stack_next - 2]);
17551 +
17552 +       alloc_stack_next--;
17553 +
17554 +       return 1;
17555 +}
17556 +
17557 +static __inline__ void
17558 +alloc_push(void *buf)
17559 +{
17560 +       if (alloc_stack_next >= alloc_stack_size)
17561 +               BUG();
17562 +
17563 +       alloc_stack[alloc_stack_next - 1] = buf;
17564 +
17565 +       alloc_stack_next++;
17566 +
17567 +       return;
17568 +}
17569 +
17570 +void *
17571 +acl_alloc(unsigned long len)
17572 +{
17573 +       void *ret;
17574 +
17575 +       if (len > PAGE_SIZE)
17576 +               BUG();
17577 +
17578 +       ret = kmalloc(len, GFP_KERNEL);
17579 +
17580 +       if (ret)
17581 +               alloc_push(ret);
17582 +
17583 +       return ret;
17584 +}
17585 +
17586 +void
17587 +acl_free_all(void)
17588 +{
17589 +       if (gr_acl_is_enabled() || !alloc_stack)
17590 +               return;
17591 +
17592 +       while (alloc_pop()) ;
17593 +
17594 +       if (alloc_stack) {
17595 +               if ((alloc_stack_size * sizeof (void *)) <= PAGE_SIZE)
17596 +                       kfree(alloc_stack);
17597 +               else
17598 +                       vfree(alloc_stack);
17599 +       }
17600 +
17601 +       alloc_stack = NULL;
17602 +       alloc_stack_size = 1;
17603 +       alloc_stack_next = 1;
17604 +
17605 +       return;
17606 +}
17607 +
17608 +int
17609 +acl_alloc_stack_init(unsigned long size)
17610 +{
17611 +       if ((size * sizeof (void *)) <= PAGE_SIZE)
17612 +               alloc_stack =
17613 +                   (void **) kmalloc(size * sizeof (void *), GFP_KERNEL);
17614 +       else
17615 +               alloc_stack = (void **) vmalloc(size * sizeof (void *));
17616 +
17617 +       alloc_stack_size = size;
17618 +
17619 +       if (!alloc_stack)
17620 +               return 0;
17621 +       else
17622 +               return 1;
17623 +}
17624 diff -urNp linux-2.6.27.10/grsecurity/gracl.c linux-2.6.27.10/grsecurity/gracl.c
17625 --- linux-2.6.27.10/grsecurity/gracl.c  1969-12-31 19:00:00.000000000 -0500
17626 +++ linux-2.6.27.10/grsecurity/gracl.c  2008-11-18 03:38:45.000000000 -0500
17627 @@ -0,0 +1,3722 @@
17628 +#include <linux/kernel.h>
17629 +#include <linux/module.h>
17630 +#include <linux/sched.h>
17631 +#include <linux/mm.h>
17632 +#include <linux/file.h>
17633 +#include <linux/fs.h>
17634 +#include <linux/namei.h>
17635 +#include <linux/mount.h>
17636 +#include <linux/tty.h>
17637 +#include <linux/proc_fs.h>
17638 +#include <linux/smp_lock.h>
17639 +#include <linux/slab.h>
17640 +#include <linux/vmalloc.h>
17641 +#include <linux/types.h>
17642 +#include <linux/sysctl.h>
17643 +#include <linux/netdevice.h>
17644 +#include <linux/ptrace.h>
17645 +#include <linux/gracl.h>
17646 +#include <linux/gralloc.h>
17647 +#include <linux/grsecurity.h>
17648 +#include <linux/grinternal.h>
17649 +#include <linux/pid_namespace.h>
17650 +#include <linux/fdtable.h>
17651 +#include <linux/percpu.h>
17652 +
17653 +#include <asm/uaccess.h>
17654 +#include <asm/errno.h>
17655 +#include <asm/mman.h>
17656 +
17657 +static struct acl_role_db acl_role_set;
17658 +static struct name_db name_set;
17659 +static struct inodev_db inodev_set;
17660 +
17661 +/* for keeping track of userspace pointers used for subjects, so we
17662 +   can share references in the kernel as well
17663 +*/
17664 +
17665 +static struct dentry *real_root;
17666 +static struct vfsmount *real_root_mnt;
17667 +
17668 +static struct acl_subj_map_db subj_map_set;
17669 +
17670 +static struct acl_role_label *default_role;
17671 +
17672 +static u16 acl_sp_role_value;
17673 +
17674 +extern char *gr_shared_page[4];
17675 +static DECLARE_MUTEX(gr_dev_sem);
17676 +DEFINE_RWLOCK(gr_inode_lock);
17677 +
17678 +struct gr_arg *gr_usermode;
17679 +
17680 +static unsigned int gr_status = GR_STATUS_INIT;
17681 +
17682 +extern int chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum);
17683 +extern void gr_clear_learn_entries(void);
17684 +
17685 +#ifdef CONFIG_GRKERNSEC_RESLOG
17686 +extern void gr_log_resource(const struct task_struct *task,
17687 +                           const int res, const unsigned long wanted, const int gt);
17688 +#endif
17689 +
17690 +unsigned char *gr_system_salt;
17691 +unsigned char *gr_system_sum;
17692 +
17693 +static struct sprole_pw **acl_special_roles = NULL;
17694 +static __u16 num_sprole_pws = 0;
17695 +
17696 +static struct acl_role_label *kernel_role = NULL;
17697 +
17698 +static unsigned int gr_auth_attempts = 0;
17699 +static unsigned long gr_auth_expires = 0UL;
17700 +
17701 +extern struct vfsmount *sock_mnt;
17702 +extern struct vfsmount *pipe_mnt;
17703 +extern struct vfsmount *shm_mnt;
17704 +static struct acl_object_label *fakefs_obj;
17705 +
17706 +extern int gr_init_uidset(void);
17707 +extern void gr_free_uidset(void);
17708 +extern void gr_remove_uid(uid_t uid);
17709 +extern int gr_find_uid(uid_t uid);
17710 +
17711 +__inline__ int
17712 +gr_acl_is_enabled(void)
17713 +{
17714 +       return (gr_status & GR_READY);
17715 +}
17716 +
17717 +char gr_roletype_to_char(void)
17718 +{
17719 +       switch (current->role->roletype &
17720 +               (GR_ROLE_DEFAULT | GR_ROLE_USER | GR_ROLE_GROUP |
17721 +                GR_ROLE_SPECIAL)) {
17722 +       case GR_ROLE_DEFAULT:
17723 +               return 'D';
17724 +       case GR_ROLE_USER:
17725 +               return 'U';
17726 +       case GR_ROLE_GROUP:
17727 +               return 'G';
17728 +       case GR_ROLE_SPECIAL:
17729 +               return 'S';
17730 +       }
17731 +
17732 +       return 'X';
17733 +}
17734 +
17735 +__inline__ int
17736 +gr_acl_tpe_check(void)
17737 +{
17738 +       if (unlikely(!(gr_status & GR_READY)))
17739 +               return 0;
17740 +       if (current->role->roletype & GR_ROLE_TPE)
17741 +               return 1;
17742 +       else
17743 +               return 0;
17744 +}
17745 +
17746 +int
17747 +gr_handle_rawio(const struct inode *inode)
17748 +{
17749 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
17750 +       if (inode && S_ISBLK(inode->i_mode) &&
17751 +           grsec_enable_chroot_caps && proc_is_chrooted(current) &&
17752 +           !capable(CAP_SYS_RAWIO))
17753 +               return 1;
17754 +#endif
17755 +       return 0;
17756 +}
17757 +
17758 +static int
17759 +gr_streq(const char *a, const char *b, const unsigned int lena, const unsigned int lenb)
17760 +{
17761 +       int i;
17762 +       unsigned long *l1;
17763 +       unsigned long *l2;
17764 +       unsigned char *c1;
17765 +       unsigned char *c2;
17766 +       int num_longs;
17767 +
17768 +       if (likely(lena != lenb))
17769 +               return 0;
17770 +
17771 +       l1 = (unsigned long *)a;
17772 +       l2 = (unsigned long *)b;
17773 +
17774 +       num_longs = lena / sizeof(unsigned long);
17775 +
17776 +       for (i = num_longs; i--; l1++, l2++) {
17777 +               if (unlikely(*l1 != *l2))
17778 +                       return 0;
17779 +       }
17780 +
17781 +       c1 = (unsigned char *) l1;
17782 +       c2 = (unsigned char *) l2;
17783 +
17784 +       i = lena - (num_longs * sizeof(unsigned long)); 
17785 +
17786 +       for (; i--; c1++, c2++) {
17787 +               if (unlikely(*c1 != *c2))
17788 +                       return 0;
17789 +       }
17790 +
17791 +       return 1;
17792 +}
17793 +
17794 +static char * __our_d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17795 +                          struct dentry *root, struct vfsmount *rootmnt,
17796 +                          char *buffer, int buflen)
17797 +{
17798 +       char * end = buffer+buflen;
17799 +       char * retval;
17800 +       int namelen;
17801 +
17802 +       *--end = '\0';
17803 +       buflen--;
17804 +
17805 +       if (buflen < 1)
17806 +               goto Elong;
17807 +       /* Get '/' right */
17808 +       retval = end-1;
17809 +       *retval = '/';
17810 +
17811 +       for (;;) {
17812 +               struct dentry * parent;
17813 +
17814 +               if (dentry == root && vfsmnt == rootmnt)
17815 +                       break;
17816 +               if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
17817 +                       /* Global root? */
17818 +                       spin_lock(&vfsmount_lock);
17819 +                       if (vfsmnt->mnt_parent == vfsmnt) {
17820 +                               spin_unlock(&vfsmount_lock);
17821 +                               goto global_root;
17822 +                       }
17823 +                       dentry = vfsmnt->mnt_mountpoint;
17824 +                       vfsmnt = vfsmnt->mnt_parent;
17825 +                       spin_unlock(&vfsmount_lock);
17826 +                       continue;
17827 +               }
17828 +               parent = dentry->d_parent;
17829 +               prefetch(parent);
17830 +               namelen = dentry->d_name.len;
17831 +               buflen -= namelen + 1;
17832 +               if (buflen < 0)
17833 +                       goto Elong;
17834 +               end -= namelen;
17835 +               memcpy(end, dentry->d_name.name, namelen);
17836 +               *--end = '/';
17837 +               retval = end;
17838 +               dentry = parent;
17839 +       }
17840 +
17841 +       return retval;
17842 +
17843 +global_root:
17844 +       namelen = dentry->d_name.len;
17845 +       buflen -= namelen;
17846 +       if (buflen < 0)
17847 +               goto Elong;
17848 +       retval -= namelen-1;    /* hit the slash */
17849 +       memcpy(retval, dentry->d_name.name, namelen);
17850 +       return retval;
17851 +Elong:
17852 +       return ERR_PTR(-ENAMETOOLONG);
17853 +}
17854 +
17855 +static char *
17856 +gen_full_path(struct dentry *dentry, struct vfsmount *vfsmnt,
17857 +              struct dentry *root, struct vfsmount *rootmnt, char *buf, int buflen)
17858 +{
17859 +       char *retval;
17860 +
17861 +       retval = __our_d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
17862 +       if (unlikely(IS_ERR(retval)))
17863 +               retval = strcpy(buf, "<path too long>");
17864 +       else if (unlikely(retval[1] == '/' && retval[2] == '\0'))
17865 +               retval[1] = '\0';
17866 +
17867 +       return retval;
17868 +}
17869 +
17870 +static char *
17871 +__d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17872 +               char *buf, int buflen)
17873 +{
17874 +       char *res;
17875 +
17876 +       /* we can use real_root, real_root_mnt, because this is only called
17877 +          by the RBAC system */
17878 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, real_root, real_root_mnt, buf, buflen);
17879 +
17880 +       return res;
17881 +}
17882 +
17883 +static char *
17884 +d_real_path(const struct dentry *dentry, const struct vfsmount *vfsmnt,
17885 +           char *buf, int buflen)
17886 +{
17887 +       char *res;
17888 +       struct dentry *root;
17889 +       struct vfsmount *rootmnt;
17890 +       struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
17891 +
17892 +       /* we can't use real_root, real_root_mnt, because they belong only to the RBAC system */
17893 +       read_lock(&reaper->fs->lock);
17894 +       root = dget(reaper->fs->root.dentry);
17895 +       rootmnt = mntget(reaper->fs->root.mnt);
17896 +       read_unlock(&reaper->fs->lock);
17897 +
17898 +       spin_lock(&dcache_lock);
17899 +       res = gen_full_path((struct dentry *)dentry, (struct vfsmount *)vfsmnt, root, rootmnt, buf, buflen);
17900 +       spin_unlock(&dcache_lock);
17901 +
17902 +       dput(root);
17903 +       mntput(rootmnt);
17904 +       return res;
17905 +}
17906 +
17907 +static char *
17908 +gr_to_filename_rbac(const struct dentry *dentry, const struct vfsmount *mnt)
17909 +{
17910 +       char *ret;
17911 +       spin_lock(&dcache_lock);
17912 +       ret = __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17913 +                            PAGE_SIZE);
17914 +       spin_unlock(&dcache_lock);
17915 +       return ret;
17916 +}
17917 +
17918 +char *
17919 +gr_to_filename_nolock(const struct dentry *dentry, const struct vfsmount *mnt)
17920 +{
17921 +       return __d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0],smp_processor_id()),
17922 +                            PAGE_SIZE);
17923 +}
17924 +
17925 +char *
17926 +gr_to_filename(const struct dentry *dentry, const struct vfsmount *mnt)
17927 +{
17928 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
17929 +                          PAGE_SIZE);
17930 +}
17931 +
17932 +char *
17933 +gr_to_filename1(const struct dentry *dentry, const struct vfsmount *mnt)
17934 +{
17935 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[1], smp_processor_id()),
17936 +                          PAGE_SIZE);
17937 +}
17938 +
17939 +char *
17940 +gr_to_filename2(const struct dentry *dentry, const struct vfsmount *mnt)
17941 +{
17942 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[2], smp_processor_id()),
17943 +                          PAGE_SIZE);
17944 +}
17945 +
17946 +char *
17947 +gr_to_filename3(const struct dentry *dentry, const struct vfsmount *mnt)
17948 +{
17949 +       return d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[3], smp_processor_id()),
17950 +                          PAGE_SIZE);
17951 +}
17952 +
17953 +__inline__ __u32
17954 +to_gr_audit(const __u32 reqmode)
17955 +{
17956 +       /* masks off auditable permission flags, then shifts them to create
17957 +          auditing flags, and adds the special case of append auditing if
17958 +          we're requesting write */
17959 +       return (((reqmode & ~GR_AUDITS) << 10) | ((reqmode & GR_WRITE) ? GR_AUDIT_APPEND : 0));
17960 +}
17961 +
17962 +struct acl_subject_label *
17963 +lookup_subject_map(const struct acl_subject_label *userp)
17964 +{
17965 +       unsigned int index = shash(userp, subj_map_set.s_size);
17966 +       struct subject_map *match;
17967 +
17968 +       match = subj_map_set.s_hash[index];
17969 +
17970 +       while (match && match->user != userp)
17971 +               match = match->next;
17972 +
17973 +       if (match != NULL)
17974 +               return match->kernel;
17975 +       else
17976 +               return NULL;
17977 +}
17978 +
17979 +static void
17980 +insert_subj_map_entry(struct subject_map *subjmap)
17981 +{
17982 +       unsigned int index = shash(subjmap->user, subj_map_set.s_size);
17983 +       struct subject_map **curr;
17984 +
17985 +       subjmap->prev = NULL;
17986 +
17987 +       curr = &subj_map_set.s_hash[index];
17988 +       if (*curr != NULL)
17989 +               (*curr)->prev = subjmap;
17990 +
17991 +       subjmap->next = *curr;
17992 +       *curr = subjmap;
17993 +
17994 +       return;
17995 +}
17996 +
17997 +static struct acl_role_label *
17998 +lookup_acl_role_label(const struct task_struct *task, const uid_t uid,
17999 +                     const gid_t gid)
18000 +{
18001 +       unsigned int index = rhash(uid, GR_ROLE_USER, acl_role_set.r_size);
18002 +       struct acl_role_label *match;
18003 +       struct role_allowed_ip *ipp;
18004 +       unsigned int x;
18005 +
18006 +       match = acl_role_set.r_hash[index];
18007 +
18008 +       while (match) {
18009 +               if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_USER)) == (GR_ROLE_DOMAIN | GR_ROLE_USER)) {
18010 +                       for (x = 0; x < match->domain_child_num; x++) {
18011 +                               if (match->domain_children[x] == uid)
18012 +                                       goto found;
18013 +                       }
18014 +               } else if (match->uidgid == uid && match->roletype & GR_ROLE_USER)
18015 +                       break;
18016 +               match = match->next;
18017 +       }
18018 +found:
18019 +       if (match == NULL) {
18020 +             try_group:
18021 +               index = rhash(gid, GR_ROLE_GROUP, acl_role_set.r_size);
18022 +               match = acl_role_set.r_hash[index];
18023 +
18024 +               while (match) {
18025 +                       if ((match->roletype & (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) == (GR_ROLE_DOMAIN | GR_ROLE_GROUP)) {
18026 +                               for (x = 0; x < match->domain_child_num; x++) {
18027 +                                       if (match->domain_children[x] == gid)
18028 +                                               goto found2;
18029 +                               }
18030 +                       } else if (match->uidgid == gid && match->roletype & GR_ROLE_GROUP)
18031 +                               break;
18032 +                       match = match->next;
18033 +               }
18034 +found2:
18035 +               if (match == NULL)
18036 +                       match = default_role;
18037 +               if (match->allowed_ips == NULL)
18038 +                       return match;
18039 +               else {
18040 +                       for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18041 +                               if (likely
18042 +                                   ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18043 +                                    (ntohl(ipp->addr) & ipp->netmask)))
18044 +                                       return match;
18045 +                       }
18046 +                       match = default_role;
18047 +               }
18048 +       } else if (match->allowed_ips == NULL) {
18049 +               return match;
18050 +       } else {
18051 +               for (ipp = match->allowed_ips; ipp; ipp = ipp->next) {
18052 +                       if (likely
18053 +                           ((ntohl(task->signal->curr_ip) & ipp->netmask) ==
18054 +                            (ntohl(ipp->addr) & ipp->netmask)))
18055 +                               return match;
18056 +               }
18057 +               goto try_group;
18058 +       }
18059 +
18060 +       return match;
18061 +}
18062 +
18063 +struct acl_subject_label *
18064 +lookup_acl_subj_label(const ino_t ino, const dev_t dev,
18065 +                     const struct acl_role_label *role)
18066 +{
18067 +       unsigned int index = fhash(ino, dev, role->subj_hash_size);
18068 +       struct acl_subject_label *match;
18069 +
18070 +       match = role->subj_hash[index];
18071 +
18072 +       while (match && (match->inode != ino || match->device != dev ||
18073 +              (match->mode & GR_DELETED))) {
18074 +               match = match->next;
18075 +       }
18076 +
18077 +       if (match && !(match->mode & GR_DELETED))
18078 +               return match;
18079 +       else
18080 +               return NULL;
18081 +}
18082 +
18083 +static struct acl_object_label *
18084 +lookup_acl_obj_label(const ino_t ino, const dev_t dev,
18085 +                    const struct acl_subject_label *subj)
18086 +{
18087 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18088 +       struct acl_object_label *match;
18089 +
18090 +       match = subj->obj_hash[index];
18091 +
18092 +       while (match && (match->inode != ino || match->device != dev ||
18093 +              (match->mode & GR_DELETED))) {
18094 +               match = match->next;
18095 +       }
18096 +
18097 +       if (match && !(match->mode & GR_DELETED))
18098 +               return match;
18099 +       else
18100 +               return NULL;
18101 +}
18102 +
18103 +static struct acl_object_label *
18104 +lookup_acl_obj_label_create(const ino_t ino, const dev_t dev,
18105 +                    const struct acl_subject_label *subj)
18106 +{
18107 +       unsigned int index = fhash(ino, dev, subj->obj_hash_size);
18108 +       struct acl_object_label *match;
18109 +
18110 +       match = subj->obj_hash[index];
18111 +
18112 +       while (match && (match->inode != ino || match->device != dev ||
18113 +              !(match->mode & GR_DELETED))) {
18114 +               match = match->next;
18115 +       }
18116 +
18117 +       if (match && (match->mode & GR_DELETED))
18118 +               return match;
18119 +
18120 +       match = subj->obj_hash[index];
18121 +
18122 +       while (match && (match->inode != ino || match->device != dev ||
18123 +              (match->mode & GR_DELETED))) {
18124 +               match = match->next;
18125 +       }
18126 +
18127 +       if (match && !(match->mode & GR_DELETED))
18128 +               return match;
18129 +       else
18130 +               return NULL;
18131 +}
18132 +
18133 +static struct name_entry *
18134 +lookup_name_entry(const char *name)
18135 +{
18136 +       unsigned int len = strlen(name);
18137 +       unsigned int key = full_name_hash(name, len);
18138 +       unsigned int index = key % name_set.n_size;
18139 +       struct name_entry *match;
18140 +
18141 +       match = name_set.n_hash[index];
18142 +
18143 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len)))
18144 +               match = match->next;
18145 +
18146 +       return match;
18147 +}
18148 +
18149 +static struct name_entry *
18150 +lookup_name_entry_create(const char *name)
18151 +{
18152 +       unsigned int len = strlen(name);
18153 +       unsigned int key = full_name_hash(name, len);
18154 +       unsigned int index = key % name_set.n_size;
18155 +       struct name_entry *match;
18156 +
18157 +       match = name_set.n_hash[index];
18158 +
18159 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18160 +                        !match->deleted))
18161 +               match = match->next;
18162 +
18163 +       if (match && match->deleted)
18164 +               return match;
18165 +
18166 +       match = name_set.n_hash[index];
18167 +
18168 +       while (match && (match->key != key || !gr_streq(match->name, name, match->len, len) ||
18169 +                        match->deleted))
18170 +               match = match->next;
18171 +
18172 +       if (match && !match->deleted)
18173 +               return match;
18174 +       else
18175 +               return NULL;
18176 +}
18177 +
18178 +static struct inodev_entry *
18179 +lookup_inodev_entry(const ino_t ino, const dev_t dev)
18180 +{
18181 +       unsigned int index = fhash(ino, dev, inodev_set.i_size);
18182 +       struct inodev_entry *match;
18183 +
18184 +       match = inodev_set.i_hash[index];
18185 +
18186 +       while (match && (match->nentry->inode != ino || match->nentry->device != dev))
18187 +               match = match->next;
18188 +
18189 +       return match;
18190 +}
18191 +
18192 +static void
18193 +insert_inodev_entry(struct inodev_entry *entry)
18194 +{
18195 +       unsigned int index = fhash(entry->nentry->inode, entry->nentry->device,
18196 +                                   inodev_set.i_size);
18197 +       struct inodev_entry **curr;
18198 +
18199 +       entry->prev = NULL;
18200 +
18201 +       curr = &inodev_set.i_hash[index];
18202 +       if (*curr != NULL)
18203 +               (*curr)->prev = entry;
18204 +       
18205 +       entry->next = *curr;
18206 +       *curr = entry;
18207 +
18208 +       return;
18209 +}
18210 +
18211 +static void
18212 +__insert_acl_role_label(struct acl_role_label *role, uid_t uidgid)
18213 +{
18214 +       unsigned int index =
18215 +           rhash(uidgid, role->roletype & (GR_ROLE_USER | GR_ROLE_GROUP), acl_role_set.r_size);
18216 +       struct acl_role_label **curr;
18217 +
18218 +       role->prev = NULL;
18219 +
18220 +       curr = &acl_role_set.r_hash[index];
18221 +       if (*curr != NULL)
18222 +               (*curr)->prev = role;
18223 +
18224 +       role->next = *curr;
18225 +       *curr = role;
18226 +
18227 +       return;
18228 +}
18229 +
18230 +static void
18231 +insert_acl_role_label(struct acl_role_label *role)
18232 +{
18233 +       int i;
18234 +
18235 +       if (role->roletype & GR_ROLE_DOMAIN) {
18236 +               for (i = 0; i < role->domain_child_num; i++)
18237 +                       __insert_acl_role_label(role, role->domain_children[i]);
18238 +       } else
18239 +               __insert_acl_role_label(role, role->uidgid);
18240 +}
18241 +                                       
18242 +static int
18243 +insert_name_entry(char *name, const ino_t inode, const dev_t device, __u8 deleted)
18244 +{
18245 +       struct name_entry **curr, *nentry;
18246 +       struct inodev_entry *ientry;
18247 +       unsigned int len = strlen(name);
18248 +       unsigned int key = full_name_hash(name, len);
18249 +       unsigned int index = key % name_set.n_size;
18250 +
18251 +       curr = &name_set.n_hash[index];
18252 +
18253 +       while (*curr && ((*curr)->key != key || !gr_streq((*curr)->name, name, (*curr)->len, len)))
18254 +               curr = &((*curr)->next);
18255 +
18256 +       if (*curr != NULL)
18257 +               return 1;
18258 +
18259 +       nentry = acl_alloc(sizeof (struct name_entry));
18260 +       if (nentry == NULL)
18261 +               return 0;
18262 +       ientry = acl_alloc(sizeof (struct inodev_entry));
18263 +       if (ientry == NULL)
18264 +               return 0;
18265 +       ientry->nentry = nentry;
18266 +
18267 +       nentry->key = key;
18268 +       nentry->name = name;
18269 +       nentry->inode = inode;
18270 +       nentry->device = device;
18271 +       nentry->len = len;
18272 +       nentry->deleted = deleted;
18273 +
18274 +       nentry->prev = NULL;
18275 +       curr = &name_set.n_hash[index];
18276 +       if (*curr != NULL)
18277 +               (*curr)->prev = nentry;
18278 +       nentry->next = *curr;
18279 +       *curr = nentry;
18280 +
18281 +       /* insert us into the table searchable by inode/dev */
18282 +       insert_inodev_entry(ientry);
18283 +
18284 +       return 1;
18285 +}
18286 +
18287 +static void
18288 +insert_acl_obj_label(struct acl_object_label *obj,
18289 +                    struct acl_subject_label *subj)
18290 +{
18291 +       unsigned int index =
18292 +           fhash(obj->inode, obj->device, subj->obj_hash_size);
18293 +       struct acl_object_label **curr;
18294 +
18295 +       
18296 +       obj->prev = NULL;
18297 +
18298 +       curr = &subj->obj_hash[index];
18299 +       if (*curr != NULL)
18300 +               (*curr)->prev = obj;
18301 +
18302 +       obj->next = *curr;
18303 +       *curr = obj;
18304 +
18305 +       return;
18306 +}
18307 +
18308 +static void
18309 +insert_acl_subj_label(struct acl_subject_label *obj,
18310 +                     struct acl_role_label *role)
18311 +{
18312 +       unsigned int index = fhash(obj->inode, obj->device, role->subj_hash_size);
18313 +       struct acl_subject_label **curr;
18314 +
18315 +       obj->prev = NULL;
18316 +
18317 +       curr = &role->subj_hash[index];
18318 +       if (*curr != NULL)
18319 +               (*curr)->prev = obj;
18320 +
18321 +       obj->next = *curr;
18322 +       *curr = obj;
18323 +
18324 +       return;
18325 +}
18326 +
18327 +/* allocating chained hash tables, so optimal size is where lambda ~ 1 */
18328 +
18329 +static void *
18330 +create_table(__u32 * len, int elementsize)
18331 +{
18332 +       unsigned int table_sizes[] = {
18333 +               7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381,
18334 +               32749, 65521, 131071, 262139, 524287, 1048573, 2097143,
18335 +               4194301, 8388593, 16777213, 33554393, 67108859, 134217689,
18336 +               268435399, 536870909, 1073741789, 2147483647
18337 +       };
18338 +       void *newtable = NULL;
18339 +       unsigned int pwr = 0;
18340 +
18341 +       while ((pwr < ((sizeof (table_sizes) / sizeof (table_sizes[0])) - 1)) &&
18342 +              table_sizes[pwr] <= *len)
18343 +               pwr++;
18344 +
18345 +       if (table_sizes[pwr] <= *len)
18346 +               return newtable;
18347 +
18348 +       if ((table_sizes[pwr] * elementsize) <= PAGE_SIZE)
18349 +               newtable =
18350 +                   kmalloc(table_sizes[pwr] * elementsize, GFP_KERNEL);
18351 +       else
18352 +               newtable = vmalloc(table_sizes[pwr] * elementsize);
18353 +
18354 +       *len = table_sizes[pwr];
18355 +
18356 +       return newtable;
18357 +}
18358 +
18359 +static int
18360 +init_variables(const struct gr_arg *arg)
18361 +{
18362 +       struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
18363 +       unsigned int stacksize;
18364 +
18365 +       subj_map_set.s_size = arg->role_db.num_subjects;
18366 +       acl_role_set.r_size = arg->role_db.num_roles + arg->role_db.num_domain_children;
18367 +       name_set.n_size = arg->role_db.num_objects;
18368 +       inodev_set.i_size = arg->role_db.num_objects;
18369 +
18370 +       if (!subj_map_set.s_size || !acl_role_set.r_size ||
18371 +           !name_set.n_size || !inodev_set.i_size)
18372 +               return 1;
18373 +
18374 +       if (!gr_init_uidset())
18375 +               return 1;
18376 +
18377 +       /* set up the stack that holds allocation info */
18378 +
18379 +       stacksize = arg->role_db.num_pointers + 5;
18380 +
18381 +       if (!acl_alloc_stack_init(stacksize))
18382 +               return 1;
18383 +
18384 +       /* grab reference for the real root dentry and vfsmount */
18385 +       read_lock(&reaper->fs->lock);
18386 +       real_root_mnt = mntget(reaper->fs->root.mnt);
18387 +       real_root = dget(reaper->fs->root.dentry);
18388 +       read_unlock(&reaper->fs->lock);
18389 +       
18390 +       fakefs_obj = acl_alloc(sizeof(struct acl_object_label));
18391 +       if (fakefs_obj == NULL)
18392 +               return 1;
18393 +       fakefs_obj->mode = GR_FIND | GR_READ | GR_WRITE | GR_EXEC;
18394 +
18395 +       subj_map_set.s_hash =
18396 +           (struct subject_map **) create_table(&subj_map_set.s_size, sizeof(void *));
18397 +       acl_role_set.r_hash =
18398 +           (struct acl_role_label **) create_table(&acl_role_set.r_size, sizeof(void *));
18399 +       name_set.n_hash = (struct name_entry **) create_table(&name_set.n_size, sizeof(void *));
18400 +       inodev_set.i_hash =
18401 +           (struct inodev_entry **) create_table(&inodev_set.i_size, sizeof(void *));
18402 +
18403 +       if (!subj_map_set.s_hash || !acl_role_set.r_hash ||
18404 +           !name_set.n_hash || !inodev_set.i_hash)
18405 +               return 1;
18406 +
18407 +       memset(subj_map_set.s_hash, 0,
18408 +              sizeof(struct subject_map *) * subj_map_set.s_size);
18409 +       memset(acl_role_set.r_hash, 0,
18410 +              sizeof (struct acl_role_label *) * acl_role_set.r_size);
18411 +       memset(name_set.n_hash, 0,
18412 +              sizeof (struct name_entry *) * name_set.n_size);
18413 +       memset(inodev_set.i_hash, 0,
18414 +              sizeof (struct inodev_entry *) * inodev_set.i_size);
18415 +
18416 +       return 0;
18417 +}
18418 +
18419 +/* free information not needed after startup
18420 +   currently contains user->kernel pointer mappings for subjects
18421 +*/
18422 +
18423 +static void
18424 +free_init_variables(void)
18425 +{
18426 +       __u32 i;
18427 +
18428 +       if (subj_map_set.s_hash) {
18429 +               for (i = 0; i < subj_map_set.s_size; i++) {
18430 +                       if (subj_map_set.s_hash[i]) {
18431 +                               kfree(subj_map_set.s_hash[i]);
18432 +                               subj_map_set.s_hash[i] = NULL;
18433 +                       }
18434 +               }
18435 +
18436 +               if ((subj_map_set.s_size * sizeof (struct subject_map *)) <=
18437 +                   PAGE_SIZE)
18438 +                       kfree(subj_map_set.s_hash);
18439 +               else
18440 +                       vfree(subj_map_set.s_hash);
18441 +       }
18442 +
18443 +       return;
18444 +}
18445 +
18446 +static void
18447 +free_variables(void)
18448 +{
18449 +       struct acl_subject_label *s;
18450 +       struct acl_role_label *r;
18451 +       struct task_struct *task, *task2;
18452 +       unsigned int i, x;
18453 +
18454 +       gr_clear_learn_entries();
18455 +
18456 +       read_lock(&tasklist_lock);
18457 +       do_each_thread(task2, task) {
18458 +               task->acl_sp_role = 0;
18459 +               task->acl_role_id = 0;
18460 +               task->acl = NULL;
18461 +               task->role = NULL;
18462 +       } while_each_thread(task2, task);
18463 +       read_unlock(&tasklist_lock);
18464 +
18465 +       /* release the reference to the real root dentry and vfsmount */
18466 +       if (real_root)
18467 +               dput(real_root);
18468 +       real_root = NULL;
18469 +       if (real_root_mnt)
18470 +               mntput(real_root_mnt);
18471 +       real_root_mnt = NULL;
18472 +
18473 +       /* free all object hash tables */
18474 +
18475 +       FOR_EACH_ROLE_START(r, i)
18476 +               if (r->subj_hash == NULL)
18477 +                       break;
18478 +               FOR_EACH_SUBJECT_START(r, s, x)
18479 +                       if (s->obj_hash == NULL)
18480 +                               break;
18481 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18482 +                               kfree(s->obj_hash);
18483 +                       else
18484 +                               vfree(s->obj_hash);
18485 +               FOR_EACH_SUBJECT_END(s, x)
18486 +               FOR_EACH_NESTED_SUBJECT_START(r, s)
18487 +                       if (s->obj_hash == NULL)
18488 +                               break;
18489 +                       if ((s->obj_hash_size * sizeof (struct acl_object_label *)) <= PAGE_SIZE)
18490 +                               kfree(s->obj_hash);
18491 +                       else
18492 +                               vfree(s->obj_hash);
18493 +               FOR_EACH_NESTED_SUBJECT_END(s)
18494 +               if ((r->subj_hash_size * sizeof (struct acl_subject_label *)) <= PAGE_SIZE)
18495 +                       kfree(r->subj_hash);
18496 +               else
18497 +                       vfree(r->subj_hash);
18498 +               r->subj_hash = NULL;
18499 +       FOR_EACH_ROLE_END(r,i)
18500 +
18501 +       acl_free_all();
18502 +
18503 +       if (acl_role_set.r_hash) {
18504 +               if ((acl_role_set.r_size * sizeof (struct acl_role_label *)) <=
18505 +                   PAGE_SIZE)
18506 +                       kfree(acl_role_set.r_hash);
18507 +               else
18508 +                       vfree(acl_role_set.r_hash);
18509 +       }
18510 +       if (name_set.n_hash) {
18511 +               if ((name_set.n_size * sizeof (struct name_entry *)) <=
18512 +                   PAGE_SIZE)
18513 +                       kfree(name_set.n_hash);
18514 +               else
18515 +                       vfree(name_set.n_hash);
18516 +       }
18517 +
18518 +       if (inodev_set.i_hash) {
18519 +               if ((inodev_set.i_size * sizeof (struct inodev_entry *)) <=
18520 +                   PAGE_SIZE)
18521 +                       kfree(inodev_set.i_hash);
18522 +               else
18523 +                       vfree(inodev_set.i_hash);
18524 +       }
18525 +
18526 +       gr_free_uidset();
18527 +
18528 +       memset(&name_set, 0, sizeof (struct name_db));
18529 +       memset(&inodev_set, 0, sizeof (struct inodev_db));
18530 +       memset(&acl_role_set, 0, sizeof (struct acl_role_db));
18531 +       memset(&subj_map_set, 0, sizeof (struct acl_subj_map_db));
18532 +
18533 +       default_role = NULL;
18534 +
18535 +       return;
18536 +}
18537 +
18538 +static __u32
18539 +count_user_objs(struct acl_object_label *userp)
18540 +{
18541 +       struct acl_object_label o_tmp;
18542 +       __u32 num = 0;
18543 +
18544 +       while (userp) {
18545 +               if (copy_from_user(&o_tmp, userp,
18546 +                                  sizeof (struct acl_object_label)))
18547 +                       break;
18548 +
18549 +               userp = o_tmp.prev;
18550 +               num++;
18551 +       }
18552 +
18553 +       return num;
18554 +}
18555 +
18556 +static struct acl_subject_label *
18557 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role);
18558 +
18559 +static int
18560 +copy_user_glob(struct acl_object_label *obj)
18561 +{
18562 +       struct acl_object_label *g_tmp, **guser;
18563 +       unsigned int len;
18564 +       char *tmp;
18565 +
18566 +       if (obj->globbed == NULL)
18567 +               return 0;
18568 +
18569 +       guser = &obj->globbed;
18570 +       while (*guser) {
18571 +               g_tmp = (struct acl_object_label *)
18572 +                       acl_alloc(sizeof (struct acl_object_label));
18573 +               if (g_tmp == NULL)
18574 +                       return -ENOMEM;
18575 +
18576 +               if (copy_from_user(g_tmp, *guser,
18577 +                                  sizeof (struct acl_object_label)))
18578 +                       return -EFAULT;
18579 +
18580 +               len = strnlen_user(g_tmp->filename, PATH_MAX);
18581 +
18582 +               if (!len || len >= PATH_MAX)
18583 +                       return -EINVAL;
18584 +
18585 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
18586 +                       return -ENOMEM;
18587 +
18588 +               if (copy_from_user(tmp, g_tmp->filename, len))
18589 +                       return -EFAULT;
18590 +
18591 +               g_tmp->filename = tmp;
18592 +
18593 +               *guser = g_tmp;
18594 +               guser = &(g_tmp->next);
18595 +       }
18596 +
18597 +       return 0;
18598 +}
18599 +
18600 +static int
18601 +copy_user_objs(struct acl_object_label *userp, struct acl_subject_label *subj,
18602 +              struct acl_role_label *role)
18603 +{
18604 +       struct acl_object_label *o_tmp;
18605 +       unsigned int len;
18606 +       int ret;
18607 +       char *tmp;
18608 +
18609 +       while (userp) {
18610 +               if ((o_tmp = (struct acl_object_label *)
18611 +                    acl_alloc(sizeof (struct acl_object_label))) == NULL)
18612 +                       return -ENOMEM;
18613 +
18614 +               if (copy_from_user(o_tmp, userp,
18615 +                                  sizeof (struct acl_object_label)))
18616 +                       return -EFAULT;
18617 +
18618 +               userp = o_tmp->prev;
18619 +
18620 +               len = strnlen_user(o_tmp->filename, PATH_MAX);
18621 +
18622 +               if (!len || len >= PATH_MAX)
18623 +                       return -EINVAL;
18624 +
18625 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
18626 +                       return -ENOMEM;
18627 +
18628 +               if (copy_from_user(tmp, o_tmp->filename, len))
18629 +                       return -EFAULT;
18630 +
18631 +               o_tmp->filename = tmp;
18632 +
18633 +               insert_acl_obj_label(o_tmp, subj);
18634 +               if (!insert_name_entry(o_tmp->filename, o_tmp->inode,
18635 +                                      o_tmp->device, (o_tmp->mode & GR_DELETED) ? 1 : 0))
18636 +                       return -ENOMEM;
18637 +
18638 +               ret = copy_user_glob(o_tmp);
18639 +               if (ret)
18640 +                       return ret;
18641 +
18642 +               if (o_tmp->nested) {
18643 +                       o_tmp->nested = do_copy_user_subj(o_tmp->nested, role);
18644 +                       if (IS_ERR(o_tmp->nested))
18645 +                               return PTR_ERR(o_tmp->nested);
18646 +
18647 +                       /* insert into nested subject list */
18648 +                       o_tmp->nested->next = role->hash->first;
18649 +                       role->hash->first = o_tmp->nested;
18650 +               }
18651 +       }
18652 +
18653 +       return 0;
18654 +}
18655 +
18656 +static __u32
18657 +count_user_subjs(struct acl_subject_label *userp)
18658 +{
18659 +       struct acl_subject_label s_tmp;
18660 +       __u32 num = 0;
18661 +
18662 +       while (userp) {
18663 +               if (copy_from_user(&s_tmp, userp,
18664 +                                  sizeof (struct acl_subject_label)))
18665 +                       break;
18666 +
18667 +               userp = s_tmp.prev;
18668 +               /* do not count nested subjects against this count, since
18669 +                  they are not included in the hash table, but are
18670 +                  attached to objects.  We have already counted
18671 +                  the subjects in userspace for the allocation 
18672 +                  stack
18673 +               */
18674 +               if (!(s_tmp.mode & GR_NESTED))
18675 +                       num++;
18676 +       }
18677 +
18678 +       return num;
18679 +}
18680 +
18681 +static int
18682 +copy_user_allowedips(struct acl_role_label *rolep)
18683 +{
18684 +       struct role_allowed_ip *ruserip, *rtmp = NULL, *rlast;
18685 +
18686 +       ruserip = rolep->allowed_ips;
18687 +
18688 +       while (ruserip) {
18689 +               rlast = rtmp;
18690 +
18691 +               if ((rtmp = (struct role_allowed_ip *)
18692 +                    acl_alloc(sizeof (struct role_allowed_ip))) == NULL)
18693 +                       return -ENOMEM;
18694 +
18695 +               if (copy_from_user(rtmp, ruserip,
18696 +                                  sizeof (struct role_allowed_ip)))
18697 +                       return -EFAULT;
18698 +
18699 +               ruserip = rtmp->prev;
18700 +
18701 +               if (!rlast) {
18702 +                       rtmp->prev = NULL;
18703 +                       rolep->allowed_ips = rtmp;
18704 +               } else {
18705 +                       rlast->next = rtmp;
18706 +                       rtmp->prev = rlast;
18707 +               }
18708 +
18709 +               if (!ruserip)
18710 +                       rtmp->next = NULL;
18711 +       }
18712 +
18713 +       return 0;
18714 +}
18715 +
18716 +static int
18717 +copy_user_transitions(struct acl_role_label *rolep)
18718 +{
18719 +       struct role_transition *rusertp, *rtmp = NULL, *rlast;
18720 +       
18721 +       unsigned int len;
18722 +       char *tmp;
18723 +
18724 +       rusertp = rolep->transitions;
18725 +
18726 +       while (rusertp) {
18727 +               rlast = rtmp;
18728 +
18729 +               if ((rtmp = (struct role_transition *)
18730 +                    acl_alloc(sizeof (struct role_transition))) == NULL)
18731 +                       return -ENOMEM;
18732 +
18733 +               if (copy_from_user(rtmp, rusertp,
18734 +                                  sizeof (struct role_transition)))
18735 +                       return -EFAULT;
18736 +
18737 +               rusertp = rtmp->prev;
18738 +
18739 +               len = strnlen_user(rtmp->rolename, GR_SPROLE_LEN);
18740 +
18741 +               if (!len || len >= GR_SPROLE_LEN)
18742 +                       return -EINVAL;
18743 +
18744 +               if ((tmp = (char *) acl_alloc(len)) == NULL)
18745 +                       return -ENOMEM;
18746 +
18747 +               if (copy_from_user(tmp, rtmp->rolename, len))
18748 +                       return -EFAULT;
18749 +
18750 +               rtmp->rolename = tmp;
18751 +
18752 +               if (!rlast) {
18753 +                       rtmp->prev = NULL;
18754 +                       rolep->transitions = rtmp;
18755 +               } else {
18756 +                       rlast->next = rtmp;
18757 +                       rtmp->prev = rlast;
18758 +               }
18759 +
18760 +               if (!rusertp)
18761 +                       rtmp->next = NULL;
18762 +       }
18763 +
18764 +       return 0;
18765 +}
18766 +
18767 +static struct acl_subject_label *
18768 +do_copy_user_subj(struct acl_subject_label *userp, struct acl_role_label *role)
18769 +{
18770 +       struct acl_subject_label *s_tmp = NULL, *s_tmp2;
18771 +       unsigned int len;
18772 +       char *tmp;
18773 +       __u32 num_objs;
18774 +       struct acl_ip_label **i_tmp, *i_utmp2;
18775 +       struct gr_hash_struct ghash;
18776 +       struct subject_map *subjmap;
18777 +       unsigned int i_num;
18778 +       int err;
18779 +
18780 +       s_tmp = lookup_subject_map(userp);
18781 +
18782 +       /* we've already copied this subject into the kernel, just return
18783 +          the reference to it, and don't copy it over again
18784 +       */
18785 +       if (s_tmp)
18786 +               return(s_tmp);
18787 +
18788 +       if ((s_tmp = (struct acl_subject_label *)
18789 +           acl_alloc(sizeof (struct acl_subject_label))) == NULL)
18790 +               return ERR_PTR(-ENOMEM);
18791 +
18792 +       subjmap = (struct subject_map *)kmalloc(sizeof (struct subject_map), GFP_KERNEL);
18793 +       if (subjmap == NULL)
18794 +               return ERR_PTR(-ENOMEM);
18795 +
18796 +       subjmap->user = userp;
18797 +       subjmap->kernel = s_tmp;
18798 +       insert_subj_map_entry(subjmap);
18799 +
18800 +       if (copy_from_user(s_tmp, userp,
18801 +                          sizeof (struct acl_subject_label)))
18802 +               return ERR_PTR(-EFAULT);
18803 +
18804 +       len = strnlen_user(s_tmp->filename, PATH_MAX);
18805 +
18806 +       if (!len || len >= PATH_MAX)
18807 +               return ERR_PTR(-EINVAL);
18808 +
18809 +       if ((tmp = (char *) acl_alloc(len)) == NULL)
18810 +               return ERR_PTR(-ENOMEM);
18811 +
18812 +       if (copy_from_user(tmp, s_tmp->filename, len))
18813 +               return ERR_PTR(-EFAULT);
18814 +
18815 +       s_tmp->filename = tmp;
18816 +
18817 +       if (!strcmp(s_tmp->filename, "/"))
18818 +               role->root_label = s_tmp;
18819 +
18820 +       if (copy_from_user(&ghash, s_tmp->hash, sizeof(struct gr_hash_struct)))
18821 +               return ERR_PTR(-EFAULT);
18822 +
18823 +       /* copy user and group transition tables */
18824 +
18825 +       if (s_tmp->user_trans_num) {
18826 +               uid_t *uidlist;
18827 +
18828 +               uidlist = (uid_t *)acl_alloc(s_tmp->user_trans_num * sizeof(uid_t));
18829 +               if (uidlist == NULL)
18830 +                       return ERR_PTR(-ENOMEM);
18831 +               if (copy_from_user(uidlist, s_tmp->user_transitions, s_tmp->user_trans_num * sizeof(uid_t)))
18832 +                       return ERR_PTR(-EFAULT);
18833 +
18834 +               s_tmp->user_transitions = uidlist;
18835 +       }
18836 +
18837 +       if (s_tmp->group_trans_num) {
18838 +               gid_t *gidlist;
18839 +
18840 +               gidlist = (gid_t *)acl_alloc(s_tmp->group_trans_num * sizeof(gid_t));
18841 +               if (gidlist == NULL)
18842 +                       return ERR_PTR(-ENOMEM);
18843 +               if (copy_from_user(gidlist, s_tmp->group_transitions, s_tmp->group_trans_num * sizeof(gid_t)))
18844 +                       return ERR_PTR(-EFAULT);
18845 +
18846 +               s_tmp->group_transitions = gidlist;
18847 +       }
18848 +
18849 +       /* set up object hash table */
18850 +       num_objs = count_user_objs(ghash.first);
18851 +
18852 +       s_tmp->obj_hash_size = num_objs;
18853 +       s_tmp->obj_hash =
18854 +           (struct acl_object_label **)
18855 +           create_table(&(s_tmp->obj_hash_size), sizeof(void *));
18856 +
18857 +       if (!s_tmp->obj_hash)
18858 +               return ERR_PTR(-ENOMEM);
18859 +
18860 +       memset(s_tmp->obj_hash, 0,
18861 +              s_tmp->obj_hash_size *
18862 +              sizeof (struct acl_object_label *));
18863 +
18864 +       /* add in objects */
18865 +       err = copy_user_objs(ghash.first, s_tmp, role);
18866 +
18867 +       if (err)
18868 +               return ERR_PTR(err);
18869 +
18870 +       /* set pointer for parent subject */
18871 +       if (s_tmp->parent_subject) {
18872 +               s_tmp2 = do_copy_user_subj(s_tmp->parent_subject, role);
18873 +
18874 +               if (IS_ERR(s_tmp2))
18875 +                       return s_tmp2;
18876 +
18877 +               s_tmp->parent_subject = s_tmp2;
18878 +       }
18879 +
18880 +       /* add in ip acls */
18881 +
18882 +       if (!s_tmp->ip_num) {
18883 +               s_tmp->ips = NULL;
18884 +               goto insert;
18885 +       }
18886 +
18887 +       i_tmp =
18888 +           (struct acl_ip_label **) acl_alloc(s_tmp->ip_num *
18889 +                                              sizeof (struct
18890 +                                                      acl_ip_label *));
18891 +
18892 +       if (!i_tmp)
18893 +               return ERR_PTR(-ENOMEM);
18894 +
18895 +       for (i_num = 0; i_num < s_tmp->ip_num; i_num++) {
18896 +               *(i_tmp + i_num) =
18897 +                   (struct acl_ip_label *)
18898 +                   acl_alloc(sizeof (struct acl_ip_label));
18899 +               if (!*(i_tmp + i_num))
18900 +                       return ERR_PTR(-ENOMEM);
18901 +
18902 +               if (copy_from_user
18903 +                   (&i_utmp2, s_tmp->ips + i_num,
18904 +                    sizeof (struct acl_ip_label *)))
18905 +                       return ERR_PTR(-EFAULT);
18906 +
18907 +               if (copy_from_user
18908 +                   (*(i_tmp + i_num), i_utmp2,
18909 +                    sizeof (struct acl_ip_label)))
18910 +                       return ERR_PTR(-EFAULT);
18911 +               
18912 +               if ((*(i_tmp + i_num))->iface == NULL)
18913 +                       continue;
18914 +
18915 +               len = strnlen_user((*(i_tmp + i_num))->iface, IFNAMSIZ);
18916 +               if (!len || len >= IFNAMSIZ)
18917 +                       return ERR_PTR(-EINVAL);
18918 +               tmp = acl_alloc(len);
18919 +               if (tmp == NULL)
18920 +                       return ERR_PTR(-ENOMEM);
18921 +               if (copy_from_user(tmp, (*(i_tmp + i_num))->iface, len))
18922 +                       return ERR_PTR(-EFAULT);
18923 +               (*(i_tmp + i_num))->iface = tmp;
18924 +       }
18925 +
18926 +       s_tmp->ips = i_tmp;
18927 +
18928 +insert:
18929 +       if (!insert_name_entry(s_tmp->filename, s_tmp->inode,
18930 +                              s_tmp->device, (s_tmp->mode & GR_DELETED) ? 1 : 0))
18931 +               return ERR_PTR(-ENOMEM);
18932 +
18933 +       return s_tmp;
18934 +}
18935 +
18936 +static int
18937 +copy_user_subjs(struct acl_subject_label *userp, struct acl_role_label *role)
18938 +{
18939 +       struct acl_subject_label s_pre;
18940 +       struct acl_subject_label * ret;
18941 +       int err;
18942 +
18943 +       while (userp) {
18944 +               if (copy_from_user(&s_pre, userp,
18945 +                                  sizeof (struct acl_subject_label)))
18946 +                       return -EFAULT;
18947 +               
18948 +               /* do not add nested subjects here, add
18949 +                  while parsing objects
18950 +               */
18951 +
18952 +               if (s_pre.mode & GR_NESTED) {
18953 +                       userp = s_pre.prev;
18954 +                       continue;
18955 +               }
18956 +
18957 +               ret = do_copy_user_subj(userp, role);
18958 +
18959 +               err = PTR_ERR(ret);
18960 +               if (IS_ERR(ret))
18961 +                       return err;
18962 +
18963 +               insert_acl_subj_label(ret, role);
18964 +
18965 +               userp = s_pre.prev;
18966 +       }
18967 +
18968 +       return 0;
18969 +}
18970 +
18971 +static int
18972 +copy_user_acl(struct gr_arg *arg)
18973 +{
18974 +       struct acl_role_label *r_tmp = NULL, **r_utmp, *r_utmp2;
18975 +       struct sprole_pw *sptmp;
18976 +       struct gr_hash_struct *ghash;
18977 +       uid_t *domainlist;
18978 +       unsigned int r_num;
18979 +       unsigned int len;
18980 +       char *tmp;
18981 +       int err = 0;
18982 +       __u16 i;
18983 +       __u32 num_subjs;
18984 +
18985 +       /* we need a default and kernel role */
18986 +       if (arg->role_db.num_roles < 2)
18987 +               return -EINVAL;
18988 +
18989 +       /* copy special role authentication info from userspace */
18990 +
18991 +       num_sprole_pws = arg->num_sprole_pws;
18992 +       acl_special_roles = (struct sprole_pw **) acl_alloc(num_sprole_pws * sizeof(struct sprole_pw *));
18993 +
18994 +       if (!acl_special_roles) {
18995 +               err = -ENOMEM;
18996 +               goto cleanup;
18997 +       }
18998 +
18999 +       for (i = 0; i < num_sprole_pws; i++) {
19000 +               sptmp = (struct sprole_pw *) acl_alloc(sizeof(struct sprole_pw));
19001 +               if (!sptmp) {
19002 +                       err = -ENOMEM;
19003 +                       goto cleanup;
19004 +               }
19005 +               if (copy_from_user(sptmp, arg->sprole_pws + i,
19006 +                                  sizeof (struct sprole_pw))) {
19007 +                       err = -EFAULT;
19008 +                       goto cleanup;
19009 +               }
19010 +
19011 +               len =
19012 +                   strnlen_user(sptmp->rolename, GR_SPROLE_LEN);
19013 +
19014 +               if (!len || len >= GR_SPROLE_LEN) {
19015 +                       err = -EINVAL;
19016 +                       goto cleanup;
19017 +               }
19018 +
19019 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
19020 +                       err = -ENOMEM;
19021 +                       goto cleanup;
19022 +               }
19023 +
19024 +               if (copy_from_user(tmp, sptmp->rolename, len)) {
19025 +                       err = -EFAULT;
19026 +                       goto cleanup;
19027 +               }
19028 +
19029 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19030 +               printk(KERN_ALERT "Copying special role %s\n", tmp);
19031 +#endif
19032 +               sptmp->rolename = tmp;
19033 +               acl_special_roles[i] = sptmp;
19034 +       }
19035 +
19036 +       r_utmp = (struct acl_role_label **) arg->role_db.r_table;
19037 +
19038 +       for (r_num = 0; r_num < arg->role_db.num_roles; r_num++) {
19039 +               r_tmp = acl_alloc(sizeof (struct acl_role_label));
19040 +
19041 +               if (!r_tmp) {
19042 +                       err = -ENOMEM;
19043 +                       goto cleanup;
19044 +               }
19045 +
19046 +               if (copy_from_user(&r_utmp2, r_utmp + r_num,
19047 +                                  sizeof (struct acl_role_label *))) {
19048 +                       err = -EFAULT;
19049 +                       goto cleanup;
19050 +               }
19051 +
19052 +               if (copy_from_user(r_tmp, r_utmp2,
19053 +                                  sizeof (struct acl_role_label))) {
19054 +                       err = -EFAULT;
19055 +                       goto cleanup;
19056 +               }
19057 +
19058 +               len = strnlen_user(r_tmp->rolename, GR_SPROLE_LEN);
19059 +
19060 +               if (!len || len >= PATH_MAX) {
19061 +                       err = -EINVAL;
19062 +                       goto cleanup;
19063 +               }
19064 +
19065 +               if ((tmp = (char *) acl_alloc(len)) == NULL) {
19066 +                       err = -ENOMEM;
19067 +                       goto cleanup;
19068 +               }
19069 +               if (copy_from_user(tmp, r_tmp->rolename, len)) {
19070 +                       err = -EFAULT;
19071 +                       goto cleanup;
19072 +               }
19073 +               r_tmp->rolename = tmp;
19074 +
19075 +               if (!strcmp(r_tmp->rolename, "default")
19076 +                   && (r_tmp->roletype & GR_ROLE_DEFAULT)) {
19077 +                       default_role = r_tmp;
19078 +               } else if (!strcmp(r_tmp->rolename, ":::kernel:::")) {
19079 +                       kernel_role = r_tmp;
19080 +               }
19081 +
19082 +               if ((ghash = (struct gr_hash_struct *) acl_alloc(sizeof(struct gr_hash_struct))) == NULL) {
19083 +                       err = -ENOMEM;
19084 +                       goto cleanup;
19085 +               }
19086 +               if (copy_from_user(ghash, r_tmp->hash, sizeof(struct gr_hash_struct))) {
19087 +                       err = -EFAULT;
19088 +                       goto cleanup;
19089 +               }
19090 +
19091 +               r_tmp->hash = ghash;
19092 +
19093 +               num_subjs = count_user_subjs(r_tmp->hash->first);
19094 +
19095 +               r_tmp->subj_hash_size = num_subjs;
19096 +               r_tmp->subj_hash =
19097 +                   (struct acl_subject_label **)
19098 +                   create_table(&(r_tmp->subj_hash_size), sizeof(void *));
19099 +
19100 +               if (!r_tmp->subj_hash) {
19101 +                       err = -ENOMEM;
19102 +                       goto cleanup;
19103 +               }
19104 +
19105 +               err = copy_user_allowedips(r_tmp);
19106 +               if (err)
19107 +                       goto cleanup;
19108 +
19109 +               /* copy domain info */
19110 +               if (r_tmp->domain_children != NULL) {
19111 +                       domainlist = acl_alloc(r_tmp->domain_child_num * sizeof(uid_t));
19112 +                       if (domainlist == NULL) {
19113 +                               err = -ENOMEM;
19114 +                               goto cleanup;
19115 +                       }
19116 +                       if (copy_from_user(domainlist, r_tmp->domain_children, r_tmp->domain_child_num * sizeof(uid_t))) {
19117 +                               err = -EFAULT;
19118 +                               goto cleanup;
19119 +                       }
19120 +                       r_tmp->domain_children = domainlist;
19121 +               }
19122 +
19123 +               err = copy_user_transitions(r_tmp);
19124 +               if (err)
19125 +                       goto cleanup;
19126 +
19127 +               memset(r_tmp->subj_hash, 0,
19128 +                      r_tmp->subj_hash_size *
19129 +                      sizeof (struct acl_subject_label *));
19130 +
19131 +               err = copy_user_subjs(r_tmp->hash->first, r_tmp);
19132 +
19133 +               if (err)
19134 +                       goto cleanup;
19135 +
19136 +               /* set nested subject list to null */
19137 +               r_tmp->hash->first = NULL;
19138 +
19139 +               insert_acl_role_label(r_tmp);
19140 +       }
19141 +
19142 +       goto return_err;
19143 +      cleanup:
19144 +       free_variables();
19145 +      return_err:
19146 +       return err;
19147 +
19148 +}
19149 +
19150 +static int
19151 +gracl_init(struct gr_arg *args)
19152 +{
19153 +       int error = 0;
19154 +
19155 +       memcpy(gr_system_salt, args->salt, GR_SALT_LEN);
19156 +       memcpy(gr_system_sum, args->sum, GR_SHA_LEN);
19157 +
19158 +       if (init_variables(args)) {
19159 +               gr_log_str(GR_DONT_AUDIT_GOOD, GR_INITF_ACL_MSG, GR_VERSION);
19160 +               error = -ENOMEM;
19161 +               free_variables();
19162 +               goto out;
19163 +       }
19164 +
19165 +       error = copy_user_acl(args);
19166 +       free_init_variables();
19167 +       if (error) {
19168 +               free_variables();
19169 +               goto out;
19170 +       }
19171 +
19172 +       if ((error = gr_set_acls(0))) {
19173 +               free_variables();
19174 +               goto out;
19175 +       }
19176 +
19177 +       gr_status |= GR_READY;
19178 +      out:
19179 +       return error;
19180 +}
19181 +
19182 +/* derived from glibc fnmatch() 0: match, 1: no match*/
19183 +
19184 +static int
19185 +glob_match(const char *p, const char *n)
19186 +{
19187 +       char c;
19188 +
19189 +       while ((c = *p++) != '\0') {
19190 +       switch (c) {
19191 +               case '?':
19192 +                       if (*n == '\0')
19193 +                               return 1;
19194 +                       else if (*n == '/')
19195 +                               return 1;
19196 +                       break;
19197 +               case '\\':
19198 +                       if (*n != c)
19199 +                               return 1;
19200 +                       break;
19201 +               case '*':
19202 +                       for (c = *p++; c == '?' || c == '*'; c = *p++) {
19203 +                               if (*n == '/')
19204 +                                       return 1;
19205 +                               else if (c == '?') {
19206 +                                       if (*n == '\0')
19207 +                                               return 1;
19208 +                                       else
19209 +                                               ++n;
19210 +                               }
19211 +                       }
19212 +                       if (c == '\0') {
19213 +                               return 0;
19214 +                       } else {
19215 +                               const char *endp;
19216 +
19217 +                               if ((endp = strchr(n, '/')) == NULL)
19218 +                                       endp = n + strlen(n);
19219 +
19220 +                               if (c == '[') {
19221 +                                       for (--p; n < endp; ++n)
19222 +                                               if (!glob_match(p, n))
19223 +                                                       return 0;
19224 +                               } else if (c == '/') {
19225 +                                       while (*n != '\0' && *n != '/')
19226 +                                               ++n;
19227 +                                       if (*n == '/' && !glob_match(p, n + 1))
19228 +                                               return 0;
19229 +                               } else {
19230 +                                       for (--p; n < endp; ++n)
19231 +                                               if (*n == c && !glob_match(p, n))
19232 +                                                       return 0;
19233 +                               }
19234 +
19235 +                               return 1;
19236 +                       }
19237 +               case '[':
19238 +                       {
19239 +                       int not;
19240 +                       char cold;
19241 +
19242 +                       if (*n == '\0' || *n == '/')
19243 +                               return 1;
19244 +
19245 +                       not = (*p == '!' || *p == '^');
19246 +                       if (not)
19247 +                               ++p;
19248 +
19249 +                       c = *p++;
19250 +                       for (;;) {
19251 +                               unsigned char fn = (unsigned char)*n;
19252 +
19253 +                               if (c == '\0')
19254 +                                       return 1;
19255 +                               else {
19256 +                                       if (c == fn)
19257 +                                               goto matched;
19258 +                                       cold = c;
19259 +                                       c = *p++;
19260 +
19261 +                                       if (c == '-' && *p != ']') {
19262 +                                               unsigned char cend = *p++;
19263 +
19264 +                                               if (cend == '\0')
19265 +                                                       return 1;
19266 +
19267 +                                               if (cold <= fn && fn <= cend)
19268 +                                                       goto matched;
19269 +
19270 +                                               c = *p++;
19271 +                                       }
19272 +                               }
19273 +
19274 +                               if (c == ']')
19275 +                                       break;
19276 +                       }
19277 +                       if (!not)
19278 +                               return 1;
19279 +                       break;
19280 +               matched:
19281 +                       while (c != ']') {
19282 +                               if (c == '\0')
19283 +                                       return 1;
19284 +
19285 +                               c = *p++;
19286 +                       }
19287 +                       if (not)
19288 +                               return 1;
19289 +               }
19290 +               break;
19291 +       default:
19292 +               if (c != *n)
19293 +                       return 1;
19294 +       }
19295 +
19296 +       ++n;
19297 +       }
19298 +
19299 +       if (*n == '\0')
19300 +               return 0;
19301 +
19302 +       if (*n == '/')
19303 +               return 0;
19304 +
19305 +       return 1;
19306 +}
19307 +
19308 +static struct acl_object_label *
19309 +chk_glob_label(struct acl_object_label *globbed,
19310 +       struct dentry *dentry, struct vfsmount *mnt, char **path)
19311 +{
19312 +       struct acl_object_label *tmp;
19313 +
19314 +       if (*path == NULL)
19315 +               *path = gr_to_filename_nolock(dentry, mnt);
19316 +
19317 +       tmp = globbed;
19318 +
19319 +       while (tmp) {
19320 +               if (!glob_match(tmp->filename, *path))
19321 +                       return tmp;
19322 +               tmp = tmp->next;
19323 +       }
19324 +
19325 +       return NULL;
19326 +}
19327 +
19328 +static struct acl_object_label *
19329 +__full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19330 +           const ino_t curr_ino, const dev_t curr_dev,
19331 +           const struct acl_subject_label *subj, char **path)
19332 +{
19333 +       struct acl_subject_label *tmpsubj;
19334 +       struct acl_object_label *retval;
19335 +       struct acl_object_label *retval2;
19336 +
19337 +       tmpsubj = (struct acl_subject_label *) subj;
19338 +       read_lock(&gr_inode_lock);
19339 +       do {
19340 +               retval = lookup_acl_obj_label(curr_ino, curr_dev, tmpsubj);
19341 +               if (retval) {
19342 +                       if (retval->globbed) {
19343 +                               retval2 = chk_glob_label(retval->globbed, (struct dentry *)orig_dentry,
19344 +                                               (struct vfsmount *)orig_mnt, path);
19345 +                               if (retval2)
19346 +                                       retval = retval2;
19347 +                       }
19348 +                       break;
19349 +               }
19350 +       } while ((tmpsubj = tmpsubj->parent_subject));
19351 +       read_unlock(&gr_inode_lock);
19352 +
19353 +       return retval;
19354 +}
19355 +
19356 +static __inline__ struct acl_object_label *
19357 +full_lookup(const struct dentry *orig_dentry, const struct vfsmount *orig_mnt,
19358 +           const struct dentry *curr_dentry,
19359 +           const struct acl_subject_label *subj, char **path)
19360 +{
19361 +       return __full_lookup(orig_dentry, orig_mnt,
19362 +                            curr_dentry->d_inode->i_ino, 
19363 +                            curr_dentry->d_inode->i_sb->s_dev, subj, path);
19364 +}
19365 +
19366 +static struct acl_object_label *
19367 +__chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19368 +             const struct acl_subject_label *subj, char *path)
19369 +{
19370 +       struct dentry *dentry = (struct dentry *) l_dentry;
19371 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19372 +       struct acl_object_label *retval;
19373 +
19374 +       spin_lock(&dcache_lock);
19375 +
19376 +       if (unlikely(mnt == shm_mnt || mnt == pipe_mnt || mnt == sock_mnt ||
19377 +               /* ignore Eric Biederman */
19378 +           IS_PRIVATE(l_dentry->d_inode))) {
19379 +               retval = fakefs_obj;
19380 +               goto out;
19381 +       }
19382 +
19383 +       for (;;) {
19384 +               if (dentry == real_root && mnt == real_root_mnt)
19385 +                       break;
19386 +
19387 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19388 +                       if (mnt->mnt_parent == mnt)
19389 +                               break;
19390 +
19391 +                       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19392 +                       if (retval != NULL)
19393 +                               goto out;
19394 +
19395 +                       dentry = mnt->mnt_mountpoint;
19396 +                       mnt = mnt->mnt_parent;
19397 +                       continue;
19398 +               }
19399 +
19400 +               retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19401 +               if (retval != NULL)
19402 +                       goto out;
19403 +
19404 +               dentry = dentry->d_parent;
19405 +       }
19406 +
19407 +       retval = full_lookup(l_dentry, l_mnt, dentry, subj, &path);
19408 +
19409 +       if (retval == NULL)
19410 +               retval = full_lookup(l_dentry, l_mnt, real_root, subj, &path);
19411 +out:
19412 +       spin_unlock(&dcache_lock);
19413 +       return retval;
19414 +}
19415 +
19416 +static __inline__ struct acl_object_label *
19417 +chk_obj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19418 +             const struct acl_subject_label *subj)
19419 +{
19420 +       char *path = NULL;
19421 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
19422 +}
19423 +
19424 +static __inline__ struct acl_object_label *
19425 +chk_obj_create_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19426 +                    const struct acl_subject_label *subj, char *path)
19427 +{
19428 +       return __chk_obj_label(l_dentry, l_mnt, subj, path);
19429 +}
19430 +
19431 +static struct acl_subject_label *
19432 +chk_subj_label(const struct dentry *l_dentry, const struct vfsmount *l_mnt,
19433 +              const struct acl_role_label *role)
19434 +{
19435 +       struct dentry *dentry = (struct dentry *) l_dentry;
19436 +       struct vfsmount *mnt = (struct vfsmount *) l_mnt;
19437 +       struct acl_subject_label *retval;
19438 +
19439 +       spin_lock(&dcache_lock);
19440 +
19441 +       for (;;) {
19442 +               if (dentry == real_root && mnt == real_root_mnt)
19443 +                       break;
19444 +               if (dentry == mnt->mnt_root || IS_ROOT(dentry)) {
19445 +                       if (mnt->mnt_parent == mnt)
19446 +                               break;
19447 +
19448 +                       read_lock(&gr_inode_lock);
19449 +                       retval =
19450 +                               lookup_acl_subj_label(dentry->d_inode->i_ino,
19451 +                                               dentry->d_inode->i_sb->s_dev, role);
19452 +                       read_unlock(&gr_inode_lock);
19453 +                       if (retval != NULL)
19454 +                               goto out;
19455 +
19456 +                       dentry = mnt->mnt_mountpoint;
19457 +                       mnt = mnt->mnt_parent;
19458 +                       continue;
19459 +               }
19460 +
19461 +               read_lock(&gr_inode_lock);
19462 +               retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19463 +                                         dentry->d_inode->i_sb->s_dev, role);
19464 +               read_unlock(&gr_inode_lock);
19465 +               if (retval != NULL)
19466 +                       goto out;
19467 +
19468 +               dentry = dentry->d_parent;
19469 +       }
19470 +
19471 +       read_lock(&gr_inode_lock);
19472 +       retval = lookup_acl_subj_label(dentry->d_inode->i_ino,
19473 +                                 dentry->d_inode->i_sb->s_dev, role);
19474 +       read_unlock(&gr_inode_lock);
19475 +
19476 +       if (unlikely(retval == NULL)) {
19477 +               read_lock(&gr_inode_lock);
19478 +               retval = lookup_acl_subj_label(real_root->d_inode->i_ino,
19479 +                                         real_root->d_inode->i_sb->s_dev, role);
19480 +               read_unlock(&gr_inode_lock);
19481 +       }
19482 +out:
19483 +       spin_unlock(&dcache_lock);
19484 +
19485 +       return retval;
19486 +}
19487 +
19488 +static void
19489 +gr_log_learn(const struct task_struct *task, const struct dentry *dentry, const struct vfsmount *mnt, const __u32 mode)
19490 +{
19491 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19492 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19493 +                      task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19494 +                      1, 1, gr_to_filename(dentry, mnt), (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19495 +
19496 +       return;
19497 +}
19498 +
19499 +static void
19500 +gr_log_learn_sysctl(const struct task_struct *task, const char *path, const __u32 mode)
19501 +{
19502 +       security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename, task->role->roletype,
19503 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19504 +                      task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19505 +                      1, 1, path, (unsigned long) mode, NIPQUAD(task->signal->curr_ip));
19506 +
19507 +       return;
19508 +}
19509 +
19510 +static void
19511 +gr_log_learn_id_change(const struct task_struct *task, const char type, const unsigned int real, 
19512 +                      const unsigned int effective, const unsigned int fs)
19513 +{
19514 +       security_learn(GR_ID_LEARN_MSG, task->role->rolename, task->role->roletype,
19515 +                      task->uid, task->gid, task->exec_file ? gr_to_filename1(task->exec_file->f_path.dentry,
19516 +                      task->exec_file->f_path.mnt) : task->acl->filename, task->acl->filename,
19517 +                      type, real, effective, fs, NIPQUAD(task->signal->curr_ip));
19518 +
19519 +       return;
19520 +}
19521 +
19522 +__u32
19523 +gr_check_link(const struct dentry * new_dentry,
19524 +             const struct dentry * parent_dentry,
19525 +             const struct vfsmount * parent_mnt,
19526 +             const struct dentry * old_dentry, const struct vfsmount * old_mnt)
19527 +{
19528 +       struct acl_object_label *obj;
19529 +       __u32 oldmode, newmode;
19530 +       __u32 needmode;
19531 +
19532 +       if (unlikely(!(gr_status & GR_READY)))
19533 +               return (GR_CREATE | GR_LINK);
19534 +
19535 +       obj = chk_obj_label(old_dentry, old_mnt, current->acl);
19536 +       oldmode = obj->mode;
19537 +
19538 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19539 +               oldmode |= (GR_CREATE | GR_LINK);
19540 +
19541 +       needmode = GR_CREATE | GR_AUDIT_CREATE | GR_SUPPRESS;
19542 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19543 +               needmode |= GR_SETID | GR_AUDIT_SETID;
19544 +
19545 +       newmode =
19546 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
19547 +                           oldmode | needmode);
19548 +
19549 +       needmode = newmode & (GR_FIND | GR_APPEND | GR_WRITE | GR_EXEC |
19550 +                             GR_SETID | GR_READ | GR_FIND | GR_DELETE |
19551 +                             GR_INHERIT | GR_AUDIT_INHERIT);
19552 +
19553 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID) && !(newmode & GR_SETID))
19554 +               goto bad;
19555 +
19556 +       if ((oldmode & needmode) != needmode)
19557 +               goto bad;
19558 +
19559 +       needmode = oldmode & (GR_NOPTRACE | GR_PTRACERD | GR_INHERIT | GR_AUDITS);
19560 +       if ((newmode & needmode) != needmode)
19561 +               goto bad;
19562 +
19563 +       if ((newmode & (GR_CREATE | GR_LINK)) == (GR_CREATE | GR_LINK))
19564 +               return newmode;
19565 +bad:
19566 +       needmode = oldmode;
19567 +       if (old_dentry->d_inode->i_mode & (S_ISUID | S_ISGID))
19568 +               needmode |= GR_SETID;
19569 +       
19570 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19571 +               gr_log_learn(current, old_dentry, old_mnt, needmode);
19572 +               return (GR_CREATE | GR_LINK);
19573 +       } else if (newmode & GR_SUPPRESS)
19574 +               return GR_SUPPRESS;
19575 +       else
19576 +               return 0;
19577 +}
19578 +
19579 +__u32
19580 +gr_search_file(const struct dentry * dentry, const __u32 mode,
19581 +              const struct vfsmount * mnt)
19582 +{
19583 +       __u32 retval = mode;
19584 +       struct acl_subject_label *curracl;
19585 +       struct acl_object_label *currobj;
19586 +
19587 +       if (unlikely(!(gr_status & GR_READY)))
19588 +               return (mode & ~GR_AUDITS);
19589 +
19590 +       curracl = current->acl;
19591 +
19592 +       currobj = chk_obj_label(dentry, mnt, curracl);
19593 +       retval = currobj->mode & mode;
19594 +
19595 +       if (unlikely
19596 +           ((curracl->mode & (GR_LEARN | GR_INHERITLEARN)) && !(mode & GR_NOPTRACE)
19597 +            && (retval != (mode & ~(GR_AUDITS | GR_SUPPRESS))))) {
19598 +               __u32 new_mode = mode;
19599 +
19600 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19601 +
19602 +               retval = new_mode;
19603 +
19604 +               if (new_mode & GR_EXEC && curracl->mode & GR_INHERITLEARN)
19605 +                       new_mode |= GR_INHERIT;
19606 +
19607 +               if (!(mode & GR_NOLEARN))
19608 +                       gr_log_learn(current, dentry, mnt, new_mode);
19609 +       }
19610 +
19611 +       return retval;
19612 +}
19613 +
19614 +__u32
19615 +gr_check_create(const struct dentry * new_dentry, const struct dentry * parent,
19616 +               const struct vfsmount * mnt, const __u32 mode)
19617 +{
19618 +       struct name_entry *match;
19619 +       struct acl_object_label *matchpo;
19620 +       struct acl_subject_label *curracl;
19621 +       char *path;
19622 +       __u32 retval;
19623 +
19624 +       if (unlikely(!(gr_status & GR_READY)))
19625 +               return (mode & ~GR_AUDITS);
19626 +
19627 +       preempt_disable();
19628 +       path = gr_to_filename_rbac(new_dentry, mnt);
19629 +       match = lookup_name_entry_create(path);
19630 +
19631 +       if (!match)
19632 +               goto check_parent;
19633 +
19634 +       curracl = current->acl;
19635 +
19636 +       read_lock(&gr_inode_lock);
19637 +       matchpo = lookup_acl_obj_label_create(match->inode, match->device, curracl);
19638 +       read_unlock(&gr_inode_lock);
19639 +
19640 +       if (matchpo) {
19641 +               if ((matchpo->mode & mode) !=
19642 +                   (mode & ~(GR_AUDITS | GR_SUPPRESS))
19643 +                   && curracl->mode & (GR_LEARN | GR_INHERITLEARN)) {
19644 +                       __u32 new_mode = mode;
19645 +
19646 +                       new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19647 +
19648 +                       gr_log_learn(current, new_dentry, mnt, new_mode);
19649 +
19650 +                       preempt_enable();
19651 +                       return new_mode;
19652 +               }
19653 +               preempt_enable();
19654 +               return (matchpo->mode & mode);
19655 +       }
19656 +
19657 +      check_parent:
19658 +       curracl = current->acl;
19659 +
19660 +       matchpo = chk_obj_create_label(parent, mnt, curracl, path);
19661 +       retval = matchpo->mode & mode;
19662 +
19663 +       if ((retval != (mode & ~(GR_AUDITS | GR_SUPPRESS)))
19664 +           && (curracl->mode & (GR_LEARN | GR_INHERITLEARN))) {
19665 +               __u32 new_mode = mode;
19666 +
19667 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
19668 +
19669 +               gr_log_learn(current, new_dentry, mnt, new_mode);
19670 +               preempt_enable();
19671 +               return new_mode;
19672 +       }
19673 +
19674 +       preempt_enable();
19675 +       return retval;
19676 +}
19677 +
19678 +int
19679 +gr_check_hidden_task(const struct task_struct *task)
19680 +{
19681 +       if (unlikely(!(gr_status & GR_READY)))
19682 +               return 0;
19683 +
19684 +       if (!(task->acl->mode & GR_PROCFIND) && !(current->acl->mode & GR_VIEW))
19685 +               return 1;
19686 +
19687 +       return 0;
19688 +}
19689 +
19690 +int
19691 +gr_check_protected_task(const struct task_struct *task)
19692 +{
19693 +       if (unlikely(!(gr_status & GR_READY) || !task))
19694 +               return 0;
19695 +
19696 +       if ((task->acl->mode & GR_PROTECTED) && !(current->acl->mode & GR_KILL) &&
19697 +           task->acl != current->acl)
19698 +               return 1;
19699 +
19700 +       return 0;
19701 +}
19702 +
19703 +void
19704 +gr_copy_label(struct task_struct *tsk)
19705 +{
19706 +       tsk->signal->used_accept = 0;
19707 +       tsk->acl_sp_role = 0;
19708 +       tsk->acl_role_id = current->acl_role_id;
19709 +       tsk->acl = current->acl;
19710 +       tsk->role = current->role;
19711 +       tsk->signal->curr_ip = current->signal->curr_ip;
19712 +       if (current->exec_file)
19713 +               get_file(current->exec_file);
19714 +       tsk->exec_file = current->exec_file;
19715 +       tsk->is_writable = current->is_writable;
19716 +       if (unlikely(current->signal->used_accept))
19717 +               current->signal->curr_ip = 0;
19718 +
19719 +       return;
19720 +}
19721 +
19722 +static void
19723 +gr_set_proc_res(struct task_struct *task)
19724 +{
19725 +       struct acl_subject_label *proc;
19726 +       unsigned short i;
19727 +
19728 +       proc = task->acl;
19729 +
19730 +       if (proc->mode & (GR_LEARN | GR_INHERITLEARN))
19731 +               return;
19732 +
19733 +       for (i = 0; i < (GR_NLIMITS - 1); i++) {
19734 +               if (!(proc->resmask & (1 << i)))
19735 +                       continue;
19736 +
19737 +               task->signal->rlim[i].rlim_cur = proc->res[i].rlim_cur;
19738 +               task->signal->rlim[i].rlim_max = proc->res[i].rlim_max;
19739 +       }
19740 +
19741 +       return;
19742 +}
19743 +
19744 +int
19745 +gr_check_user_change(int real, int effective, int fs)
19746 +{
19747 +       unsigned int i;
19748 +       __u16 num;
19749 +       uid_t *uidlist;
19750 +       int curuid;
19751 +       int realok = 0;
19752 +       int effectiveok = 0;
19753 +       int fsok = 0;
19754 +
19755 +       if (unlikely(!(gr_status & GR_READY)))
19756 +               return 0;
19757 +
19758 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19759 +               gr_log_learn_id_change(current, 'u', real, effective, fs);
19760 +
19761 +       num = current->acl->user_trans_num;
19762 +       uidlist = current->acl->user_transitions;
19763 +
19764 +       if (uidlist == NULL)
19765 +               return 0;
19766 +
19767 +       if (real == -1)
19768 +               realok = 1;
19769 +       if (effective == -1)
19770 +               effectiveok = 1;
19771 +       if (fs == -1)
19772 +               fsok = 1;
19773 +
19774 +       if (current->acl->user_trans_type & GR_ID_ALLOW) {
19775 +               for (i = 0; i < num; i++) {
19776 +                       curuid = (int)uidlist[i];
19777 +                       if (real == curuid)
19778 +                               realok = 1;
19779 +                       if (effective == curuid)
19780 +                               effectiveok = 1;
19781 +                       if (fs == curuid)
19782 +                               fsok = 1;
19783 +               }
19784 +       } else if (current->acl->user_trans_type & GR_ID_DENY) {
19785 +               for (i = 0; i < num; i++) {
19786 +                       curuid = (int)uidlist[i];
19787 +                       if (real == curuid)
19788 +                               break;
19789 +                       if (effective == curuid)
19790 +                               break;
19791 +                       if (fs == curuid)
19792 +                               break;
19793 +               }
19794 +               /* not in deny list */
19795 +               if (i == num) {
19796 +                       realok = 1;
19797 +                       effectiveok = 1;
19798 +                       fsok = 1;
19799 +               }
19800 +       }
19801 +
19802 +       if (realok && effectiveok && fsok)
19803 +               return 0;
19804 +       else {
19805 +               gr_log_int(GR_DONT_AUDIT, GR_USRCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19806 +               return 1;
19807 +       }
19808 +}
19809 +
19810 +int
19811 +gr_check_group_change(int real, int effective, int fs)
19812 +{
19813 +       unsigned int i;
19814 +       __u16 num;
19815 +       gid_t *gidlist;
19816 +       int curgid;
19817 +       int realok = 0;
19818 +       int effectiveok = 0;
19819 +       int fsok = 0;
19820 +
19821 +       if (unlikely(!(gr_status & GR_READY)))
19822 +               return 0;
19823 +
19824 +       if (current->acl->mode & (GR_LEARN | GR_INHERITLEARN))
19825 +               gr_log_learn_id_change(current, 'g', real, effective, fs);
19826 +
19827 +       num = current->acl->group_trans_num;
19828 +       gidlist = current->acl->group_transitions;
19829 +
19830 +       if (gidlist == NULL)
19831 +               return 0;
19832 +
19833 +       if (real == -1)
19834 +               realok = 1;
19835 +       if (effective == -1)
19836 +               effectiveok = 1;
19837 +       if (fs == -1)
19838 +               fsok = 1;
19839 +
19840 +       if (current->acl->group_trans_type & GR_ID_ALLOW) {
19841 +               for (i = 0; i < num; i++) {
19842 +                       curgid = (int)gidlist[i];
19843 +                       if (real == curgid)
19844 +                               realok = 1;
19845 +                       if (effective == curgid)
19846 +                               effectiveok = 1;
19847 +                       if (fs == curgid)
19848 +                               fsok = 1;
19849 +               }
19850 +       } else if (current->acl->group_trans_type & GR_ID_DENY) {
19851 +               for (i = 0; i < num; i++) {
19852 +                       curgid = (int)gidlist[i];
19853 +                       if (real == curgid)
19854 +                               break;
19855 +                       if (effective == curgid)
19856 +                               break;
19857 +                       if (fs == curgid)
19858 +                               break;
19859 +               }
19860 +               /* not in deny list */
19861 +               if (i == num) {
19862 +                       realok = 1;
19863 +                       effectiveok = 1;
19864 +                       fsok = 1;
19865 +               }
19866 +       }
19867 +
19868 +       if (realok && effectiveok && fsok)
19869 +               return 0;
19870 +       else {
19871 +               gr_log_int(GR_DONT_AUDIT, GR_GRPCHANGE_ACL_MSG, realok ? (effectiveok ? (fsok ? 0 : fs) : effective) : real);
19872 +               return 1;
19873 +       }
19874 +}
19875 +
19876 +void
19877 +gr_set_role_label(struct task_struct *task, const uid_t uid, const uid_t gid)
19878 +{
19879 +       struct acl_role_label *role = task->role;
19880 +       struct acl_subject_label *subj = NULL;
19881 +       struct acl_object_label *obj;
19882 +       struct file *filp;
19883 +
19884 +       if (unlikely(!(gr_status & GR_READY)))
19885 +               return;
19886 +
19887 +       filp = task->exec_file;
19888 +
19889 +       /* kernel process, we'll give them the kernel role */
19890 +       if (unlikely(!filp)) {
19891 +               task->role = kernel_role;
19892 +               task->acl = kernel_role->root_label;
19893 +               return;
19894 +       } else if (!task->role || !(task->role->roletype & GR_ROLE_SPECIAL))
19895 +               role = lookup_acl_role_label(task, uid, gid);
19896 +
19897 +       /* perform subject lookup in possibly new role
19898 +          we can use this result below in the case where role == task->role
19899 +       */
19900 +       subj = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, role);
19901 +
19902 +       /* if we changed uid/gid, but result in the same role
19903 +          and are using inheritance, don't lose the inherited subject
19904 +          if current subject is other than what normal lookup
19905 +          would result in, we arrived via inheritance, don't
19906 +          lose subject
19907 +       */
19908 +       if (role != task->role || (!(task->acl->mode & GR_INHERITLEARN) &&
19909 +                                  (subj == task->acl)))
19910 +               task->acl = subj;
19911 +
19912 +       task->role = role;
19913 +
19914 +       task->is_writable = 0;
19915 +
19916 +       /* ignore additional mmap checks for processes that are writable 
19917 +          by the default ACL */
19918 +       obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
19919 +       if (unlikely(obj->mode & GR_WRITE))
19920 +               task->is_writable = 1;
19921 +       obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
19922 +       if (unlikely(obj->mode & GR_WRITE))
19923 +               task->is_writable = 1;
19924 +
19925 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19926 +       printk(KERN_ALERT "Set role label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19927 +#endif
19928 +
19929 +       gr_set_proc_res(task);
19930 +
19931 +       return;
19932 +}
19933 +
19934 +int
19935 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
19936 +{
19937 +       struct task_struct *task = current;
19938 +       struct acl_subject_label *newacl;
19939 +       struct acl_object_label *obj;
19940 +       __u32 retmode;
19941 +
19942 +       if (unlikely(!(gr_status & GR_READY)))
19943 +               return 0;
19944 +
19945 +       newacl = chk_subj_label(dentry, mnt, task->role);
19946 +
19947 +       task_lock(task);
19948 +       if (((task->ptrace & PT_PTRACED) && !(task->acl->mode &
19949 +            GR_POVERRIDE) && (task->acl != newacl) &&
19950 +            !(task->role->roletype & GR_ROLE_GOD) &&
19951 +            !gr_search_file(dentry, GR_PTRACERD, mnt) &&
19952 +            !(task->acl->mode & (GR_LEARN | GR_INHERITLEARN))) ||
19953 +           (atomic_read(&task->fs->count) > 1 ||
19954 +            atomic_read(&task->files->count) > 1 ||
19955 +            atomic_read(&task->sighand->count) > 1)) {
19956 +                task_unlock(task);
19957 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_PTRACE_EXEC_ACL_MSG, dentry, mnt);
19958 +               return -EACCES;
19959 +       }
19960 +       task_unlock(task);
19961 +
19962 +       obj = chk_obj_label(dentry, mnt, task->acl);
19963 +       retmode = obj->mode & (GR_INHERIT | GR_AUDIT_INHERIT);
19964 +
19965 +       if (!(task->acl->mode & GR_INHERITLEARN) &&
19966 +           ((newacl->mode & GR_LEARN) || !(retmode & GR_INHERIT))) {
19967 +               if (obj->nested)
19968 +                       task->acl = obj->nested;
19969 +               else
19970 +                       task->acl = newacl;
19971 +       } else if (retmode & GR_INHERIT && retmode & GR_AUDIT_INHERIT)
19972 +               gr_log_str_fs(GR_DO_AUDIT, GR_INHERIT_ACL_MSG, task->acl->filename, dentry, mnt);
19973 +
19974 +       task->is_writable = 0;
19975 +
19976 +       /* ignore additional mmap checks for processes that are writable 
19977 +          by the default ACL */
19978 +       obj = chk_obj_label(dentry, mnt, default_role->root_label);
19979 +       if (unlikely(obj->mode & GR_WRITE))
19980 +               task->is_writable = 1;
19981 +       obj = chk_obj_label(dentry, mnt, task->role->root_label);
19982 +       if (unlikely(obj->mode & GR_WRITE))
19983 +               task->is_writable = 1;
19984 +
19985 +       gr_set_proc_res(task);
19986 +
19987 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
19988 +       printk(KERN_ALERT "Set subject label for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
19989 +#endif
19990 +       return 0;
19991 +}
19992 +
19993 +/* always called with valid inodev ptr */
19994 +static void
19995 +do_handle_delete(struct inodev_entry *inodev, const ino_t ino, const dev_t dev)
19996 +{
19997 +       struct acl_object_label *matchpo;
19998 +       struct acl_subject_label *matchps;
19999 +       struct acl_subject_label *subj;
20000 +       struct acl_role_label *role;
20001 +       unsigned int i, x;
20002 +
20003 +       FOR_EACH_ROLE_START(role, i)
20004 +               FOR_EACH_SUBJECT_START(role, subj, x)
20005 +                       if ((matchpo = lookup_acl_obj_label(ino, dev, subj)) != NULL)
20006 +                               matchpo->mode |= GR_DELETED;
20007 +               FOR_EACH_SUBJECT_END(subj,x)
20008 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
20009 +                       if (subj->inode == ino && subj->device == dev)
20010 +                               subj->mode |= GR_DELETED;
20011 +               FOR_EACH_NESTED_SUBJECT_END(subj)
20012 +               if ((matchps = lookup_acl_subj_label(ino, dev, role)) != NULL)
20013 +                       matchps->mode |= GR_DELETED;
20014 +       FOR_EACH_ROLE_END(role,i)
20015 +
20016 +       inodev->nentry->deleted = 1;
20017 +
20018 +       return;
20019 +}
20020 +
20021 +void
20022 +gr_handle_delete(const ino_t ino, const dev_t dev)
20023 +{
20024 +       struct inodev_entry *inodev;
20025 +
20026 +       if (unlikely(!(gr_status & GR_READY)))
20027 +               return;
20028 +
20029 +       write_lock(&gr_inode_lock);
20030 +       inodev = lookup_inodev_entry(ino, dev);
20031 +       if (inodev != NULL)
20032 +               do_handle_delete(inodev, ino, dev);
20033 +       write_unlock(&gr_inode_lock);
20034 +
20035 +       return;
20036 +}
20037 +
20038 +static void
20039 +update_acl_obj_label(const ino_t oldinode, const dev_t olddevice,
20040 +                    const ino_t newinode, const dev_t newdevice,
20041 +                    struct acl_subject_label *subj)
20042 +{
20043 +       unsigned int index = fhash(oldinode, olddevice, subj->obj_hash_size);
20044 +       struct acl_object_label *match;
20045 +
20046 +       match = subj->obj_hash[index];
20047 +
20048 +       while (match && (match->inode != oldinode ||
20049 +              match->device != olddevice ||
20050 +              !(match->mode & GR_DELETED)))
20051 +               match = match->next;
20052 +
20053 +       if (match && (match->inode == oldinode)
20054 +           && (match->device == olddevice)
20055 +           && (match->mode & GR_DELETED)) {
20056 +               if (match->prev == NULL) {
20057 +                       subj->obj_hash[index] = match->next;
20058 +                       if (match->next != NULL)
20059 +                               match->next->prev = NULL;
20060 +               } else {
20061 +                       match->prev->next = match->next;
20062 +                       if (match->next != NULL)
20063 +                               match->next->prev = match->prev;
20064 +               }
20065 +               match->prev = NULL;
20066 +               match->next = NULL;
20067 +               match->inode = newinode;
20068 +               match->device = newdevice;
20069 +               match->mode &= ~GR_DELETED;
20070 +
20071 +               insert_acl_obj_label(match, subj);
20072 +       }
20073 +
20074 +       return;
20075 +}
20076 +
20077 +static void
20078 +update_acl_subj_label(const ino_t oldinode, const dev_t olddevice,
20079 +                     const ino_t newinode, const dev_t newdevice,
20080 +                     struct acl_role_label *role)
20081 +{
20082 +       unsigned int index = fhash(oldinode, olddevice, role->subj_hash_size);
20083 +       struct acl_subject_label *match;
20084 +
20085 +       match = role->subj_hash[index];
20086 +
20087 +       while (match && (match->inode != oldinode ||
20088 +              match->device != olddevice ||
20089 +              !(match->mode & GR_DELETED)))
20090 +               match = match->next;
20091 +
20092 +       if (match && (match->inode == oldinode)
20093 +           && (match->device == olddevice)
20094 +           && (match->mode & GR_DELETED)) {
20095 +               if (match->prev == NULL) {
20096 +                       role->subj_hash[index] = match->next;
20097 +                       if (match->next != NULL)
20098 +                               match->next->prev = NULL;
20099 +               } else {
20100 +                       match->prev->next = match->next;
20101 +                       if (match->next != NULL)
20102 +                               match->next->prev = match->prev;
20103 +               }
20104 +               match->prev = NULL;
20105 +               match->next = NULL;
20106 +               match->inode = newinode;
20107 +               match->device = newdevice;
20108 +               match->mode &= ~GR_DELETED;
20109 +
20110 +               insert_acl_subj_label(match, role);
20111 +       }
20112 +
20113 +       return;
20114 +}
20115 +
20116 +static void
20117 +update_inodev_entry(const ino_t oldinode, const dev_t olddevice,
20118 +                   const ino_t newinode, const dev_t newdevice)
20119 +{
20120 +       unsigned int index = fhash(oldinode, olddevice, inodev_set.i_size);
20121 +       struct inodev_entry *match;
20122 +
20123 +       match = inodev_set.i_hash[index];
20124 +
20125 +       while (match && (match->nentry->inode != oldinode ||
20126 +              match->nentry->device != olddevice || !match->nentry->deleted))
20127 +               match = match->next;
20128 +
20129 +       if (match && (match->nentry->inode == oldinode)
20130 +           && (match->nentry->device == olddevice) &&
20131 +           match->nentry->deleted) {
20132 +               if (match->prev == NULL) {
20133 +                       inodev_set.i_hash[index] = match->next;
20134 +                       if (match->next != NULL)
20135 +                               match->next->prev = NULL;
20136 +               } else {
20137 +                       match->prev->next = match->next;
20138 +                       if (match->next != NULL)
20139 +                               match->next->prev = match->prev;
20140 +               }
20141 +               match->prev = NULL;
20142 +               match->next = NULL;
20143 +               match->nentry->inode = newinode;
20144 +               match->nentry->device = newdevice;
20145 +               match->nentry->deleted = 0;
20146 +
20147 +               insert_inodev_entry(match);
20148 +       }
20149 +
20150 +       return;
20151 +}
20152 +
20153 +static void
20154 +do_handle_create(const struct name_entry *matchn, const struct dentry *dentry,
20155 +                const struct vfsmount *mnt)
20156 +{
20157 +       struct acl_subject_label *subj;
20158 +       struct acl_role_label *role;
20159 +       unsigned int i, x;
20160 +
20161 +       FOR_EACH_ROLE_START(role, i)
20162 +               update_acl_subj_label(matchn->inode, matchn->device,
20163 +                                     dentry->d_inode->i_ino,
20164 +                                     dentry->d_inode->i_sb->s_dev, role);
20165 +
20166 +               FOR_EACH_NESTED_SUBJECT_START(role, subj)
20167 +                       if ((subj->inode == dentry->d_inode->i_ino) &&
20168 +                           (subj->device == dentry->d_inode->i_sb->s_dev)) {
20169 +                               subj->inode = dentry->d_inode->i_ino;
20170 +                               subj->device = dentry->d_inode->i_sb->s_dev;
20171 +                       }
20172 +               FOR_EACH_NESTED_SUBJECT_END(subj)
20173 +               FOR_EACH_SUBJECT_START(role, subj, x)
20174 +                       update_acl_obj_label(matchn->inode, matchn->device,
20175 +                                            dentry->d_inode->i_ino,
20176 +                                            dentry->d_inode->i_sb->s_dev, subj);
20177 +               FOR_EACH_SUBJECT_END(subj,x)
20178 +       FOR_EACH_ROLE_END(role,i)
20179 +
20180 +       update_inodev_entry(matchn->inode, matchn->device,
20181 +                           dentry->d_inode->i_ino, dentry->d_inode->i_sb->s_dev);
20182 +
20183 +       return;
20184 +}
20185 +
20186 +void
20187 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
20188 +{
20189 +       struct name_entry *matchn;
20190 +
20191 +       if (unlikely(!(gr_status & GR_READY)))
20192 +               return;
20193 +
20194 +       preempt_disable();
20195 +       matchn = lookup_name_entry(gr_to_filename_rbac(dentry, mnt));
20196 +
20197 +       if (unlikely((unsigned long)matchn)) {
20198 +               write_lock(&gr_inode_lock);
20199 +               do_handle_create(matchn, dentry, mnt);
20200 +               write_unlock(&gr_inode_lock);
20201 +       }
20202 +       preempt_enable();
20203 +
20204 +       return;
20205 +}
20206 +
20207 +void
20208 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
20209 +                struct dentry *old_dentry,
20210 +                struct dentry *new_dentry,
20211 +                struct vfsmount *mnt, const __u8 replace)
20212 +{
20213 +       struct name_entry *matchn;
20214 +       struct inodev_entry *inodev;
20215 +
20216 +       /* vfs_rename swaps the name and parent link for old_dentry and
20217 +          new_dentry
20218 +          at this point, old_dentry has the new name, parent link, and inode
20219 +          for the renamed file
20220 +          if a file is being replaced by a rename, new_dentry has the inode
20221 +          and name for the replaced file
20222 +       */
20223 +
20224 +       if (unlikely(!(gr_status & GR_READY)))
20225 +               return;
20226 +
20227 +       preempt_disable();
20228 +       matchn = lookup_name_entry(gr_to_filename_rbac(old_dentry, mnt));
20229 +
20230 +       /* we wouldn't have to check d_inode if it weren't for
20231 +          NFS silly-renaming
20232 +        */
20233 +
20234 +       write_lock(&gr_inode_lock);
20235 +       if (unlikely(replace && new_dentry->d_inode)) {
20236 +               inodev = lookup_inodev_entry(new_dentry->d_inode->i_ino,
20237 +                                            new_dentry->d_inode->i_sb->s_dev);
20238 +               if (inodev != NULL && (new_dentry->d_inode->i_nlink <= 1))
20239 +                       do_handle_delete(inodev, new_dentry->d_inode->i_ino,
20240 +                                        new_dentry->d_inode->i_sb->s_dev);
20241 +       }
20242 +
20243 +       inodev = lookup_inodev_entry(old_dentry->d_inode->i_ino,
20244 +                                    old_dentry->d_inode->i_sb->s_dev);
20245 +       if (inodev != NULL && (old_dentry->d_inode->i_nlink <= 1))
20246 +               do_handle_delete(inodev, old_dentry->d_inode->i_ino,
20247 +                                old_dentry->d_inode->i_sb->s_dev);
20248 +
20249 +       if (unlikely((unsigned long)matchn))
20250 +               do_handle_create(matchn, old_dentry, mnt);
20251 +
20252 +       write_unlock(&gr_inode_lock);
20253 +       preempt_enable();
20254 +
20255 +       return;
20256 +}
20257 +
20258 +static int
20259 +lookup_special_role_auth(__u16 mode, const char *rolename, unsigned char **salt,
20260 +                        unsigned char **sum)
20261 +{
20262 +       struct acl_role_label *r;
20263 +       struct role_allowed_ip *ipp;
20264 +       struct role_transition *trans;
20265 +       unsigned int i;
20266 +       int found = 0;
20267 +
20268 +       /* check transition table */
20269 +
20270 +       for (trans = current->role->transitions; trans; trans = trans->next) {
20271 +               if (!strcmp(rolename, trans->rolename)) {
20272 +                       found = 1;
20273 +                       break;
20274 +               }
20275 +       }
20276 +
20277 +       if (!found)
20278 +               return 0;
20279 +
20280 +       /* handle special roles that do not require authentication
20281 +          and check ip */
20282 +
20283 +       FOR_EACH_ROLE_START(r, i)
20284 +               if (!strcmp(rolename, r->rolename) &&
20285 +                   (r->roletype & GR_ROLE_SPECIAL)) {
20286 +                       found = 0;
20287 +                       if (r->allowed_ips != NULL) {
20288 +                               for (ipp = r->allowed_ips; ipp; ipp = ipp->next) {
20289 +                                       if ((ntohl(current->signal->curr_ip) & ipp->netmask) ==
20290 +                                            (ntohl(ipp->addr) & ipp->netmask))
20291 +                                               found = 1;
20292 +                               }
20293 +                       } else
20294 +                               found = 2;
20295 +                       if (!found)
20296 +                               return 0;
20297 +
20298 +                       if (((mode == SPROLE) && (r->roletype & GR_ROLE_NOPW)) ||
20299 +                           ((mode == SPROLEPAM) && (r->roletype & GR_ROLE_PAM))) {
20300 +                               *salt = NULL;
20301 +                               *sum = NULL;
20302 +                               return 1;
20303 +                       }
20304 +               }
20305 +       FOR_EACH_ROLE_END(r,i)
20306 +
20307 +       for (i = 0; i < num_sprole_pws; i++) {
20308 +               if (!strcmp(rolename, acl_special_roles[i]->rolename)) {
20309 +                       *salt = acl_special_roles[i]->salt;
20310 +                       *sum = acl_special_roles[i]->sum;
20311 +                       return 1;
20312 +               }
20313 +       }
20314 +
20315 +       return 0;
20316 +}
20317 +
20318 +static void
20319 +assign_special_role(char *rolename)
20320 +{
20321 +       struct acl_object_label *obj;
20322 +       struct acl_role_label *r;
20323 +       struct acl_role_label *assigned = NULL;
20324 +       struct task_struct *tsk;
20325 +       struct file *filp;
20326 +       unsigned int i;
20327 +
20328 +       FOR_EACH_ROLE_START(r, i)
20329 +               if (!strcmp(rolename, r->rolename) &&
20330 +                   (r->roletype & GR_ROLE_SPECIAL))
20331 +                       assigned = r;
20332 +       FOR_EACH_ROLE_END(r,i)
20333 +
20334 +       if (!assigned)
20335 +               return;
20336 +
20337 +       read_lock(&tasklist_lock);
20338 +       read_lock(&grsec_exec_file_lock);
20339 +
20340 +       tsk = current->parent;
20341 +       if (tsk == NULL)
20342 +               goto out_unlock;
20343 +
20344 +       filp = tsk->exec_file;
20345 +       if (filp == NULL)
20346 +               goto out_unlock;
20347 +
20348 +       tsk->is_writable = 0;
20349 +
20350 +       tsk->acl_sp_role = 1;
20351 +       tsk->acl_role_id = ++acl_sp_role_value;
20352 +       tsk->role = assigned;
20353 +       tsk->acl = chk_subj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role);
20354 +
20355 +       /* ignore additional mmap checks for processes that are writable 
20356 +          by the default ACL */
20357 +       obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20358 +       if (unlikely(obj->mode & GR_WRITE))
20359 +               tsk->is_writable = 1;
20360 +       obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, tsk->role->root_label);
20361 +       if (unlikely(obj->mode & GR_WRITE))
20362 +               tsk->is_writable = 1;
20363 +
20364 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20365 +       printk(KERN_ALERT "Assigning special role:%s subject:%s to process (%s:%d)\n", tsk->role->rolename, tsk->acl->filename, tsk->comm, tsk->pid);
20366 +#endif
20367 +
20368 +out_unlock:
20369 +       read_unlock(&grsec_exec_file_lock);
20370 +       read_unlock(&tasklist_lock);
20371 +       return;
20372 +}
20373 +
20374 +int gr_check_secure_terminal(struct task_struct *task)
20375 +{
20376 +       struct task_struct *p, *p2, *p3;
20377 +       struct files_struct *files;
20378 +       struct fdtable *fdt;
20379 +       struct file *our_file = NULL, *file;
20380 +       int i;
20381 +
20382 +       if (task->signal->tty == NULL)
20383 +               return 1;
20384 +
20385 +       files = get_files_struct(task);
20386 +       if (files != NULL) {
20387 +               rcu_read_lock();
20388 +               fdt = files_fdtable(files);
20389 +               for (i=0; i < fdt->max_fds; i++) {
20390 +                       file = fcheck_files(files, i);
20391 +                       if (file && (our_file == NULL) && (file->private_data == task->signal->tty)) {
20392 +                               get_file(file);
20393 +                               our_file = file;
20394 +                       }
20395 +               }
20396 +               rcu_read_unlock();
20397 +               put_files_struct(files);
20398 +       }
20399 +
20400 +       if (our_file == NULL)
20401 +               return 1;
20402 +
20403 +       read_lock(&tasklist_lock);
20404 +       do_each_thread(p2, p) {
20405 +               files = get_files_struct(p);
20406 +               if (files == NULL ||
20407 +                   (p->signal && p->signal->tty == task->signal->tty)) {
20408 +                       if (files != NULL)
20409 +                               put_files_struct(files);
20410 +                       continue;
20411 +               }
20412 +               rcu_read_lock();
20413 +               fdt = files_fdtable(files);
20414 +               for (i=0; i < fdt->max_fds; i++) {
20415 +                       file = fcheck_files(files, i);
20416 +                       if (file && S_ISCHR(file->f_path.dentry->d_inode->i_mode) &&
20417 +                           file->f_path.dentry->d_inode->i_rdev == our_file->f_path.dentry->d_inode->i_rdev) {
20418 +                               p3 = task;
20419 +                               while (p3->pid > 0) {
20420 +                                       if (p3 == p)
20421 +                                               break;
20422 +                                       p3 = p3->parent;
20423 +                               }
20424 +                               if (p3 == p)
20425 +                                       break;
20426 +                               gr_log_ttysniff(GR_DONT_AUDIT_GOOD, GR_TTYSNIFF_ACL_MSG, p);
20427 +                               gr_handle_alertkill(p);
20428 +                               rcu_read_unlock();
20429 +                               put_files_struct(files);
20430 +                               read_unlock(&tasklist_lock);
20431 +                               fput(our_file);
20432 +                               return 0;
20433 +                       }
20434 +               }
20435 +               rcu_read_unlock();
20436 +               put_files_struct(files);
20437 +       } while_each_thread(p2, p);
20438 +       read_unlock(&tasklist_lock);
20439 +
20440 +       fput(our_file);
20441 +       return 1;
20442 +}
20443 +
20444 +ssize_t
20445 +write_grsec_handler(struct file *file, const char * buf, size_t count, loff_t *ppos)
20446 +{
20447 +       struct gr_arg_wrapper uwrap;
20448 +       unsigned char *sprole_salt;
20449 +       unsigned char *sprole_sum;
20450 +       int error = sizeof (struct gr_arg_wrapper);
20451 +       int error2 = 0;
20452 +
20453 +       down(&gr_dev_sem);
20454 +
20455 +       if ((gr_status & GR_READY) && !(current->acl->mode & GR_KERNELAUTH)) {
20456 +               error = -EPERM;
20457 +               goto out;
20458 +       }
20459 +
20460 +       if (count != sizeof (struct gr_arg_wrapper)) {
20461 +               gr_log_int_int(GR_DONT_AUDIT_GOOD, GR_DEV_ACL_MSG, (int)count, (int)sizeof(struct gr_arg_wrapper));
20462 +               error = -EINVAL;
20463 +               goto out;
20464 +       }
20465 +
20466 +       
20467 +       if (gr_auth_expires && time_after_eq(get_seconds(), gr_auth_expires)) {
20468 +               gr_auth_expires = 0;
20469 +               gr_auth_attempts = 0;
20470 +       }
20471 +
20472 +       if (copy_from_user(&uwrap, buf, sizeof (struct gr_arg_wrapper))) {
20473 +               error = -EFAULT;
20474 +               goto out;
20475 +       }
20476 +
20477 +       if ((uwrap.version != GRSECURITY_VERSION) || (uwrap.size != sizeof(struct gr_arg))) {
20478 +               error = -EINVAL;
20479 +               goto out;
20480 +       }
20481 +
20482 +       if (copy_from_user(gr_usermode, uwrap.arg, sizeof (struct gr_arg))) {
20483 +               error = -EFAULT;
20484 +               goto out;
20485 +       }
20486 +
20487 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != SPROLEPAM &&
20488 +           gr_auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20489 +           time_after(gr_auth_expires, get_seconds())) {
20490 +               error = -EBUSY;
20491 +               goto out;
20492 +       }
20493 +
20494 +       /* if non-root trying to do anything other than use a special role,
20495 +          do not attempt authentication, do not count towards authentication
20496 +          locking
20497 +        */
20498 +
20499 +       if (gr_usermode->mode != SPROLE && gr_usermode->mode != STATUS &&
20500 +           gr_usermode->mode != UNSPROLE && gr_usermode->mode != SPROLEPAM &&
20501 +           current->uid) {
20502 +               error = -EPERM;
20503 +               goto out;
20504 +       }
20505 +
20506 +       /* ensure pw and special role name are null terminated */
20507 +
20508 +       gr_usermode->pw[GR_PW_LEN - 1] = '\0';
20509 +       gr_usermode->sp_role[GR_SPROLE_LEN - 1] = '\0';
20510 +
20511 +       /* Okay. 
20512 +        * We have our enough of the argument structure..(we have yet
20513 +        * to copy_from_user the tables themselves) . Copy the tables
20514 +        * only if we need them, i.e. for loading operations. */
20515 +
20516 +       switch (gr_usermode->mode) {
20517 +       case STATUS:
20518 +                       if (gr_status & GR_READY) {
20519 +                               error = 1;
20520 +                               if (!gr_check_secure_terminal(current))
20521 +                                       error = 3;
20522 +                       } else
20523 +                               error = 2;
20524 +                       goto out;
20525 +       case SHUTDOWN:
20526 +               if ((gr_status & GR_READY)
20527 +                   && !(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20528 +                       gr_status &= ~GR_READY;
20529 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTS_ACL_MSG);
20530 +                       free_variables();
20531 +                       memset(gr_usermode, 0, sizeof (struct gr_arg));
20532 +                       memset(gr_system_salt, 0, GR_SALT_LEN);
20533 +                       memset(gr_system_sum, 0, GR_SHA_LEN);
20534 +               } else if (gr_status & GR_READY) {
20535 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHUTF_ACL_MSG);
20536 +                       error = -EPERM;
20537 +               } else {
20538 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SHUTI_ACL_MSG);
20539 +                       error = -EAGAIN;
20540 +               }
20541 +               break;
20542 +       case ENABLE:
20543 +               if (!(gr_status & GR_READY) && !(error2 = gracl_init(gr_usermode)))
20544 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_ENABLE_ACL_MSG, GR_VERSION);
20545 +               else {
20546 +                       if (gr_status & GR_READY)
20547 +                               error = -EAGAIN;
20548 +                       else
20549 +                               error = error2;
20550 +                       gr_log_str(GR_DONT_AUDIT, GR_ENABLEF_ACL_MSG, GR_VERSION);
20551 +               }
20552 +               break;
20553 +       case RELOAD:
20554 +               if (!(gr_status & GR_READY)) {
20555 +                       gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOADI_ACL_MSG, GR_VERSION);
20556 +                       error = -EAGAIN;
20557 +               } else if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20558 +                       lock_kernel();
20559 +                       gr_status &= ~GR_READY;
20560 +                       free_variables();
20561 +                       if (!(error2 = gracl_init(gr_usermode))) {
20562 +                               unlock_kernel();
20563 +                               gr_log_str(GR_DONT_AUDIT_GOOD, GR_RELOAD_ACL_MSG, GR_VERSION);
20564 +                       } else {
20565 +                               unlock_kernel();
20566 +                               error = error2;
20567 +                               gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20568 +                       }
20569 +               } else {
20570 +                       gr_log_str(GR_DONT_AUDIT, GR_RELOADF_ACL_MSG, GR_VERSION);
20571 +                       error = -EPERM;
20572 +               }
20573 +               break;
20574 +       case SEGVMOD:
20575 +               if (unlikely(!(gr_status & GR_READY))) {
20576 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODI_ACL_MSG);
20577 +                       error = -EAGAIN;
20578 +                       break;
20579 +               }
20580 +
20581 +               if (!(chkpw(gr_usermode, gr_system_salt, gr_system_sum))) {
20582 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SEGVMODS_ACL_MSG);
20583 +                       if (gr_usermode->segv_device && gr_usermode->segv_inode) {
20584 +                               struct acl_subject_label *segvacl;
20585 +                               segvacl =
20586 +                                   lookup_acl_subj_label(gr_usermode->segv_inode,
20587 +                                                         gr_usermode->segv_device,
20588 +                                                         current->role);
20589 +                               if (segvacl) {
20590 +                                       segvacl->crashes = 0;
20591 +                                       segvacl->expires = 0;
20592 +                               }
20593 +                       } else if (gr_find_uid(gr_usermode->segv_uid) >= 0) {
20594 +                               gr_remove_uid(gr_usermode->segv_uid);
20595 +                       }
20596 +               } else {
20597 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SEGVMODF_ACL_MSG);
20598 +                       error = -EPERM;
20599 +               }
20600 +               break;
20601 +       case SPROLE:
20602 +       case SPROLEPAM:
20603 +               if (unlikely(!(gr_status & GR_READY))) {
20604 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_SPROLEI_ACL_MSG);
20605 +                       error = -EAGAIN;
20606 +                       break;
20607 +               }
20608 +
20609 +               if (current->role->expires && time_after_eq(get_seconds(), current->role->expires)) {
20610 +                       current->role->expires = 0;
20611 +                       current->role->auth_attempts = 0;
20612 +               }
20613 +
20614 +               if (current->role->auth_attempts >= CONFIG_GRKERNSEC_ACL_MAXTRIES &&
20615 +                   time_after(current->role->expires, get_seconds())) {
20616 +                       error = -EBUSY;
20617 +                       goto out;
20618 +               }
20619 +
20620 +               if (lookup_special_role_auth
20621 +                   (gr_usermode->mode, gr_usermode->sp_role, &sprole_salt, &sprole_sum)
20622 +                   && ((!sprole_salt && !sprole_sum)
20623 +                       || !(chkpw(gr_usermode, sprole_salt, sprole_sum)))) {
20624 +                       char *p = "";
20625 +                       assign_special_role(gr_usermode->sp_role);
20626 +                       read_lock(&tasklist_lock);
20627 +                       if (current->parent)
20628 +                               p = current->parent->role->rolename;
20629 +                       read_unlock(&tasklist_lock);
20630 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLES_ACL_MSG,
20631 +                                       p, acl_sp_role_value);
20632 +               } else {
20633 +                       gr_log_str(GR_DONT_AUDIT, GR_SPROLEF_ACL_MSG, gr_usermode->sp_role);
20634 +                       error = -EPERM;
20635 +                       if(!(current->role->auth_attempts++))
20636 +                               current->role->expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20637 +
20638 +                       goto out;
20639 +               }
20640 +               break;
20641 +       case UNSPROLE:
20642 +               if (unlikely(!(gr_status & GR_READY))) {
20643 +                       gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_UNSPROLEI_ACL_MSG);
20644 +                       error = -EAGAIN;
20645 +                       break;
20646 +               }
20647 +
20648 +               if (current->role->roletype & GR_ROLE_SPECIAL) {
20649 +                       char *p = "";
20650 +                       int i = 0;
20651 +
20652 +                       read_lock(&tasklist_lock);
20653 +                       if (current->parent) {
20654 +                               p = current->parent->role->rolename;
20655 +                               i = current->parent->acl_role_id;
20656 +                       }
20657 +                       read_unlock(&tasklist_lock);
20658 +
20659 +                       gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_UNSPROLES_ACL_MSG, p, i);
20660 +                       gr_set_acls(1);
20661 +               } else {
20662 +                       gr_log_str(GR_DONT_AUDIT, GR_UNSPROLEF_ACL_MSG, current->role->rolename);
20663 +                       error = -EPERM;
20664 +                       goto out;
20665 +               }
20666 +               break;
20667 +       default:
20668 +               gr_log_int(GR_DONT_AUDIT, GR_INVMODE_ACL_MSG, gr_usermode->mode);
20669 +               error = -EINVAL;
20670 +               break;
20671 +       }
20672 +
20673 +       if (error != -EPERM)
20674 +               goto out;
20675 +
20676 +       if(!(gr_auth_attempts++))
20677 +               gr_auth_expires = get_seconds() + CONFIG_GRKERNSEC_ACL_TIMEOUT;
20678 +
20679 +      out:
20680 +       up(&gr_dev_sem);
20681 +       return error;
20682 +}
20683 +
20684 +int
20685 +gr_set_acls(const int type)
20686 +{
20687 +       struct acl_object_label *obj;
20688 +       struct task_struct *task, *task2;
20689 +       struct file *filp;
20690 +       struct acl_role_label *role = current->role;
20691 +       __u16 acl_role_id = current->acl_role_id;
20692 +
20693 +       read_lock(&tasklist_lock);
20694 +       read_lock(&grsec_exec_file_lock);
20695 +       do_each_thread(task2, task) {
20696 +               /* check to see if we're called from the exit handler,
20697 +                  if so, only replace ACLs that have inherited the admin
20698 +                  ACL */
20699 +
20700 +               if (type && (task->role != role ||
20701 +                            task->acl_role_id != acl_role_id))
20702 +                       continue;
20703 +
20704 +               task->acl_role_id = 0;
20705 +               task->acl_sp_role = 0;
20706 +
20707 +               if ((filp = task->exec_file)) {
20708 +                       task->role = lookup_acl_role_label(task, task->uid, task->gid);
20709 +
20710 +                       task->acl =
20711 +                           chk_subj_label(filp->f_path.dentry, filp->f_path.mnt,
20712 +                                          task->role);
20713 +                       if (task->acl) {
20714 +                               struct acl_subject_label *curr;
20715 +                               curr = task->acl;
20716 +
20717 +                               task->is_writable = 0;
20718 +                               /* ignore additional mmap checks for processes that are writable 
20719 +                                  by the default ACL */
20720 +                               obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
20721 +                               if (unlikely(obj->mode & GR_WRITE))
20722 +                                       task->is_writable = 1;
20723 +                               obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, task->role->root_label);
20724 +                               if (unlikely(obj->mode & GR_WRITE))
20725 +                                       task->is_writable = 1;
20726 +
20727 +                               gr_set_proc_res(task);
20728 +
20729 +#ifdef CONFIG_GRKERNSEC_ACL_DEBUG
20730 +                               printk(KERN_ALERT "gr_set_acls for (%s:%d): role:%s, subject:%s\n", task->comm, task->pid, task->role->rolename, task->acl->filename);
20731 +#endif
20732 +                       } else {
20733 +                               read_unlock(&grsec_exec_file_lock);
20734 +                               read_unlock(&tasklist_lock);
20735 +                               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_DEFACL_MSG, task->comm, task->pid);
20736 +                               return 1;
20737 +                       }
20738 +               } else {
20739 +                       // it's a kernel process
20740 +                       task->role = kernel_role;
20741 +                       task->acl = kernel_role->root_label;
20742 +#ifdef CONFIG_GRKERNSEC_ACL_HIDEKERN
20743 +                       task->acl->mode &= ~GR_PROCFIND;
20744 +#endif
20745 +               }
20746 +       } while_each_thread(task2, task);
20747 +       read_unlock(&grsec_exec_file_lock);
20748 +       read_unlock(&tasklist_lock);
20749 +       return 0;
20750 +}
20751 +
20752 +void
20753 +gr_learn_resource(const struct task_struct *task,
20754 +                 const int res, const unsigned long wanted, const int gt)
20755 +{
20756 +       struct acl_subject_label *acl;
20757 +
20758 +       if (unlikely((gr_status & GR_READY) &&
20759 +                    task->acl && (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))))
20760 +               goto skip_reslog;
20761 +
20762 +#ifdef CONFIG_GRKERNSEC_RESLOG
20763 +       gr_log_resource(task, res, wanted, gt);
20764 +#endif
20765 +      skip_reslog:
20766 +
20767 +       if (unlikely(!(gr_status & GR_READY) || !wanted))
20768 +               return;
20769 +
20770 +       acl = task->acl;
20771 +
20772 +       if (likely(!acl || !(acl->mode & (GR_LEARN | GR_INHERITLEARN)) ||
20773 +                  !(acl->resmask & (1 << (unsigned short) res))))
20774 +               return;
20775 +
20776 +       if (wanted >= acl->res[res].rlim_cur) {
20777 +               unsigned long res_add;
20778 +
20779 +               res_add = wanted;
20780 +               switch (res) {
20781 +               case RLIMIT_CPU:
20782 +                       res_add += GR_RLIM_CPU_BUMP;
20783 +                       break;
20784 +               case RLIMIT_FSIZE:
20785 +                       res_add += GR_RLIM_FSIZE_BUMP;
20786 +                       break;
20787 +               case RLIMIT_DATA:
20788 +                       res_add += GR_RLIM_DATA_BUMP;
20789 +                       break;
20790 +               case RLIMIT_STACK:
20791 +                       res_add += GR_RLIM_STACK_BUMP;
20792 +                       break;
20793 +               case RLIMIT_CORE:
20794 +                       res_add += GR_RLIM_CORE_BUMP;
20795 +                       break;
20796 +               case RLIMIT_RSS:
20797 +                       res_add += GR_RLIM_RSS_BUMP;
20798 +                       break;
20799 +               case RLIMIT_NPROC:
20800 +                       res_add += GR_RLIM_NPROC_BUMP;
20801 +                       break;
20802 +               case RLIMIT_NOFILE:
20803 +                       res_add += GR_RLIM_NOFILE_BUMP;
20804 +                       break;
20805 +               case RLIMIT_MEMLOCK:
20806 +                       res_add += GR_RLIM_MEMLOCK_BUMP;
20807 +                       break;
20808 +               case RLIMIT_AS:
20809 +                       res_add += GR_RLIM_AS_BUMP;
20810 +                       break;
20811 +               case RLIMIT_LOCKS:
20812 +                       res_add += GR_RLIM_LOCKS_BUMP;
20813 +                       break;
20814 +               }
20815 +
20816 +               acl->res[res].rlim_cur = res_add;
20817 +
20818 +               if (wanted > acl->res[res].rlim_max)
20819 +                       acl->res[res].rlim_max = res_add;
20820 +
20821 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
20822 +                              task->role->roletype, acl->filename,
20823 +                              acl->res[res].rlim_cur, acl->res[res].rlim_max,
20824 +                              "", (unsigned long) res);
20825 +       }
20826 +
20827 +       return;
20828 +}
20829 +
20830 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
20831 +void
20832 +pax_set_initial_flags(struct linux_binprm *bprm)
20833 +{
20834 +       struct task_struct *task = current;
20835 +        struct acl_subject_label *proc;
20836 +       unsigned long flags;
20837 +
20838 +        if (unlikely(!(gr_status & GR_READY)))
20839 +                return;
20840 +
20841 +       flags = pax_get_flags(task);
20842 +
20843 +        proc = task->acl;
20844 +
20845 +       if (proc->pax_flags & GR_PAX_DISABLE_PAGEEXEC)
20846 +               flags &= ~MF_PAX_PAGEEXEC;
20847 +       if (proc->pax_flags & GR_PAX_DISABLE_SEGMEXEC)
20848 +               flags &= ~MF_PAX_SEGMEXEC;
20849 +       if (proc->pax_flags & GR_PAX_DISABLE_RANDMMAP)
20850 +               flags &= ~MF_PAX_RANDMMAP;
20851 +       if (proc->pax_flags & GR_PAX_DISABLE_EMUTRAMP)
20852 +               flags &= ~MF_PAX_EMUTRAMP;
20853 +       if (proc->pax_flags & GR_PAX_DISABLE_MPROTECT)
20854 +               flags &= ~MF_PAX_MPROTECT;
20855 +
20856 +       if (proc->pax_flags & GR_PAX_ENABLE_PAGEEXEC)
20857 +               flags |= MF_PAX_PAGEEXEC;
20858 +       if (proc->pax_flags & GR_PAX_ENABLE_SEGMEXEC)
20859 +               flags |= MF_PAX_SEGMEXEC;
20860 +       if (proc->pax_flags & GR_PAX_ENABLE_RANDMMAP)
20861 +               flags |= MF_PAX_RANDMMAP;
20862 +       if (proc->pax_flags & GR_PAX_ENABLE_EMUTRAMP)
20863 +               flags |= MF_PAX_EMUTRAMP;
20864 +       if (proc->pax_flags & GR_PAX_ENABLE_MPROTECT)
20865 +               flags |= MF_PAX_MPROTECT;
20866 +
20867 +       pax_set_flags(task, flags);
20868 +
20869 +        return;
20870 +}
20871 +#endif
20872 +
20873 +#ifdef CONFIG_SYSCTL
20874 +/* Eric Biederman likes breaking userland ABI and every inode-based security
20875 +   system to save 35kb of memory */
20876 +
20877 +/* we modify the passed in filename, but adjust it back before returning */
20878 +static struct acl_object_label *gr_lookup_by_name(char *name, unsigned int len)
20879 +{
20880 +       struct name_entry *nmatch;
20881 +       char *p, *lastp = NULL;
20882 +       struct acl_object_label *obj = NULL, *tmp;
20883 +       struct acl_subject_label *tmpsubj;
20884 +       char c = '\0';
20885 +
20886 +       read_lock(&gr_inode_lock);
20887 +
20888 +       p = name + len - 1;
20889 +       do {
20890 +               nmatch = lookup_name_entry(name);
20891 +               if (lastp != NULL)
20892 +                       *lastp = c;
20893 +
20894 +               if (nmatch == NULL)
20895 +                       goto next_component;
20896 +               tmpsubj = current->acl;
20897 +               do {
20898 +                       obj = lookup_acl_obj_label(nmatch->inode, nmatch->device, tmpsubj);
20899 +                       if (obj != NULL) {
20900 +                               tmp = obj->globbed;
20901 +                               while (tmp) {
20902 +                                       if (!glob_match(tmp->filename, name)) {
20903 +                                               obj = tmp;
20904 +                                               goto found_obj;
20905 +                                       }
20906 +                                       tmp = tmp->next;
20907 +                               }
20908 +                               goto found_obj;
20909 +                       }
20910 +               } while ((tmpsubj = tmpsubj->parent_subject));
20911 +next_component:
20912 +               /* end case */
20913 +               if (p == name)
20914 +                       break;
20915 +
20916 +               while (*p != '/')
20917 +                       p--;
20918 +               if (p == name)
20919 +                       lastp = p + 1;
20920 +               else {
20921 +                       lastp = p;
20922 +                       p--;
20923 +               }
20924 +               c = *lastp;
20925 +               *lastp = '\0';
20926 +       } while (1);
20927 +found_obj:
20928 +       read_unlock(&gr_inode_lock);
20929 +       /* obj returned will always be non-null */
20930 +       return obj;
20931 +}
20932 +
20933 +/* returns 0 when allowing, non-zero on error
20934 +   op of 0 is used for readdir, so we don't log the names of hidden files
20935 +*/
20936 +__u32
20937 +gr_handle_sysctl(const struct ctl_table *table, const int op)
20938 +{
20939 +       ctl_table *tmp;
20940 +       const char *proc_sys = "/proc/sys";
20941 +       char *path;
20942 +       struct acl_object_label *obj;
20943 +       unsigned short len = 0, pos = 0, depth = 0, i;
20944 +       __u32 err = 0;
20945 +       __u32 mode = 0;
20946 +
20947 +       if (unlikely(!(gr_status & GR_READY)))
20948 +               return 0;
20949 +
20950 +       /* for now, ignore operations on non-sysctl entries if it's not a
20951 +          readdir*/
20952 +       if (table->child != NULL && op != 0)
20953 +               return 0;
20954 +
20955 +       mode |= GR_FIND;
20956 +       /* it's only a read if it's an entry, read on dirs is for readdir */
20957 +       if (op & MAY_READ)
20958 +               mode |= GR_READ;
20959 +       if (op & MAY_WRITE)
20960 +               mode |= GR_WRITE;
20961 +
20962 +       preempt_disable();
20963 +
20964 +       path = per_cpu_ptr(gr_shared_page[0], smp_processor_id());
20965 +
20966 +       /* it's only a read/write if it's an actual entry, not a dir
20967 +          (which are opened for readdir)
20968 +       */
20969 +
20970 +       /* convert the requested sysctl entry into a pathname */
20971 +
20972 +       for (tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20973 +               len += strlen(tmp->procname);
20974 +               len++;
20975 +               depth++;
20976 +       }
20977 +
20978 +       if ((len + depth + strlen(proc_sys) + 1) > PAGE_SIZE) {
20979 +               /* deny */
20980 +               goto out;
20981 +       }
20982 +
20983 +       memset(path, 0, PAGE_SIZE);
20984 +
20985 +       memcpy(path, proc_sys, strlen(proc_sys));
20986 +
20987 +       pos += strlen(proc_sys);
20988 +
20989 +       for (; depth > 0; depth--) {
20990 +               path[pos] = '/';
20991 +               pos++;
20992 +               for (i = 1, tmp = (ctl_table *)table; tmp != NULL; tmp = tmp->parent) {
20993 +                       if (depth == i) {
20994 +                               memcpy(path + pos, tmp->procname,
20995 +                                      strlen(tmp->procname));
20996 +                               pos += strlen(tmp->procname);
20997 +                       }
20998 +                       i++;
20999 +               }
21000 +       }
21001 +
21002 +       obj = gr_lookup_by_name(path, pos);
21003 +       err = obj->mode & (mode | to_gr_audit(mode) | GR_SUPPRESS);
21004 +
21005 +       if (unlikely((current->acl->mode & (GR_LEARN | GR_INHERITLEARN)) &&
21006 +                    ((err & mode) != mode))) {
21007 +               __u32 new_mode = mode;
21008 +
21009 +               new_mode &= ~(GR_AUDITS | GR_SUPPRESS);
21010 +
21011 +               err = 0;
21012 +               gr_log_learn_sysctl(current, path, new_mode);
21013 +       } else if (!(err & GR_FIND) && !(err & GR_SUPPRESS) && op != 0) {
21014 +               gr_log_hidden_sysctl(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, path);
21015 +               err = -ENOENT;
21016 +       } else if (!(err & GR_FIND)) {
21017 +               err = -ENOENT;
21018 +       } else if (((err & mode) & ~GR_FIND) != (mode & ~GR_FIND) && !(err & GR_SUPPRESS)) {
21019 +               gr_log_str4(GR_DONT_AUDIT, GR_SYSCTL_ACL_MSG, "denied",
21020 +                              path, (mode & GR_READ) ? " reading" : "",
21021 +                              (mode & GR_WRITE) ? " writing" : "");
21022 +               err = -EACCES;
21023 +       } else if ((err & mode) != mode) {
21024 +               err = -EACCES;
21025 +       } else if ((((err & mode) & ~GR_FIND) == (mode & ~GR_FIND)) && (err & GR_AUDITS)) {
21026 +               gr_log_str4(GR_DO_AUDIT, GR_SYSCTL_ACL_MSG, "successful",
21027 +                              path, (mode & GR_READ) ? " reading" : "",
21028 +                              (mode & GR_WRITE) ? " writing" : "");
21029 +               err = 0;
21030 +       } else
21031 +               err = 0;
21032 +
21033 +      out:
21034 +       preempt_enable();
21035 +
21036 +       return err;
21037 +}
21038 +#endif
21039 +
21040 +int
21041 +gr_handle_proc_ptrace(struct task_struct *task)
21042 +{
21043 +       struct file *filp;
21044 +       struct task_struct *tmp = task;
21045 +       struct task_struct *curtemp = current;
21046 +       __u32 retmode;
21047 +
21048 +       if (unlikely(!(gr_status & GR_READY)))
21049 +               return 0;
21050 +
21051 +       read_lock(&tasklist_lock);
21052 +       read_lock(&grsec_exec_file_lock);
21053 +       filp = task->exec_file;
21054 +
21055 +       while (tmp->pid > 0) {
21056 +               if (tmp == curtemp)
21057 +                       break;
21058 +               tmp = tmp->parent;
21059 +       }
21060 +
21061 +       if (!filp || (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE))) {
21062 +               read_unlock(&grsec_exec_file_lock);
21063 +               read_unlock(&tasklist_lock);
21064 +               return 1;
21065 +       }
21066 +
21067 +       retmode = gr_search_file(filp->f_path.dentry, GR_NOPTRACE, filp->f_path.mnt);
21068 +       read_unlock(&grsec_exec_file_lock);
21069 +       read_unlock(&tasklist_lock);
21070 +
21071 +       if (retmode & GR_NOPTRACE)
21072 +               return 1;
21073 +
21074 +       if (!(current->acl->mode & GR_POVERRIDE) && !(current->role->roletype & GR_ROLE_GOD)
21075 +           && (current->acl != task->acl || (current->acl != current->role->root_label
21076 +           && current->pid != task->pid)))
21077 +               return 1;
21078 +
21079 +       return 0;
21080 +}
21081 +
21082 +int
21083 +gr_handle_ptrace(struct task_struct *task, const long request)
21084 +{
21085 +       struct task_struct *tmp = task;
21086 +       struct task_struct *curtemp = current;
21087 +       __u32 retmode;
21088 +
21089 +       if (unlikely(!(gr_status & GR_READY)))
21090 +               return 0;
21091 +
21092 +       read_lock(&tasklist_lock);
21093 +       while (tmp->pid > 0) {
21094 +               if (tmp == curtemp)
21095 +                       break;
21096 +               tmp = tmp->parent;
21097 +       }
21098 +
21099 +       if (tmp->pid == 0 && !(current->acl->mode & GR_RELAXPTRACE)) {
21100 +               read_unlock(&tasklist_lock);
21101 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21102 +               return 1;
21103 +       }
21104 +       read_unlock(&tasklist_lock);
21105 +
21106 +       read_lock(&grsec_exec_file_lock);
21107 +       if (unlikely(!task->exec_file)) {
21108 +               read_unlock(&grsec_exec_file_lock);
21109 +               return 0;
21110 +       }
21111 +
21112 +       retmode = gr_search_file(task->exec_file->f_path.dentry, GR_PTRACERD | GR_NOPTRACE, task->exec_file->f_path.mnt);
21113 +       read_unlock(&grsec_exec_file_lock);
21114 +
21115 +       if (retmode & GR_NOPTRACE) {
21116 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21117 +               return 1;
21118 +       }
21119 +               
21120 +       if (retmode & GR_PTRACERD) {
21121 +               switch (request) {
21122 +               case PTRACE_POKETEXT:
21123 +               case PTRACE_POKEDATA:
21124 +               case PTRACE_POKEUSR:
21125 +#if !defined(CONFIG_PPC32) && !defined(CONFIG_PPC64) && !defined(CONFIG_PARISC) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64)
21126 +               case PTRACE_SETREGS:
21127 +               case PTRACE_SETFPREGS:
21128 +#endif
21129 +#ifdef CONFIG_X86
21130 +               case PTRACE_SETFPXREGS:
21131 +#endif
21132 +#ifdef CONFIG_ALTIVEC
21133 +               case PTRACE_SETVRREGS:
21134 +#endif
21135 +                       return 1;
21136 +               default:
21137 +                       return 0;
21138 +               }
21139 +       } else if (!(current->acl->mode & GR_POVERRIDE) &&
21140 +                  !(current->role->roletype & GR_ROLE_GOD) &&
21141 +                  (current->acl != task->acl)) {
21142 +               gr_log_ptrace(GR_DONT_AUDIT, GR_PTRACE_ACL_MSG, task);
21143 +               return 1;
21144 +       }
21145 +
21146 +       return 0;
21147 +}
21148 +
21149 +static int is_writable_mmap(const struct file *filp)
21150 +{
21151 +       struct task_struct *task = current;
21152 +       struct acl_object_label *obj, *obj2;
21153 +
21154 +       if (gr_status & GR_READY && !(task->acl->mode & GR_OVERRIDE) &&
21155 +           !task->is_writable && S_ISREG(filp->f_path.dentry->d_inode->i_mode)) {
21156 +               obj = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt, default_role->root_label);
21157 +               obj2 = chk_obj_label(filp->f_path.dentry, filp->f_path.mnt,
21158 +                                    task->role->root_label);
21159 +               if (unlikely((obj->mode & GR_WRITE) || (obj2->mode & GR_WRITE))) {
21160 +                       gr_log_fs_generic(GR_DONT_AUDIT, GR_WRITLIB_ACL_MSG, filp->f_path.dentry, filp->f_path.mnt);
21161 +                       return 1;
21162 +               }
21163 +       }
21164 +       return 0;
21165 +}
21166 +
21167 +int
21168 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot)
21169 +{
21170 +       __u32 mode;
21171 +
21172 +       if (unlikely(!file || !(prot & PROT_EXEC)))
21173 +               return 1;
21174 +
21175 +       if (is_writable_mmap(file))
21176 +               return 0;
21177 +
21178 +       mode =
21179 +           gr_search_file(file->f_path.dentry,
21180 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21181 +                          file->f_path.mnt);
21182 +
21183 +       if (!gr_tpe_allow(file))
21184 +               return 0;
21185 +
21186 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21187 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21188 +               return 0;
21189 +       } else if (unlikely(!(mode & GR_EXEC))) {
21190 +               return 0;
21191 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21192 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MMAP_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21193 +               return 1;
21194 +       }
21195 +
21196 +       return 1;
21197 +}
21198 +
21199 +int
21200 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
21201 +{
21202 +       __u32 mode;
21203 +
21204 +       if (unlikely(!file || !(prot & PROT_EXEC)))
21205 +               return 1;
21206 +
21207 +       if (is_writable_mmap(file))
21208 +               return 0;
21209 +
21210 +       mode =
21211 +           gr_search_file(file->f_path.dentry,
21212 +                          GR_EXEC | GR_AUDIT_EXEC | GR_SUPPRESS,
21213 +                          file->f_path.mnt);
21214 +
21215 +       if (!gr_tpe_allow(file))
21216 +               return 0;
21217 +
21218 +       if (unlikely(!(mode & GR_EXEC) && !(mode & GR_SUPPRESS))) {
21219 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21220 +               return 0;
21221 +       } else if (unlikely(!(mode & GR_EXEC))) {
21222 +               return 0;
21223 +       } else if (unlikely(mode & GR_EXEC && mode & GR_AUDIT_EXEC)) {
21224 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_MPROTECT_ACL_MSG, file->f_path.dentry, file->f_path.mnt);
21225 +               return 1;
21226 +       }
21227 +
21228 +       return 1;
21229 +}
21230 +
21231 +void
21232 +gr_acl_handle_psacct(struct task_struct *task, const long code)
21233 +{
21234 +       unsigned long runtime;
21235 +       unsigned long cputime;
21236 +       unsigned int wday, cday;
21237 +       __u8 whr, chr;
21238 +       __u8 wmin, cmin;
21239 +       __u8 wsec, csec;
21240 +       struct timespec timeval;
21241 +
21242 +       if (unlikely(!(gr_status & GR_READY) || !task->acl ||
21243 +                    !(task->acl->mode & GR_PROCACCT)))
21244 +               return;
21245 +
21246 +       do_posix_clock_monotonic_gettime(&timeval);
21247 +       runtime = timeval.tv_sec - task->start_time.tv_sec;
21248 +       wday = runtime / (3600 * 24);
21249 +       runtime -= wday * (3600 * 24);
21250 +       whr = runtime / 3600;
21251 +       runtime -= whr * 3600;
21252 +       wmin = runtime / 60;
21253 +       runtime -= wmin * 60;
21254 +       wsec = runtime;
21255 +
21256 +       cputime = (task->utime + task->stime) / HZ;
21257 +       cday = cputime / (3600 * 24);
21258 +       cputime -= cday * (3600 * 24);
21259 +       chr = cputime / 3600;
21260 +       cputime -= chr * 3600;
21261 +       cmin = cputime / 60;
21262 +       cputime -= cmin * 60;
21263 +       csec = cputime;
21264 +
21265 +       gr_log_procacct(GR_DO_AUDIT, GR_ACL_PROCACCT_MSG, task, wday, whr, wmin, wsec, cday, chr, cmin, csec, code);
21266 +
21267 +       return;
21268 +}
21269 +
21270 +void gr_set_kernel_label(struct task_struct *task)
21271 +{
21272 +       if (gr_status & GR_READY) {
21273 +               task->role = kernel_role;
21274 +               task->acl = kernel_role->root_label;
21275 +       }
21276 +       return;
21277 +}
21278 +
21279 +int gr_acl_handle_filldir(const struct file *file, const char *name, const unsigned int namelen, const ino_t ino)
21280 +{
21281 +       struct task_struct *task = current;
21282 +       struct dentry *dentry = file->f_path.dentry;
21283 +       struct vfsmount *mnt = file->f_path.mnt;
21284 +       struct acl_object_label *obj, *tmp;
21285 +       struct acl_subject_label *subj;
21286 +       unsigned int bufsize;
21287 +       int is_not_root;
21288 +       char *path;
21289 +
21290 +       if (unlikely(!(gr_status & GR_READY)))
21291 +               return 1;
21292 +
21293 +       if (task->acl->mode & (GR_LEARN | GR_INHERITLEARN))
21294 +               return 1;
21295 +
21296 +       /* ignore Eric Biederman */
21297 +       if (IS_PRIVATE(dentry->d_inode))
21298 +               return 1;
21299 +
21300 +       subj = task->acl;
21301 +       do {
21302 +               obj = lookup_acl_obj_label(ino, dentry->d_inode->i_sb->s_dev, subj);
21303 +               if (obj != NULL)
21304 +                       return (obj->mode & GR_FIND) ? 1 : 0;
21305 +       } while ((subj = subj->parent_subject));
21306 +       
21307 +       obj = chk_obj_label(dentry, mnt, task->acl);
21308 +       if (obj->globbed == NULL)
21309 +               return (obj->mode & GR_FIND) ? 1 : 0;
21310 +
21311 +       is_not_root = ((obj->filename[0] == '/') &&
21312 +                  (obj->filename[1] == '\0')) ? 0 : 1;
21313 +       bufsize = PAGE_SIZE - namelen - is_not_root;
21314 +
21315 +       /* check bufsize > PAGE_SIZE || bufsize == 0 */
21316 +       if (unlikely((bufsize - 1) > (PAGE_SIZE - 1)))
21317 +               return 1;
21318 +
21319 +       preempt_disable();
21320 +       path = d_real_path(dentry, mnt, per_cpu_ptr(gr_shared_page[0], smp_processor_id()),
21321 +                          bufsize);
21322 +
21323 +       bufsize = strlen(path);
21324 +
21325 +       /* if base is "/", don't append an additional slash */
21326 +       if (is_not_root)
21327 +               *(path + bufsize) = '/';
21328 +       memcpy(path + bufsize + is_not_root, name, namelen);
21329 +       *(path + bufsize + namelen + is_not_root) = '\0';
21330 +
21331 +       tmp = obj->globbed;
21332 +       while (tmp) {
21333 +               if (!glob_match(tmp->filename, path)) {
21334 +                       preempt_enable();
21335 +                       return (tmp->mode & GR_FIND) ? 1 : 0;
21336 +               }
21337 +               tmp = tmp->next;
21338 +       }
21339 +       preempt_enable();
21340 +       return (obj->mode & GR_FIND) ? 1 : 0;
21341 +}
21342 +
21343 +EXPORT_SYMBOL(gr_learn_resource);
21344 +EXPORT_SYMBOL(gr_set_kernel_label);
21345 +#ifdef CONFIG_SECURITY
21346 +EXPORT_SYMBOL(gr_check_user_change);
21347 +EXPORT_SYMBOL(gr_check_group_change);
21348 +#endif
21349 +
21350 diff -urNp linux-2.6.27.10/grsecurity/gracl_cap.c linux-2.6.27.10/grsecurity/gracl_cap.c
21351 --- linux-2.6.27.10/grsecurity/gracl_cap.c      1969-12-31 19:00:00.000000000 -0500
21352 +++ linux-2.6.27.10/grsecurity/gracl_cap.c      2008-11-18 03:38:45.000000000 -0500
21353 @@ -0,0 +1,129 @@
21354 +#include <linux/kernel.h>
21355 +#include <linux/module.h>
21356 +#include <linux/sched.h>
21357 +#include <linux/gracl.h>
21358 +#include <linux/grsecurity.h>
21359 +#include <linux/grinternal.h>
21360 +
21361 +static const char *captab_log[] = {
21362 +       "CAP_CHOWN",
21363 +       "CAP_DAC_OVERRIDE",
21364 +       "CAP_DAC_READ_SEARCH",
21365 +       "CAP_FOWNER",
21366 +       "CAP_FSETID",
21367 +       "CAP_KILL",
21368 +       "CAP_SETGID",
21369 +       "CAP_SETUID",
21370 +       "CAP_SETPCAP",
21371 +       "CAP_LINUX_IMMUTABLE",
21372 +       "CAP_NET_BIND_SERVICE",
21373 +       "CAP_NET_BROADCAST",
21374 +       "CAP_NET_ADMIN",
21375 +       "CAP_NET_RAW",
21376 +       "CAP_IPC_LOCK",
21377 +       "CAP_IPC_OWNER",
21378 +       "CAP_SYS_MODULE",
21379 +       "CAP_SYS_RAWIO",
21380 +       "CAP_SYS_CHROOT",
21381 +       "CAP_SYS_PTRACE",
21382 +       "CAP_SYS_PACCT",
21383 +       "CAP_SYS_ADMIN",
21384 +       "CAP_SYS_BOOT",
21385 +       "CAP_SYS_NICE",
21386 +       "CAP_SYS_RESOURCE",
21387 +       "CAP_SYS_TIME",
21388 +       "CAP_SYS_TTY_CONFIG",
21389 +       "CAP_MKNOD",
21390 +       "CAP_LEASE",
21391 +       "CAP_AUDIT_WRITE",
21392 +       "CAP_AUDIT_CONTROL",
21393 +       "CAP_SETFCAP",
21394 +       "CAP_MAC_OVERRIDE",
21395 +       "CAP_MAC_ADMIN"
21396 +};
21397 +
21398 +EXPORT_SYMBOL(gr_task_is_capable);
21399 +EXPORT_SYMBOL(gr_is_capable_nolog);
21400 +
21401 +int
21402 +gr_task_is_capable(struct task_struct *task, const int cap)
21403 +{
21404 +       struct acl_subject_label *curracl;
21405 +       kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21406 +
21407 +       if (!gr_acl_is_enabled())
21408 +               return 1;
21409 +
21410 +       curracl = task->acl;
21411 +
21412 +       cap_drop = curracl->cap_lower;
21413 +       cap_mask = curracl->cap_mask;
21414 +
21415 +       while ((curracl = curracl->parent_subject)) {
21416 +               /* if the cap isn't specified in the current computed mask but is specified in the
21417 +                  current level subject, and is lowered in the current level subject, then add
21418 +                  it to the set of dropped capabilities
21419 +                  otherwise, add the current level subject's mask to the current computed mask
21420 +                */
21421 +               if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21422 +                       cap_raise(cap_mask, cap);
21423 +                       if (cap_raised(curracl->cap_lower, cap))
21424 +                               cap_raise(cap_drop, cap);
21425 +               }
21426 +       }
21427 +
21428 +       if (!cap_raised(cap_drop, cap))
21429 +               return 1;
21430 +
21431 +       curracl = task->acl;
21432 +
21433 +       if ((curracl->mode & (GR_LEARN | GR_INHERITLEARN))
21434 +           && cap_raised(task->cap_effective, cap)) {
21435 +               security_learn(GR_LEARN_AUDIT_MSG, task->role->rolename,
21436 +                              task->role->roletype, task->uid,
21437 +                              task->gid, task->exec_file ?
21438 +                              gr_to_filename(task->exec_file->f_path.dentry,
21439 +                              task->exec_file->f_path.mnt) : curracl->filename,
21440 +                              curracl->filename, 0UL,
21441 +                              0UL, "", (unsigned long) cap, NIPQUAD(task->signal->curr_ip));
21442 +               return 1;
21443 +       }
21444 +
21445 +       if ((cap >= 0) && (cap < (sizeof(captab_log)/sizeof(captab_log[0]))) && cap_raised(task->cap_effective, cap))
21446 +               gr_log_cap(GR_DONT_AUDIT, GR_CAP_ACL_MSG, task, captab_log[cap]);
21447 +       return 0;
21448 +}
21449 +
21450 +int
21451 +gr_is_capable_nolog(const int cap)
21452 +{
21453 +       struct acl_subject_label *curracl;
21454 +       kernel_cap_t cap_drop = __cap_empty_set, cap_mask = __cap_empty_set;
21455 +
21456 +       if (!gr_acl_is_enabled())
21457 +               return 1;
21458 +
21459 +       curracl = current->acl;
21460 +
21461 +       cap_drop = curracl->cap_lower;
21462 +       cap_mask = curracl->cap_mask;
21463 +
21464 +       while ((curracl = curracl->parent_subject)) {
21465 +               /* if the cap isn't specified in the current computed mask but is specified in the
21466 +                  current level subject, and is lowered in the current level subject, then add
21467 +                  it to the set of dropped capabilities
21468 +                  otherwise, add the current level subject's mask to the current computed mask
21469 +                */
21470 +               if (!cap_raised(cap_mask, cap) && cap_raised(curracl->cap_mask, cap)) {
21471 +                       cap_raise(cap_mask, cap);
21472 +                       if (cap_raised(curracl->cap_lower, cap))
21473 +                               cap_raise(cap_drop, cap);
21474 +               }
21475 +       }
21476 +
21477 +       if (!cap_raised(cap_drop, cap))
21478 +               return 1;
21479 +
21480 +       return 0;
21481 +}
21482 +
21483 diff -urNp linux-2.6.27.10/grsecurity/gracl_fs.c linux-2.6.27.10/grsecurity/gracl_fs.c
21484 --- linux-2.6.27.10/grsecurity/gracl_fs.c       1969-12-31 19:00:00.000000000 -0500
21485 +++ linux-2.6.27.10/grsecurity/gracl_fs.c       2008-11-18 03:38:45.000000000 -0500
21486 @@ -0,0 +1,423 @@
21487 +#include <linux/kernel.h>
21488 +#include <linux/sched.h>
21489 +#include <linux/types.h>
21490 +#include <linux/fs.h>
21491 +#include <linux/file.h>
21492 +#include <linux/stat.h>
21493 +#include <linux/grsecurity.h>
21494 +#include <linux/grinternal.h>
21495 +#include <linux/gracl.h>
21496 +
21497 +__u32
21498 +gr_acl_handle_hidden_file(const struct dentry * dentry,
21499 +                         const struct vfsmount * mnt)
21500 +{
21501 +       __u32 mode;
21502 +
21503 +       if (unlikely(!dentry->d_inode))
21504 +               return GR_FIND;
21505 +
21506 +       mode =
21507 +           gr_search_file(dentry, GR_FIND | GR_AUDIT_FIND | GR_SUPPRESS, mnt);
21508 +
21509 +       if (unlikely(mode & GR_FIND && mode & GR_AUDIT_FIND)) {
21510 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21511 +               return mode;
21512 +       } else if (unlikely(!(mode & GR_FIND) && !(mode & GR_SUPPRESS))) {
21513 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, GR_HIDDEN_ACL_MSG, dentry, mnt);
21514 +               return 0;
21515 +       } else if (unlikely(!(mode & GR_FIND)))
21516 +               return 0;
21517 +
21518 +       return GR_FIND;
21519 +}
21520 +
21521 +__u32
21522 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
21523 +                  const int fmode)
21524 +{
21525 +       __u32 reqmode = GR_FIND;
21526 +       __u32 mode;
21527 +
21528 +       if (unlikely(!dentry->d_inode))
21529 +               return reqmode;
21530 +
21531 +       if (unlikely(fmode & O_APPEND))
21532 +               reqmode |= GR_APPEND;
21533 +       else if (unlikely(fmode & FMODE_WRITE))
21534 +               reqmode |= GR_WRITE;
21535 +       if (likely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21536 +               reqmode |= GR_READ;
21537 +
21538 +       mode =
21539 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21540 +                          mnt);
21541 +
21542 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21543 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21544 +                              reqmode & GR_READ ? " reading" : "",
21545 +                              reqmode & GR_WRITE ? " writing" : reqmode &
21546 +                              GR_APPEND ? " appending" : "");
21547 +               return reqmode;
21548 +       } else
21549 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21550 +       {
21551 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_OPEN_ACL_MSG, dentry, mnt,
21552 +                              reqmode & GR_READ ? " reading" : "",
21553 +                              reqmode & GR_WRITE ? " writing" : reqmode &
21554 +                              GR_APPEND ? " appending" : "");
21555 +               return 0;
21556 +       } else if (unlikely((mode & reqmode) != reqmode))
21557 +               return 0;
21558 +
21559 +       return reqmode;
21560 +}
21561 +
21562 +__u32
21563 +gr_acl_handle_creat(const struct dentry * dentry,
21564 +                   const struct dentry * p_dentry,
21565 +                   const struct vfsmount * p_mnt, const int fmode,
21566 +                   const int imode)
21567 +{
21568 +       __u32 reqmode = GR_WRITE | GR_CREATE;
21569 +       __u32 mode;
21570 +
21571 +       if (unlikely(fmode & O_APPEND))
21572 +               reqmode |= GR_APPEND;
21573 +       if (unlikely((fmode & FMODE_READ) && !(fmode & O_DIRECTORY)))
21574 +               reqmode |= GR_READ;
21575 +       if (unlikely((fmode & O_CREAT) && (imode & (S_ISUID | S_ISGID))))
21576 +               reqmode |= GR_SETID;
21577 +
21578 +       mode =
21579 +           gr_check_create(dentry, p_dentry, p_mnt,
21580 +                           reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21581 +
21582 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21583 +               gr_log_fs_rbac_mode2(GR_DO_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21584 +                              reqmode & GR_READ ? " reading" : "",
21585 +                              reqmode & GR_WRITE ? " writing" : reqmode &
21586 +                              GR_APPEND ? " appending" : "");
21587 +               return reqmode;
21588 +       } else
21589 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21590 +       {
21591 +               gr_log_fs_rbac_mode2(GR_DONT_AUDIT, GR_CREATE_ACL_MSG, dentry, p_mnt,
21592 +                              reqmode & GR_READ ? " reading" : "",
21593 +                              reqmode & GR_WRITE ? " writing" : reqmode &
21594 +                              GR_APPEND ? " appending" : "");
21595 +               return 0;
21596 +       } else if (unlikely((mode & reqmode) != reqmode))
21597 +               return 0;
21598 +
21599 +       return reqmode;
21600 +}
21601 +
21602 +__u32
21603 +gr_acl_handle_access(const struct dentry * dentry, const struct vfsmount * mnt,
21604 +                    const int fmode)
21605 +{
21606 +       __u32 mode, reqmode = GR_FIND;
21607 +
21608 +       if ((fmode & S_IXOTH) && !S_ISDIR(dentry->d_inode->i_mode))
21609 +               reqmode |= GR_EXEC;
21610 +       if (fmode & S_IWOTH)
21611 +               reqmode |= GR_WRITE;
21612 +       if (fmode & S_IROTH)
21613 +               reqmode |= GR_READ;
21614 +
21615 +       mode =
21616 +           gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS,
21617 +                          mnt);
21618 +
21619 +       if (unlikely(((mode & reqmode) == reqmode) && mode & GR_AUDITS)) {
21620 +               gr_log_fs_rbac_mode3(GR_DO_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21621 +                              reqmode & GR_READ ? " reading" : "",
21622 +                              reqmode & GR_WRITE ? " writing" : "",
21623 +                              reqmode & GR_EXEC ? " executing" : "");
21624 +               return reqmode;
21625 +       } else
21626 +           if (unlikely((mode & reqmode) != reqmode && !(mode & GR_SUPPRESS)))
21627 +       {
21628 +               gr_log_fs_rbac_mode3(GR_DONT_AUDIT, GR_ACCESS_ACL_MSG, dentry, mnt,
21629 +                              reqmode & GR_READ ? " reading" : "",
21630 +                              reqmode & GR_WRITE ? " writing" : "",
21631 +                              reqmode & GR_EXEC ? " executing" : "");
21632 +               return 0;
21633 +       } else if (unlikely((mode & reqmode) != reqmode))
21634 +               return 0;
21635 +
21636 +       return reqmode;
21637 +}
21638 +
21639 +static __u32 generic_fs_handler(const struct dentry *dentry, const struct vfsmount *mnt, __u32 reqmode, const char *fmt)
21640 +{
21641 +       __u32 mode;
21642 +
21643 +       mode = gr_search_file(dentry, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS, mnt);
21644 +
21645 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21646 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, dentry, mnt);
21647 +               return mode;
21648 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21649 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, dentry, mnt);
21650 +               return 0;
21651 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
21652 +               return 0;
21653 +
21654 +       return (reqmode);
21655 +}
21656 +
21657 +__u32
21658 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
21659 +{
21660 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_RMDIR_ACL_MSG);
21661 +}
21662 +
21663 +__u32
21664 +gr_acl_handle_unlink(const struct dentry *dentry, const struct vfsmount *mnt)
21665 +{
21666 +       return generic_fs_handler(dentry, mnt, GR_WRITE | GR_DELETE , GR_UNLINK_ACL_MSG);
21667 +}
21668 +
21669 +__u32
21670 +gr_acl_handle_truncate(const struct dentry *dentry, const struct vfsmount *mnt)
21671 +{
21672 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_TRUNCATE_ACL_MSG);
21673 +}
21674 +
21675 +__u32
21676 +gr_acl_handle_utime(const struct dentry *dentry, const struct vfsmount *mnt)
21677 +{
21678 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_ATIME_ACL_MSG);
21679 +}
21680 +
21681 +__u32
21682 +gr_acl_handle_fchmod(const struct dentry *dentry, const struct vfsmount *mnt,
21683 +                    mode_t mode)
21684 +{
21685 +       if (unlikely(dentry->d_inode && S_ISSOCK(dentry->d_inode->i_mode)))
21686 +               return 1;
21687 +
21688 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21689 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21690 +                                  GR_FCHMOD_ACL_MSG);
21691 +       } else {
21692 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_FCHMOD_ACL_MSG);
21693 +       }
21694 +}
21695 +
21696 +__u32
21697 +gr_acl_handle_chmod(const struct dentry *dentry, const struct vfsmount *mnt,
21698 +                   mode_t mode)
21699 +{
21700 +       if (unlikely((mode != (mode_t)-1) && (mode & (S_ISUID | S_ISGID)))) {
21701 +               return generic_fs_handler(dentry, mnt, GR_WRITE | GR_SETID,
21702 +                                  GR_CHMOD_ACL_MSG);
21703 +       } else {
21704 +               return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHMOD_ACL_MSG);
21705 +       }
21706 +}
21707 +
21708 +__u32
21709 +gr_acl_handle_chown(const struct dentry *dentry, const struct vfsmount *mnt)
21710 +{
21711 +       return generic_fs_handler(dentry, mnt, GR_WRITE, GR_CHOWN_ACL_MSG);
21712 +}
21713 +
21714 +__u32
21715 +gr_acl_handle_execve(const struct dentry *dentry, const struct vfsmount *mnt)
21716 +{
21717 +       return generic_fs_handler(dentry, mnt, GR_EXEC, GR_EXEC_ACL_MSG);
21718 +}
21719 +
21720 +__u32
21721 +gr_acl_handle_unix(const struct dentry *dentry, const struct vfsmount *mnt)
21722 +{
21723 +       return generic_fs_handler(dentry, mnt, GR_READ | GR_WRITE,
21724 +                          GR_UNIXCONNECT_ACL_MSG);
21725 +}
21726 +
21727 +/* hardlinks require at minimum create permission,
21728 +   any additional privilege required is based on the
21729 +   privilege of the file being linked to
21730 +*/
21731 +__u32
21732 +gr_acl_handle_link(const struct dentry * new_dentry,
21733 +                  const struct dentry * parent_dentry,
21734 +                  const struct vfsmount * parent_mnt,
21735 +                  const struct dentry * old_dentry,
21736 +                  const struct vfsmount * old_mnt, const char *to)
21737 +{
21738 +       __u32 mode;
21739 +       __u32 needmode = GR_CREATE | GR_LINK;
21740 +       __u32 needaudit = GR_AUDIT_CREATE | GR_AUDIT_LINK;
21741 +
21742 +       mode =
21743 +           gr_check_link(new_dentry, parent_dentry, parent_mnt, old_dentry,
21744 +                         old_mnt);
21745 +
21746 +       if (unlikely(((mode & needmode) == needmode) && (mode & needaudit))) {
21747 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21748 +               return mode;
21749 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21750 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_LINK_ACL_MSG, old_dentry, old_mnt, to);
21751 +               return 0;
21752 +       } else if (unlikely((mode & needmode) != needmode))
21753 +               return 0;
21754 +
21755 +       return 1;
21756 +}
21757 +
21758 +__u32
21759 +gr_acl_handle_symlink(const struct dentry * new_dentry,
21760 +                     const struct dentry * parent_dentry,
21761 +                     const struct vfsmount * parent_mnt, const char *from)
21762 +{
21763 +       __u32 needmode = GR_WRITE | GR_CREATE;
21764 +       __u32 mode;
21765 +
21766 +       mode =
21767 +           gr_check_create(new_dentry, parent_dentry, parent_mnt,
21768 +                           GR_CREATE | GR_AUDIT_CREATE |
21769 +                           GR_WRITE | GR_AUDIT_WRITE | GR_SUPPRESS);
21770 +
21771 +       if (unlikely(mode & GR_WRITE && mode & GR_AUDITS)) {
21772 +               gr_log_fs_str_rbac(GR_DO_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21773 +               return mode;
21774 +       } else if (unlikely(((mode & needmode) != needmode) && !(mode & GR_SUPPRESS))) {
21775 +               gr_log_fs_str_rbac(GR_DONT_AUDIT, GR_SYMLINK_ACL_MSG, from, new_dentry, parent_mnt);
21776 +               return 0;
21777 +       } else if (unlikely((mode & needmode) != needmode))
21778 +               return 0;
21779 +
21780 +       return (GR_WRITE | GR_CREATE);
21781 +}
21782 +
21783 +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)
21784 +{
21785 +       __u32 mode;
21786 +
21787 +       mode = gr_check_create(new_dentry, parent_dentry, parent_mnt, reqmode | to_gr_audit(reqmode) | GR_SUPPRESS);
21788 +
21789 +       if (unlikely(((mode & (reqmode)) == (reqmode)) && mode & GR_AUDITS)) {
21790 +               gr_log_fs_rbac_generic(GR_DO_AUDIT, fmt, new_dentry, parent_mnt);
21791 +               return mode;
21792 +       } else if (unlikely((mode & (reqmode)) != (reqmode) && !(mode & GR_SUPPRESS))) {
21793 +               gr_log_fs_rbac_generic(GR_DONT_AUDIT, fmt, new_dentry, parent_mnt);
21794 +               return 0;
21795 +       } else if (unlikely((mode & (reqmode)) != (reqmode)))
21796 +               return 0;
21797 +
21798 +       return (reqmode);
21799 +}
21800 +
21801 +__u32
21802 +gr_acl_handle_mknod(const struct dentry * new_dentry,
21803 +                   const struct dentry * parent_dentry,
21804 +                   const struct vfsmount * parent_mnt,
21805 +                   const int mode)
21806 +{
21807 +       __u32 reqmode = GR_WRITE | GR_CREATE;
21808 +       if (unlikely(mode & (S_ISUID | S_ISGID)))
21809 +               reqmode |= GR_SETID;
21810 +
21811 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21812 +                                 reqmode, GR_MKNOD_ACL_MSG);
21813 +}
21814 +
21815 +__u32
21816 +gr_acl_handle_mkdir(const struct dentry *new_dentry,
21817 +                   const struct dentry *parent_dentry,
21818 +                   const struct vfsmount *parent_mnt)
21819 +{
21820 +       return generic_fs_create_handler(new_dentry, parent_dentry, parent_mnt,
21821 +                                 GR_WRITE | GR_CREATE, GR_MKDIR_ACL_MSG);
21822 +}
21823 +
21824 +#define RENAME_CHECK_SUCCESS(old, new) \
21825 +       (((old & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)) && \
21826 +        ((new & (GR_WRITE | GR_READ)) == (GR_WRITE | GR_READ)))
21827 +
21828 +int
21829 +gr_acl_handle_rename(struct dentry *new_dentry,
21830 +                    struct dentry *parent_dentry,
21831 +                    const struct vfsmount *parent_mnt,
21832 +                    struct dentry *old_dentry,
21833 +                    struct inode *old_parent_inode,
21834 +                    struct vfsmount *old_mnt, const char *newname)
21835 +{
21836 +       __u32 comp1, comp2;
21837 +       int error = 0;
21838 +
21839 +       if (unlikely(!gr_acl_is_enabled()))
21840 +               return 0;
21841 +
21842 +       if (!new_dentry->d_inode) {
21843 +               comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
21844 +                                       GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
21845 +                                       GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
21846 +               comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
21847 +                                      GR_DELETE | GR_AUDIT_DELETE |
21848 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
21849 +                                      GR_SUPPRESS, old_mnt);
21850 +       } else {
21851 +               comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
21852 +                                      GR_CREATE | GR_DELETE |
21853 +                                      GR_AUDIT_CREATE | GR_AUDIT_DELETE |
21854 +                                      GR_AUDIT_READ | GR_AUDIT_WRITE |
21855 +                                      GR_SUPPRESS, parent_mnt);
21856 +               comp2 =
21857 +                   gr_search_file(old_dentry,
21858 +                                  GR_READ | GR_WRITE | GR_AUDIT_READ |
21859 +                                  GR_DELETE | GR_AUDIT_DELETE |
21860 +                                  GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
21861 +       }
21862 +
21863 +       if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
21864 +           ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
21865 +               gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21866 +       else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
21867 +                && !(comp2 & GR_SUPPRESS)) {
21868 +               gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname);
21869 +               error = -EACCES;
21870 +       } else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
21871 +               error = -EACCES;
21872 +
21873 +       return error;
21874 +}
21875 +
21876 +void
21877 +gr_acl_handle_exit(void)
21878 +{
21879 +       u16 id;
21880 +       char *rolename;
21881 +       struct file *exec_file;
21882 +
21883 +       if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
21884 +               id = current->acl_role_id;
21885 +               rolename = current->role->rolename;
21886 +               gr_set_acls(1);
21887 +               gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
21888 +       }
21889 +
21890 +       write_lock(&grsec_exec_file_lock);
21891 +       exec_file = current->exec_file;
21892 +       current->exec_file = NULL;
21893 +       write_unlock(&grsec_exec_file_lock);
21894 +
21895 +       if (exec_file)
21896 +               fput(exec_file);
21897 +}
21898 +
21899 +int
21900 +gr_acl_handle_procpidmem(const struct task_struct *task)
21901 +{
21902 +       if (unlikely(!gr_acl_is_enabled()))
21903 +               return 0;
21904 +
21905 +       if (task != current && task->acl->mode & GR_PROTPROCFD)
21906 +               return -EACCES;
21907 +
21908 +       return 0;
21909 +}
21910 diff -urNp linux-2.6.27.10/grsecurity/gracl_ip.c linux-2.6.27.10/grsecurity/gracl_ip.c
21911 --- linux-2.6.27.10/grsecurity/gracl_ip.c       1969-12-31 19:00:00.000000000 -0500
21912 +++ linux-2.6.27.10/grsecurity/gracl_ip.c       2008-11-18 03:38:45.000000000 -0500
21913 @@ -0,0 +1,313 @@
21914 +#include <linux/kernel.h>
21915 +#include <asm/uaccess.h>
21916 +#include <asm/errno.h>
21917 +#include <net/sock.h>
21918 +#include <linux/file.h>
21919 +#include <linux/fs.h>
21920 +#include <linux/net.h>
21921 +#include <linux/in.h>
21922 +#include <linux/skbuff.h>
21923 +#include <linux/ip.h>
21924 +#include <linux/udp.h>
21925 +#include <linux/smp_lock.h>
21926 +#include <linux/types.h>
21927 +#include <linux/sched.h>
21928 +#include <linux/netdevice.h>
21929 +#include <linux/inetdevice.h>
21930 +#include <linux/gracl.h>
21931 +#include <linux/grsecurity.h>
21932 +#include <linux/grinternal.h>
21933 +
21934 +#define GR_BIND        0x01
21935 +#define GR_CONNECT     0x02
21936 +#define GR_INVERT      0x04
21937 +
21938 +static const char * gr_protocols[256] = {
21939 +       "ip", "icmp", "igmp", "ggp", "ipencap", "st", "tcp", "cbt",
21940 +       "egp", "igp", "bbn-rcc", "nvp", "pup", "argus", "emcon", "xnet",
21941 +       "chaos", "udp", "mux", "dcn", "hmp", "prm", "xns-idp", "trunk-1",
21942 +       "trunk-2", "leaf-1", "leaf-2", "rdp", "irtp", "iso-tp4", "netblt", "mfe-nsp",
21943 +       "merit-inp", "sep", "3pc", "idpr", "xtp", "ddp", "idpr-cmtp", "tp++",
21944 +       "il", "ipv6", "sdrp", "ipv6-route", "ipv6-frag", "idrp", "rsvp", "gre",
21945 +       "mhrp", "bna", "ipv6-crypt", "ipv6-auth", "i-nlsp", "swipe", "narp", "mobile",
21946 +       "tlsp", "skip", "ipv6-icmp", "ipv6-nonxt", "ipv6-opts", "unknown:61", "cftp", "unknown:63",
21947 +       "sat-expak", "kryptolan", "rvd", "ippc", "unknown:68", "sat-mon", "visa", "ipcv",
21948 +       "cpnx", "cphb", "wsn", "pvp", "br-sat-mon", "sun-nd", "wb-mon", "wb-expak", 
21949 +       "iso-ip", "vmtp", "secure-vmtp", "vines", "ttp", "nfsnet-igp", "dgp", "tcf", 
21950 +       "eigrp", "ospf", "sprite-rpc", "larp", "mtp", "ax.25", "ipip", "micp",
21951 +       "scc-sp", "etherip", "encap", "unknown:99", "gmtp", "ifmp", "pnni", "pim",
21952 +       "aris", "scps", "qnx", "a/n", "ipcomp", "snp", "compaq-peer", "ipx-in-ip",
21953 +       "vrrp", "pgm", "unknown:114", "l2tp", "ddx", "iatp", "stp", "srp",
21954 +       "uti", "smp", "sm", "ptp", "isis", "fire", "crtp", "crdup",
21955 +       "sscopmce", "iplt", "sps", "pipe", "sctp", "fc", "unkown:134", "unknown:135",
21956 +       "unknown:136", "unknown:137", "unknown:138", "unknown:139", "unknown:140", "unknown:141", "unknown:142", "unknown:143",
21957 +       "unknown:144", "unknown:145", "unknown:146", "unknown:147", "unknown:148", "unknown:149", "unknown:150", "unknown:151",
21958 +       "unknown:152", "unknown:153", "unknown:154", "unknown:155", "unknown:156", "unknown:157", "unknown:158", "unknown:159",
21959 +       "unknown:160", "unknown:161", "unknown:162", "unknown:163", "unknown:164", "unknown:165", "unknown:166", "unknown:167",
21960 +       "unknown:168", "unknown:169", "unknown:170", "unknown:171", "unknown:172", "unknown:173", "unknown:174", "unknown:175",
21961 +       "unknown:176", "unknown:177", "unknown:178", "unknown:179", "unknown:180", "unknown:181", "unknown:182", "unknown:183",
21962 +       "unknown:184", "unknown:185", "unknown:186", "unknown:187", "unknown:188", "unknown:189", "unknown:190", "unknown:191",
21963 +       "unknown:192", "unknown:193", "unknown:194", "unknown:195", "unknown:196", "unknown:197", "unknown:198", "unknown:199",
21964 +       "unknown:200", "unknown:201", "unknown:202", "unknown:203", "unknown:204", "unknown:205", "unknown:206", "unknown:207",
21965 +       "unknown:208", "unknown:209", "unknown:210", "unknown:211", "unknown:212", "unknown:213", "unknown:214", "unknown:215",
21966 +       "unknown:216", "unknown:217", "unknown:218", "unknown:219", "unknown:220", "unknown:221", "unknown:222", "unknown:223",
21967 +       "unknown:224", "unknown:225", "unknown:226", "unknown:227", "unknown:228", "unknown:229", "unknown:230", "unknown:231",
21968 +       "unknown:232", "unknown:233", "unknown:234", "unknown:235", "unknown:236", "unknown:237", "unknown:238", "unknown:239",
21969 +       "unknown:240", "unknown:241", "unknown:242", "unknown:243", "unknown:244", "unknown:245", "unknown:246", "unknown:247",
21970 +       "unknown:248", "unknown:249", "unknown:250", "unknown:251", "unknown:252", "unknown:253", "unknown:254", "unknown:255",
21971 +       };
21972 +
21973 +static const char * gr_socktypes[11] = {
21974 +       "unknown:0", "stream", "dgram", "raw", "rdm", "seqpacket", "unknown:6", 
21975 +       "unknown:7", "unknown:8", "unknown:9", "packet"
21976 +       };
21977 +
21978 +const char *
21979 +gr_proto_to_name(unsigned char proto)
21980 +{
21981 +       return gr_protocols[proto];
21982 +}
21983 +
21984 +const char *
21985 +gr_socktype_to_name(unsigned char type)
21986 +{
21987 +       return gr_socktypes[type];
21988 +}
21989 +
21990 +int
21991 +gr_search_socket(const int domain, const int type, const int protocol)
21992 +{
21993 +       struct acl_subject_label *curr;
21994 +
21995 +       if (unlikely(!gr_acl_is_enabled()))
21996 +               goto exit;
21997 +
21998 +       if ((domain < 0) || (type < 0) || (protocol < 0) || (domain != PF_INET)
21999 +           || (domain >= NPROTO) || (type >= SOCK_MAX) || (protocol > 255))
22000 +               goto exit;      // let the kernel handle it
22001 +
22002 +       curr = current->acl;
22003 +
22004 +       if (!curr->ips)
22005 +               goto exit;
22006 +
22007 +       if ((curr->ip_type & (1 << type)) &&
22008 +           (curr->ip_proto[protocol / 32] & (1 << (protocol % 32))))
22009 +               goto exit;
22010 +
22011 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22012 +               /* we don't place acls on raw sockets , and sometimes
22013 +                  dgram/ip sockets are opened for ioctl and not
22014 +                  bind/connect, so we'll fake a bind learn log */
22015 +               if (type == SOCK_RAW || type == SOCK_PACKET) {
22016 +                       __u32 fakeip = 0;
22017 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22018 +                                      current->role->roletype, current->uid,
22019 +                                      current->gid, current->exec_file ?
22020 +                                      gr_to_filename(current->exec_file->f_path.dentry,
22021 +                                      current->exec_file->f_path.mnt) :
22022 +                                      curr->filename, curr->filename,
22023 +                                      NIPQUAD(fakeip), 0, type,
22024 +                                      protocol, GR_CONNECT, 
22025 +NIPQUAD(current->signal->curr_ip));
22026 +               } else if ((type == SOCK_DGRAM) && (protocol == IPPROTO_IP)) {
22027 +                       __u32 fakeip = 0;
22028 +                       security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22029 +                                      current->role->roletype, current->uid,
22030 +                                      current->gid, current->exec_file ?
22031 +                                      gr_to_filename(current->exec_file->f_path.dentry,
22032 +                                      current->exec_file->f_path.mnt) :
22033 +                                      curr->filename, curr->filename,
22034 +                                      NIPQUAD(fakeip), 0, type,
22035 +                                      protocol, GR_BIND, NIPQUAD(current->signal->curr_ip));
22036 +               }
22037 +               /* we'll log when they use connect or bind */
22038 +               goto exit;
22039 +       }
22040 +
22041 +       gr_log_str3(GR_DONT_AUDIT, GR_SOCK_MSG, "inet", 
22042 +                   gr_socktype_to_name(type), gr_proto_to_name(protocol));
22043 +
22044 +       return 0;
22045 +      exit:
22046 +       return 1;
22047 +}
22048 +
22049 +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)
22050 +{
22051 +       if ((ip->mode & mode) &&
22052 +           (ip_port >= ip->low) &&
22053 +           (ip_port <= ip->high) &&
22054 +           ((ntohl(ip_addr) & our_netmask) ==
22055 +            (ntohl(our_addr) & our_netmask))
22056 +           && (ip->proto[protocol / 32] & (1 << (protocol % 32)))
22057 +           && (ip->type & (1 << type))) {
22058 +               if (ip->mode & GR_INVERT)
22059 +                       return 2; // specifically denied
22060 +               else
22061 +                       return 1; // allowed
22062 +       }
22063 +
22064 +       return 0; // not specifically allowed, may continue parsing
22065 +}
22066 +
22067 +static int
22068 +gr_search_connectbind(const int mode, const struct sock *sk,
22069 +                     const struct sockaddr_in *addr, const int type)
22070 +{
22071 +       char iface[IFNAMSIZ] = {0};
22072 +       struct acl_subject_label *curr;
22073 +       struct acl_ip_label *ip;
22074 +       struct net_device *dev;
22075 +       struct in_device *idev;
22076 +       unsigned long i;
22077 +       int ret;
22078 +       __u32 ip_addr = 0;
22079 +       __u32 our_addr;
22080 +       __u32 our_netmask;
22081 +       char *p;
22082 +       __u16 ip_port = 0;
22083 +
22084 +       if (unlikely(!gr_acl_is_enabled() || sk->sk_family != PF_INET))
22085 +               return 1;
22086 +
22087 +       curr = current->acl;
22088 +
22089 +       if (!curr->ips)
22090 +               return 1;
22091 +
22092 +       ip_addr = addr->sin_addr.s_addr;
22093 +       ip_port = ntohs(addr->sin_port);
22094 +
22095 +       if (curr->mode & (GR_LEARN | GR_INHERITLEARN)) {
22096 +               security_learn(GR_IP_LEARN_MSG, current->role->rolename,
22097 +                              current->role->roletype, current->uid,
22098 +                              current->gid, current->exec_file ?
22099 +                              gr_to_filename(current->exec_file->f_path.dentry,
22100 +                              current->exec_file->f_path.mnt) :
22101 +                              curr->filename, curr->filename,
22102 +                              NIPQUAD(ip_addr), ip_port, type,
22103 +                              sk->sk_protocol, mode, NIPQUAD(current->signal->curr_ip));
22104 +               return 1;
22105 +       }
22106 +
22107 +       for (i = 0; i < curr->ip_num; i++) {
22108 +               ip = *(curr->ips + i);
22109 +               if (ip->iface != NULL) {
22110 +                       strncpy(iface, ip->iface, IFNAMSIZ - 1);
22111 +                       p = strchr(iface, ':');
22112 +                       if (p != NULL)
22113 +                               *p = '\0';
22114 +                       dev = dev_get_by_name(sock_net(sk), iface);
22115 +                       if (dev == NULL)
22116 +                               continue;
22117 +                       idev = in_dev_get(dev);
22118 +                       if (idev == NULL) {
22119 +                               dev_put(dev);
22120 +                               continue;
22121 +                       }
22122 +                       rcu_read_lock();
22123 +                       for_ifa(idev) {
22124 +                               if (!strcmp(ip->iface, ifa->ifa_label)) {
22125 +                                       our_addr = ifa->ifa_address;
22126 +                                       our_netmask = 0xffffffff;
22127 +                                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22128 +                                       if (ret == 1) {
22129 +                                               rcu_read_unlock();
22130 +                                               in_dev_put(idev);
22131 +                                               dev_put(dev);
22132 +                                               return 1;
22133 +                                       } else if (ret == 2) {
22134 +                                               rcu_read_unlock();
22135 +                                               in_dev_put(idev);
22136 +                                               dev_put(dev);
22137 +                                               goto denied;
22138 +                                       }
22139 +                               }
22140 +                       } endfor_ifa(idev);
22141 +                       rcu_read_unlock();
22142 +                       in_dev_put(idev);
22143 +                       dev_put(dev);
22144 +               } else {
22145 +                       our_addr = ip->addr;
22146 +                       our_netmask = ip->netmask;
22147 +                       ret = check_ip_policy(ip, ip_addr, ip_port, sk->sk_protocol, mode, type, our_addr, our_netmask);
22148 +                       if (ret == 1)
22149 +                               return 1;
22150 +                       else if (ret == 2)
22151 +                               goto denied;
22152 +               }
22153 +       }
22154 +
22155 +denied:
22156 +       if (mode == GR_BIND)
22157 +               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));
22158 +       else if (mode == GR_CONNECT)
22159 +               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));
22160 +
22161 +       return 0;
22162 +}
22163 +
22164 +int
22165 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
22166 +{
22167 +       return gr_search_connectbind(GR_CONNECT, sock->sk, addr, sock->type);
22168 +}
22169 +
22170 +int
22171 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
22172 +{
22173 +       return gr_search_connectbind(GR_BIND, sock->sk, addr, sock->type);
22174 +}
22175 +
22176 +int gr_search_listen(const struct socket *sock)
22177 +{
22178 +       struct sock *sk = sock->sk;
22179 +       struct sockaddr_in addr;
22180 +
22181 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22182 +       addr.sin_port = inet_sk(sk)->sport;
22183 +
22184 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22185 +}
22186 +
22187 +int gr_search_accept(const struct socket *sock)
22188 +{
22189 +       struct sock *sk = sock->sk;
22190 +       struct sockaddr_in addr;
22191 +
22192 +       addr.sin_addr.s_addr = inet_sk(sk)->saddr;
22193 +       addr.sin_port = inet_sk(sk)->sport;
22194 +
22195 +       return gr_search_connectbind(GR_BIND, sock->sk, &addr, sock->type);
22196 +}
22197 +
22198 +int
22199 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
22200 +{
22201 +       if (addr)
22202 +               return gr_search_connectbind(GR_CONNECT, sk, addr, SOCK_DGRAM);
22203 +       else {
22204 +               struct sockaddr_in sin;
22205 +               const struct inet_sock *inet = inet_sk(sk);
22206 +
22207 +               sin.sin_addr.s_addr = inet->daddr;
22208 +               sin.sin_port = inet->dport;
22209 +
22210 +               return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22211 +       }
22212 +}
22213 +
22214 +int
22215 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
22216 +{
22217 +       struct sockaddr_in sin;
22218 +
22219 +       if (unlikely(skb->len < sizeof (struct udphdr)))
22220 +               return 1;       // skip this packet
22221 +
22222 +       sin.sin_addr.s_addr = ip_hdr(skb)->saddr;
22223 +       sin.sin_port = udp_hdr(skb)->source;
22224 +
22225 +       return gr_search_connectbind(GR_CONNECT, sk, &sin, SOCK_DGRAM);
22226 +}
22227 diff -urNp linux-2.6.27.10/grsecurity/gracl_learn.c linux-2.6.27.10/grsecurity/gracl_learn.c
22228 --- linux-2.6.27.10/grsecurity/gracl_learn.c    1969-12-31 19:00:00.000000000 -0500
22229 +++ linux-2.6.27.10/grsecurity/gracl_learn.c    2008-11-18 03:38:45.000000000 -0500
22230 @@ -0,0 +1,211 @@
22231 +#include <linux/kernel.h>
22232 +#include <linux/mm.h>
22233 +#include <linux/sched.h>
22234 +#include <linux/poll.h>
22235 +#include <linux/smp_lock.h>
22236 +#include <linux/string.h>
22237 +#include <linux/file.h>
22238 +#include <linux/types.h>
22239 +#include <linux/vmalloc.h>
22240 +#include <linux/grinternal.h>
22241 +
22242 +extern ssize_t write_grsec_handler(struct file * file, const char __user * buf,
22243 +                                  size_t count, loff_t *ppos);
22244 +extern int gr_acl_is_enabled(void);
22245 +
22246 +static DECLARE_WAIT_QUEUE_HEAD(learn_wait);
22247 +static int gr_learn_attached;
22248 +
22249 +/* use a 512k buffer */
22250 +#define LEARN_BUFFER_SIZE (512 * 1024)
22251 +
22252 +static DEFINE_SPINLOCK(gr_learn_lock);
22253 +static DECLARE_MUTEX(gr_learn_user_sem);
22254 +
22255 +/* we need to maintain two buffers, so that the kernel context of grlearn
22256 +   uses a semaphore around the userspace copying, and the other kernel contexts
22257 +   use a spinlock when copying into the buffer, since they cannot sleep
22258 +*/
22259 +static char *learn_buffer;
22260 +static char *learn_buffer_user;
22261 +static int learn_buffer_len;
22262 +static int learn_buffer_user_len;
22263 +
22264 +static ssize_t
22265 +read_learn(struct file *file, char __user * buf, size_t count, loff_t * ppos)
22266 +{
22267 +       DECLARE_WAITQUEUE(wait, current);
22268 +       ssize_t retval = 0;
22269 +
22270 +       add_wait_queue(&learn_wait, &wait);
22271 +       set_current_state(TASK_INTERRUPTIBLE);
22272 +       do {
22273 +               down(&gr_learn_user_sem);
22274 +               spin_lock(&gr_learn_lock);
22275 +               if (learn_buffer_len)
22276 +                       break;
22277 +               spin_unlock(&gr_learn_lock);
22278 +               up(&gr_learn_user_sem);
22279 +               if (file->f_flags & O_NONBLOCK) {
22280 +                       retval = -EAGAIN;
22281 +                       goto out;
22282 +               }
22283 +               if (signal_pending(current)) {
22284 +                       retval = -ERESTARTSYS;
22285 +                       goto out;
22286 +               }
22287 +
22288 +               schedule();
22289 +       } while (1);
22290 +
22291 +       memcpy(learn_buffer_user, learn_buffer, learn_buffer_len);
22292 +       learn_buffer_user_len = learn_buffer_len;
22293 +       retval = learn_buffer_len;
22294 +       learn_buffer_len = 0;
22295 +
22296 +       spin_unlock(&gr_learn_lock);
22297 +
22298 +       if (copy_to_user(buf, learn_buffer_user, learn_buffer_user_len))
22299 +               retval = -EFAULT;
22300 +
22301 +       up(&gr_learn_user_sem);
22302 +out:
22303 +       set_current_state(TASK_RUNNING);
22304 +       remove_wait_queue(&learn_wait, &wait);
22305 +       return retval;
22306 +}
22307 +
22308 +static unsigned int
22309 +poll_learn(struct file * file, poll_table * wait)
22310 +{
22311 +       poll_wait(file, &learn_wait, wait);
22312 +
22313 +       if (learn_buffer_len)
22314 +               return (POLLIN | POLLRDNORM);
22315 +
22316 +       return 0;
22317 +}
22318 +
22319 +void
22320 +gr_clear_learn_entries(void)
22321 +{
22322 +       char *tmp;
22323 +
22324 +       down(&gr_learn_user_sem);
22325 +       if (learn_buffer != NULL) {
22326 +               spin_lock(&gr_learn_lock);
22327 +               tmp = learn_buffer;
22328 +               learn_buffer = NULL;
22329 +               spin_unlock(&gr_learn_lock);
22330 +               vfree(learn_buffer);
22331 +       }
22332 +       if (learn_buffer_user != NULL) {
22333 +               vfree(learn_buffer_user);
22334 +               learn_buffer_user = NULL;
22335 +       }
22336 +       learn_buffer_len = 0;
22337 +       up(&gr_learn_user_sem);
22338 +
22339 +       return;
22340 +}
22341 +
22342 +void
22343 +gr_add_learn_entry(const char *fmt, ...)
22344 +{
22345 +       va_list args;
22346 +       unsigned int len;
22347 +
22348 +       if (!gr_learn_attached)
22349 +               return;
22350 +
22351 +       spin_lock(&gr_learn_lock);
22352 +
22353 +       /* leave a gap at the end so we know when it's "full" but don't have to
22354 +          compute the exact length of the string we're trying to append
22355 +       */
22356 +       if (learn_buffer_len > LEARN_BUFFER_SIZE - 16384) {
22357 +               spin_unlock(&gr_learn_lock);
22358 +               wake_up_interruptible(&learn_wait);
22359 +               return;
22360 +       }
22361 +       if (learn_buffer == NULL) {
22362 +               spin_unlock(&gr_learn_lock);
22363 +               return;
22364 +       }
22365 +
22366 +       va_start(args, fmt);
22367 +       len = vsnprintf(learn_buffer + learn_buffer_len, LEARN_BUFFER_SIZE - learn_buffer_len, fmt, args);
22368 +       va_end(args);
22369 +
22370 +       learn_buffer_len += len + 1;
22371 +
22372 +       spin_unlock(&gr_learn_lock);
22373 +       wake_up_interruptible(&learn_wait);
22374 +
22375 +       return;
22376 +}
22377 +
22378 +static int
22379 +open_learn(struct inode *inode, struct file *file)
22380 +{
22381 +       if (file->f_mode & FMODE_READ && gr_learn_attached)
22382 +               return -EBUSY;
22383 +       if (file->f_mode & FMODE_READ) {
22384 +               int retval = 0;
22385 +               down(&gr_learn_user_sem);
22386 +               if (learn_buffer == NULL)
22387 +                       learn_buffer = vmalloc(LEARN_BUFFER_SIZE);
22388 +               if (learn_buffer_user == NULL)
22389 +                       learn_buffer_user = vmalloc(LEARN_BUFFER_SIZE);
22390 +               if (learn_buffer == NULL) {
22391 +                       retval = -ENOMEM;
22392 +                       goto out_error;
22393 +               }
22394 +               if (learn_buffer_user == NULL) {
22395 +                       retval = -ENOMEM;
22396 +                       goto out_error;
22397 +               }
22398 +               learn_buffer_len = 0;
22399 +               learn_buffer_user_len = 0;
22400 +               gr_learn_attached = 1;
22401 +out_error:
22402 +               up(&gr_learn_user_sem);
22403 +               return retval;
22404 +       }
22405 +       return 0;
22406 +}
22407 +
22408 +static int
22409 +close_learn(struct inode *inode, struct file *file)
22410 +{
22411 +       char *tmp;
22412 +
22413 +       if (file->f_mode & FMODE_READ) {
22414 +               down(&gr_learn_user_sem);
22415 +               if (learn_buffer != NULL) {
22416 +                       spin_lock(&gr_learn_lock);
22417 +                       tmp = learn_buffer;
22418 +                       learn_buffer = NULL;
22419 +                       spin_unlock(&gr_learn_lock);
22420 +                       vfree(tmp);
22421 +               }
22422 +               if (learn_buffer_user != NULL) {
22423 +                       vfree(learn_buffer_user);
22424 +                       learn_buffer_user = NULL;
22425 +               }
22426 +               learn_buffer_len = 0;
22427 +               learn_buffer_user_len = 0;
22428 +               gr_learn_attached = 0;
22429 +               up(&gr_learn_user_sem);
22430 +       }
22431 +
22432 +       return 0;
22433 +}
22434 +               
22435 +struct file_operations grsec_fops = {
22436 +       .read           = read_learn,
22437 +       .write          = write_grsec_handler,
22438 +       .open           = open_learn,
22439 +       .release        = close_learn,
22440 +       .poll           = poll_learn,
22441 +};
22442 diff -urNp linux-2.6.27.10/grsecurity/gracl_res.c linux-2.6.27.10/grsecurity/gracl_res.c
22443 --- linux-2.6.27.10/grsecurity/gracl_res.c      1969-12-31 19:00:00.000000000 -0500
22444 +++ linux-2.6.27.10/grsecurity/gracl_res.c      2008-11-18 03:38:45.000000000 -0500
22445 @@ -0,0 +1,45 @@
22446 +#include <linux/kernel.h>
22447 +#include <linux/sched.h>
22448 +#include <linux/gracl.h>
22449 +#include <linux/grinternal.h>
22450 +
22451 +static const char *restab_log[] = {
22452 +       [RLIMIT_CPU] = "RLIMIT_CPU",
22453 +       [RLIMIT_FSIZE] = "RLIMIT_FSIZE",
22454 +       [RLIMIT_DATA] = "RLIMIT_DATA",
22455 +       [RLIMIT_STACK] = "RLIMIT_STACK",
22456 +       [RLIMIT_CORE] = "RLIMIT_CORE",
22457 +       [RLIMIT_RSS] = "RLIMIT_RSS",
22458 +       [RLIMIT_NPROC] = "RLIMIT_NPROC",
22459 +       [RLIMIT_NOFILE] = "RLIMIT_NOFILE",
22460 +       [RLIMIT_MEMLOCK] = "RLIMIT_MEMLOCK",
22461 +       [RLIMIT_AS] = "RLIMIT_AS",
22462 +       [RLIMIT_LOCKS] = "RLIMIT_LOCKS",
22463 +       [RLIMIT_LOCKS + 1] = "RLIMIT_CRASH"
22464 +};
22465 +
22466 +void
22467 +gr_log_resource(const struct task_struct *task,
22468 +               const int res, const unsigned long wanted, const int gt)
22469 +{
22470 +       if (res == RLIMIT_NPROC && 
22471 +           (cap_raised(task->cap_effective, CAP_SYS_ADMIN) || 
22472 +            cap_raised(task->cap_effective, CAP_SYS_RESOURCE)))
22473 +               return;
22474 +       else if (res == RLIMIT_MEMLOCK &&
22475 +                cap_raised(task->cap_effective, CAP_IPC_LOCK))
22476 +               return;
22477 +
22478 +       if (!gr_acl_is_enabled() && !grsec_resource_logging)
22479 +               return;
22480 +
22481 +       preempt_disable();
22482 +
22483 +       if (unlikely(((gt && wanted > task->signal->rlim[res].rlim_cur) ||
22484 +                     (!gt && wanted >= task->signal->rlim[res].rlim_cur)) &&
22485 +                    task->signal->rlim[res].rlim_cur != RLIM_INFINITY))
22486 +               gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], task->signal->rlim[res].rlim_cur);
22487 +       preempt_enable_no_resched();
22488 +
22489 +       return;
22490 +}
22491 diff -urNp linux-2.6.27.10/grsecurity/gracl_segv.c linux-2.6.27.10/grsecurity/gracl_segv.c
22492 --- linux-2.6.27.10/grsecurity/gracl_segv.c     1969-12-31 19:00:00.000000000 -0500
22493 +++ linux-2.6.27.10/grsecurity/gracl_segv.c     2008-11-18 03:38:45.000000000 -0500
22494 @@ -0,0 +1,304 @@
22495 +#include <linux/kernel.h>
22496 +#include <linux/mm.h>
22497 +#include <asm/uaccess.h>
22498 +#include <asm/errno.h>
22499 +#include <asm/mman.h>
22500 +#include <net/sock.h>
22501 +#include <linux/file.h>
22502 +#include <linux/fs.h>
22503 +#include <linux/net.h>
22504 +#include <linux/in.h>
22505 +#include <linux/smp_lock.h>
22506 +#include <linux/slab.h>
22507 +#include <linux/types.h>
22508 +#include <linux/sched.h>
22509 +#include <linux/timer.h>
22510 +#include <linux/gracl.h>
22511 +#include <linux/grsecurity.h>
22512 +#include <linux/grinternal.h>
22513 +
22514 +static struct crash_uid *uid_set;
22515 +static unsigned short uid_used;
22516 +static DEFINE_SPINLOCK(gr_uid_lock);
22517 +extern rwlock_t gr_inode_lock;
22518 +extern struct acl_subject_label *
22519 +       lookup_acl_subj_label(const ino_t inode, const dev_t dev,
22520 +                             struct acl_role_label *role);
22521 +extern int specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t);
22522 +
22523 +int
22524 +gr_init_uidset(void)
22525 +{
22526 +       uid_set =
22527 +           kmalloc(GR_UIDTABLE_MAX * sizeof (struct crash_uid), GFP_KERNEL);
22528 +       uid_used = 0;
22529 +
22530 +       return uid_set ? 1 : 0;
22531 +}
22532 +
22533 +void
22534 +gr_free_uidset(void)
22535 +{
22536 +       if (uid_set)
22537 +               kfree(uid_set);
22538 +
22539 +       return;
22540 +}
22541 +
22542 +int
22543 +gr_find_uid(const uid_t uid)
22544 +{
22545 +       struct crash_uid *tmp = uid_set;
22546 +       uid_t buid;
22547 +       int low = 0, high = uid_used - 1, mid;
22548 +
22549 +       while (high >= low) {
22550 +               mid = (low + high) >> 1;
22551 +               buid = tmp[mid].uid;
22552 +               if (buid == uid)
22553 +                       return mid;
22554 +               if (buid > uid)
22555 +                       high = mid - 1;
22556 +               if (buid < uid)
22557 +                       low = mid + 1;
22558 +       }
22559 +
22560 +       return -1;
22561 +}
22562 +
22563 +static __inline__ void
22564 +gr_insertsort(void)
22565 +{
22566 +       unsigned short i, j;
22567 +       struct crash_uid index;
22568 +
22569 +       for (i = 1; i < uid_used; i++) {
22570 +               index = uid_set[i];
22571 +               j = i;
22572 +               while ((j > 0) && uid_set[j - 1].uid > index.uid) {
22573 +                       uid_set[j] = uid_set[j - 1];
22574 +                       j--;
22575 +               }
22576 +               uid_set[j] = index;
22577 +       }
22578 +
22579 +       return;
22580 +}
22581 +
22582 +static __inline__ void
22583 +gr_insert_uid(const uid_t uid, const unsigned long expires)
22584 +{
22585 +       int loc;
22586 +
22587 +       if (uid_used == GR_UIDTABLE_MAX)
22588 +               return;
22589 +
22590 +       loc = gr_find_uid(uid);
22591 +
22592 +       if (loc >= 0) {
22593 +               uid_set[loc].expires = expires;
22594 +               return;
22595 +       }
22596 +
22597 +       uid_set[uid_used].uid = uid;
22598 +       uid_set[uid_used].expires = expires;
22599 +       uid_used++;
22600 +
22601 +       gr_insertsort();
22602 +
22603 +       return;
22604 +}
22605 +
22606 +void
22607 +gr_remove_uid(const unsigned short loc)
22608 +{
22609 +       unsigned short i;
22610 +
22611 +       for (i = loc + 1; i < uid_used; i++)
22612 +               uid_set[i - 1] = uid_set[i];
22613 +
22614 +       uid_used--;
22615 +
22616 +       return;
22617 +}
22618 +
22619 +int
22620 +gr_check_crash_uid(const uid_t uid)
22621 +{
22622 +       int loc;
22623 +       int ret = 0;
22624 +
22625 +       if (unlikely(!gr_acl_is_enabled()))
22626 +               return 0;
22627 +
22628 +       spin_lock(&gr_uid_lock);
22629 +       loc = gr_find_uid(uid);
22630 +
22631 +       if (loc < 0)
22632 +               goto out_unlock;
22633 +
22634 +       if (time_before_eq(uid_set[loc].expires, get_seconds()))
22635 +               gr_remove_uid(loc);
22636 +       else
22637 +               ret = 1;
22638 +
22639 +out_unlock:
22640 +       spin_unlock(&gr_uid_lock);
22641 +       return ret;
22642 +}
22643 +
22644 +static __inline__ int
22645 +proc_is_setxid(const struct task_struct *task)
22646 +{
22647 +       if (task->uid != task->euid || task->uid != task->suid ||
22648 +           task->uid != task->fsuid)
22649 +               return 1;
22650 +       if (task->gid != task->egid || task->gid != task->sgid ||
22651 +           task->gid != task->fsgid)
22652 +               return 1;
22653 +
22654 +       return 0;
22655 +}
22656 +static __inline__ int
22657 +gr_fake_force_sig(int sig, struct task_struct *t)
22658 +{
22659 +       unsigned long int flags;
22660 +       int ret, blocked, ignored;
22661 +       struct k_sigaction *action;
22662 +
22663 +       spin_lock_irqsave(&t->sighand->siglock, flags);
22664 +       action = &t->sighand->action[sig-1];
22665 +       ignored = action->sa.sa_handler == SIG_IGN;
22666 +       blocked = sigismember(&t->blocked, sig);
22667 +       if (blocked || ignored) {
22668 +               action->sa.sa_handler = SIG_DFL;
22669 +               if (blocked) {
22670 +                       sigdelset(&t->blocked, sig);
22671 +                       recalc_sigpending_and_wake(t);
22672 +               }
22673 +       }
22674 +       if (action->sa.sa_handler == SIG_DFL)
22675 +               t->signal->flags &= ~SIGNAL_UNKILLABLE;
22676 +       ret = specific_send_sig_info(sig, SEND_SIG_PRIV, t);
22677 +
22678 +       spin_unlock_irqrestore(&t->sighand->siglock, flags);
22679 +
22680 +       return ret;
22681 +}
22682 +
22683 +void
22684 +gr_handle_crash(struct task_struct *task, const int sig)
22685 +{
22686 +       struct acl_subject_label *curr;
22687 +       struct acl_subject_label *curr2;
22688 +       struct task_struct *tsk, *tsk2;
22689 +
22690 +       if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
22691 +               return;
22692 +
22693 +       if (unlikely(!gr_acl_is_enabled()))
22694 +               return;
22695 +
22696 +       curr = task->acl;
22697 +
22698 +       if (!(curr->resmask & (1 << GR_CRASH_RES)))
22699 +               return;
22700 +
22701 +       if (time_before_eq(curr->expires, get_seconds())) {
22702 +               curr->expires = 0;
22703 +               curr->crashes = 0;
22704 +       }
22705 +
22706 +       curr->crashes++;
22707 +
22708 +       if (!curr->expires)
22709 +               curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;
22710 +
22711 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22712 +           time_after(curr->expires, get_seconds())) {
22713 +               if (task->uid && proc_is_setxid(task)) {
22714 +                       gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22715 +                       spin_lock(&gr_uid_lock);
22716 +                       gr_insert_uid(task->uid, curr->expires);
22717 +                       spin_unlock(&gr_uid_lock);
22718 +                       curr->expires = 0;
22719 +                       curr->crashes = 0;
22720 +                       read_lock(&tasklist_lock);
22721 +                       do_each_thread(tsk2, tsk) {
22722 +                               if (tsk != task && tsk->uid == task->uid)
22723 +                                       gr_fake_force_sig(SIGKILL, tsk);
22724 +                       } while_each_thread(tsk2, tsk);
22725 +                       read_unlock(&tasklist_lock);
22726 +               } else {
22727 +                       gr_log_crash2(GR_DONT_AUDIT, GR_SEGVNOSUID_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
22728 +                       read_lock(&tasklist_lock);
22729 +                       do_each_thread(tsk2, tsk) {
22730 +                               if (likely(tsk != task)) {
22731 +                                       curr2 = tsk->acl;
22732 +
22733 +                                       if (curr2->device == curr->device &&
22734 +                                           curr2->inode == curr->inode)
22735 +                                               gr_fake_force_sig(SIGKILL, tsk);
22736 +                               }
22737 +                       } while_each_thread(tsk2, tsk);
22738 +                       read_unlock(&tasklist_lock);
22739 +               }
22740 +       }
22741 +
22742 +       return;
22743 +}
22744 +
22745 +int
22746 +gr_check_crash_exec(const struct file *filp)
22747 +{
22748 +       struct acl_subject_label *curr;
22749 +
22750 +       if (unlikely(!gr_acl_is_enabled()))
22751 +               return 0;
22752 +
22753 +       read_lock(&gr_inode_lock);
22754 +       curr = lookup_acl_subj_label(filp->f_path.dentry->d_inode->i_ino,
22755 +                                    filp->f_path.dentry->d_inode->i_sb->s_dev,
22756 +                                    current->role);
22757 +       read_unlock(&gr_inode_lock);
22758 +
22759 +       if (!curr || !(curr->resmask & (1 << GR_CRASH_RES)) ||
22760 +           (!curr->crashes && !curr->expires))
22761 +               return 0;
22762 +
22763 +       if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
22764 +           time_after(curr->expires, get_seconds()))
22765 +               return 1;
22766 +       else if (time_before_eq(curr->expires, get_seconds())) {
22767 +               curr->crashes = 0;
22768 +               curr->expires = 0;
22769 +       }
22770 +
22771 +       return 0;
22772 +}
22773 +
22774 +void
22775 +gr_handle_alertkill(struct task_struct *task)
22776 +{
22777 +       struct acl_subject_label *curracl;
22778 +       __u32 curr_ip;
22779 +       struct task_struct *p, *p2;
22780 +
22781 +       if (unlikely(!gr_acl_is_enabled()))
22782 +               return;
22783 +
22784 +       curracl = task->acl;
22785 +       curr_ip = task->signal->curr_ip;
22786 +
22787 +       if ((curracl->mode & GR_KILLIPPROC) && curr_ip) {
22788 +               read_lock(&tasklist_lock);
22789 +               do_each_thread(p2, p) {
22790 +                       if (p->signal->curr_ip == curr_ip)
22791 +                               gr_fake_force_sig(SIGKILL, p);
22792 +               } while_each_thread(p2, p);
22793 +               read_unlock(&tasklist_lock);
22794 +       } else if (curracl->mode & GR_KILLPROC)
22795 +               gr_fake_force_sig(SIGKILL, task);
22796 +
22797 +       return;
22798 +}
22799 diff -urNp linux-2.6.27.10/grsecurity/gracl_shm.c linux-2.6.27.10/grsecurity/gracl_shm.c
22800 --- linux-2.6.27.10/grsecurity/gracl_shm.c      1969-12-31 19:00:00.000000000 -0500
22801 +++ linux-2.6.27.10/grsecurity/gracl_shm.c      2008-11-18 03:38:45.000000000 -0500
22802 @@ -0,0 +1,33 @@
22803 +#include <linux/kernel.h>
22804 +#include <linux/mm.h>
22805 +#include <linux/sched.h>
22806 +#include <linux/file.h>
22807 +#include <linux/ipc.h>
22808 +#include <linux/gracl.h>
22809 +#include <linux/grsecurity.h>
22810 +#include <linux/grinternal.h>
22811 +
22812 +int
22813 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
22814 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
22815 +{
22816 +       struct task_struct *task;
22817 +
22818 +       if (!gr_acl_is_enabled())
22819 +               return 1;
22820 +
22821 +       task = find_task_by_vpid(shm_cprid);
22822 +
22823 +       if (unlikely(!task))
22824 +               task = find_task_by_vpid(shm_lapid);
22825 +
22826 +       if (unlikely(task && (time_before_eq((unsigned long)task->start_time.tv_sec, (unsigned long)shm_createtime) ||
22827 +                             (task->pid == shm_lapid)) &&
22828 +                    (task->acl->mode & GR_PROTSHM) &&
22829 +                    (task->acl != current->acl))) {
22830 +               gr_log_int3(GR_DONT_AUDIT, GR_SHMAT_ACL_MSG, cuid, shm_cprid, shmid);
22831 +               return 0;
22832 +       }
22833 +
22834 +       return 1;
22835 +}
22836 diff -urNp linux-2.6.27.10/grsecurity/grsec_chdir.c linux-2.6.27.10/grsecurity/grsec_chdir.c
22837 --- linux-2.6.27.10/grsecurity/grsec_chdir.c    1969-12-31 19:00:00.000000000 -0500
22838 +++ linux-2.6.27.10/grsecurity/grsec_chdir.c    2008-11-18 03:38:45.000000000 -0500
22839 @@ -0,0 +1,19 @@
22840 +#include <linux/kernel.h>
22841 +#include <linux/sched.h>
22842 +#include <linux/fs.h>
22843 +#include <linux/file.h>
22844 +#include <linux/grsecurity.h>
22845 +#include <linux/grinternal.h>
22846 +
22847 +void
22848 +gr_log_chdir(const struct dentry *dentry, const struct vfsmount *mnt)
22849 +{
22850 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
22851 +       if ((grsec_enable_chdir && grsec_enable_group &&
22852 +            in_group_p(grsec_audit_gid)) || (grsec_enable_chdir &&
22853 +                                             !grsec_enable_group)) {
22854 +               gr_log_fs_generic(GR_DO_AUDIT, GR_CHDIR_AUDIT_MSG, dentry, mnt);
22855 +       }
22856 +#endif
22857 +       return;
22858 +}
22859 diff -urNp linux-2.6.27.10/grsecurity/grsec_chroot.c linux-2.6.27.10/grsecurity/grsec_chroot.c
22860 --- linux-2.6.27.10/grsecurity/grsec_chroot.c   1969-12-31 19:00:00.000000000 -0500
22861 +++ linux-2.6.27.10/grsecurity/grsec_chroot.c   2008-11-18 03:38:45.000000000 -0500
22862 @@ -0,0 +1,336 @@
22863 +#include <linux/kernel.h>
22864 +#include <linux/module.h>
22865 +#include <linux/sched.h>
22866 +#include <linux/file.h>
22867 +#include <linux/fs.h>
22868 +#include <linux/mount.h>
22869 +#include <linux/types.h>
22870 +#include <linux/pid_namespace.h>
22871 +#include <linux/grsecurity.h>
22872 +#include <linux/grinternal.h>
22873 +
22874 +int
22875 +gr_handle_chroot_unix(const pid_t pid)
22876 +{
22877 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
22878 +       struct pid *spid = NULL;
22879 +
22880 +       if (unlikely(!grsec_enable_chroot_unix))
22881 +               return 1;
22882 +
22883 +       if (likely(!proc_is_chrooted(current)))
22884 +               return 1;
22885 +
22886 +       read_lock(&tasklist_lock);
22887 +
22888 +       spid = find_vpid(pid);
22889 +       if (spid) {
22890 +               struct task_struct *p;
22891 +               p = pid_task(spid, PIDTYPE_PID);
22892 +               task_lock(p);
22893 +               if (unlikely(!have_same_root(current, p))) {
22894 +                       task_unlock(p);
22895 +                       read_unlock(&tasklist_lock);
22896 +                       gr_log_noargs(GR_DONT_AUDIT, GR_UNIX_CHROOT_MSG);
22897 +                       return 0;
22898 +               }
22899 +               task_unlock(p);
22900 +       }
22901 +       read_unlock(&tasklist_lock);
22902 +#endif
22903 +       return 1;
22904 +}
22905 +
22906 +int
22907 +gr_handle_chroot_nice(void)
22908 +{
22909 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22910 +       if (grsec_enable_chroot_nice && proc_is_chrooted(current)) {
22911 +               gr_log_noargs(GR_DONT_AUDIT, GR_NICE_CHROOT_MSG);
22912 +               return -EPERM;
22913 +       }
22914 +#endif
22915 +       return 0;
22916 +}
22917 +
22918 +int
22919 +gr_handle_chroot_setpriority(struct task_struct *p, const int niceval)
22920 +{
22921 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
22922 +       if (grsec_enable_chroot_nice && (niceval < task_nice(p))
22923 +                       && proc_is_chrooted(current)) {
22924 +               gr_log_str_int(GR_DONT_AUDIT, GR_PRIORITY_CHROOT_MSG, p->comm, p->pid);
22925 +               return -EACCES;
22926 +       }
22927 +#endif
22928 +       return 0;
22929 +}
22930 +
22931 +int
22932 +gr_handle_chroot_rawio(const struct inode *inode)
22933 +{
22934 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
22935 +       if (grsec_enable_chroot_caps && proc_is_chrooted(current) && 
22936 +           inode && S_ISBLK(inode->i_mode) && !capable(CAP_SYS_RAWIO))
22937 +               return 1;
22938 +#endif
22939 +       return 0;
22940 +}
22941 +
22942 +int
22943 +gr_pid_is_chrooted(struct task_struct *p)
22944 +{
22945 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
22946 +       if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || p == NULL)
22947 +               return 0;
22948 +
22949 +       task_lock(p);
22950 +       if ((p->exit_state & (EXIT_ZOMBIE | EXIT_DEAD)) ||
22951 +           !have_same_root(current, p)) {
22952 +               task_unlock(p);
22953 +               return 1;
22954 +       }
22955 +       task_unlock(p);
22956 +#endif
22957 +       return 0;
22958 +}
22959 +
22960 +EXPORT_SYMBOL(gr_pid_is_chrooted);
22961 +
22962 +#if defined(CONFIG_GRKERNSEC_CHROOT_DOUBLE) || defined(CONFIG_GRKERNSEC_CHROOT_FCHDIR)
22963 +int gr_is_outside_chroot(const struct dentry *u_dentry, const struct vfsmount *u_mnt)
22964 +{
22965 +       struct dentry *dentry = (struct dentry *)u_dentry;
22966 +       struct vfsmount *mnt = (struct vfsmount *)u_mnt;
22967 +       struct dentry *realroot;
22968 +       struct vfsmount *realrootmnt;
22969 +       struct dentry *currentroot;
22970 +       struct vfsmount *currentmnt;
22971 +       struct task_struct *reaper = current->nsproxy->pid_ns->child_reaper;
22972 +       int ret = 1;
22973 +
22974 +       read_lock(&reaper->fs->lock);
22975 +       realrootmnt = mntget(reaper->fs->root.mnt);
22976 +       realroot = dget(reaper->fs->root.dentry);
22977 +       read_unlock(&reaper->fs->lock);
22978 +
22979 +       read_lock(&current->fs->lock);
22980 +       currentmnt = mntget(current->fs->root.mnt);
22981 +       currentroot = dget(current->fs->root.dentry);
22982 +       read_unlock(&current->fs->lock);
22983 +
22984 +       spin_lock(&dcache_lock);
22985 +       for (;;) {
22986 +               if (unlikely((dentry == realroot && mnt == realrootmnt)
22987 +                    || (dentry == currentroot && mnt == currentmnt)))
22988 +                       break;
22989 +               if (unlikely(dentry == mnt->mnt_root || IS_ROOT(dentry))) {
22990 +                       if (mnt->mnt_parent == mnt)
22991 +                               break;
22992 +                       dentry = mnt->mnt_mountpoint;
22993 +                       mnt = mnt->mnt_parent;
22994 +                       continue;
22995 +               }
22996 +               dentry = dentry->d_parent;
22997 +       }
22998 +       spin_unlock(&dcache_lock);
22999 +
23000 +       dput(currentroot);
23001 +       mntput(currentmnt);
23002 +
23003 +       /* access is outside of chroot */
23004 +       if (dentry == realroot && mnt == realrootmnt)
23005 +               ret = 0;
23006 +
23007 +       dput(realroot);
23008 +       mntput(realrootmnt);
23009 +       return ret;
23010 +}
23011 +#endif
23012 +
23013 +int
23014 +gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt)
23015 +{
23016 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23017 +       if (!grsec_enable_chroot_fchdir)
23018 +               return 1;
23019 +
23020 +       if (!proc_is_chrooted(current))
23021 +               return 1;
23022 +       else if (!gr_is_outside_chroot(u_dentry, u_mnt)) {
23023 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_FCHDIR_MSG, u_dentry, u_mnt);
23024 +               return 0;
23025 +       }
23026 +#endif
23027 +       return 1;
23028 +}
23029 +
23030 +int
23031 +gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23032 +               const time_t shm_createtime)
23033 +{
23034 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23035 +       struct pid *pid = NULL;
23036 +       time_t starttime;
23037 +
23038 +       if (unlikely(!grsec_enable_chroot_shmat))
23039 +               return 1;
23040 +
23041 +       if (likely(!proc_is_chrooted(current)))
23042 +               return 1;
23043 +
23044 +       read_lock(&tasklist_lock);
23045 +
23046 +       pid = find_vpid(shm_cprid);
23047 +       if (pid) {
23048 +               struct task_struct *p;
23049 +               p = pid_task(pid, PIDTYPE_PID);
23050 +               task_lock(p);
23051 +               starttime = p->start_time.tv_sec;
23052 +               if (unlikely(!have_same_root(current, p) &&
23053 +                            time_before_eq((unsigned long)starttime, (unsigned long)shm_createtime))) {
23054 +                       task_unlock(p);
23055 +                       read_unlock(&tasklist_lock);
23056 +                       gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23057 +                       return 0;
23058 +               }
23059 +               task_unlock(p);
23060 +       } else {
23061 +               pid = find_vpid(shm_lapid);
23062 +               if (pid) {
23063 +                       struct task_struct *p;
23064 +                       p = pid_task(pid, PIDTYPE_PID);
23065 +                       task_lock(p);
23066 +                       if (unlikely(!have_same_root(current, p))) {
23067 +                               task_unlock(p);
23068 +                               read_unlock(&tasklist_lock);
23069 +                               gr_log_noargs(GR_DONT_AUDIT, GR_SHMAT_CHROOT_MSG);
23070 +                               return 0;
23071 +                       }
23072 +                       task_unlock(p);
23073 +               }
23074 +       }
23075 +
23076 +       read_unlock(&tasklist_lock);
23077 +#endif
23078 +       return 1;
23079 +}
23080 +
23081 +void
23082 +gr_log_chroot_exec(const struct dentry *dentry, const struct vfsmount *mnt)
23083 +{
23084 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23085 +       if (grsec_enable_chroot_execlog && proc_is_chrooted(current))
23086 +               gr_log_fs_generic(GR_DO_AUDIT, GR_EXEC_CHROOT_MSG, dentry, mnt);
23087 +#endif
23088 +       return;
23089 +}
23090 +
23091 +int
23092 +gr_handle_chroot_mknod(const struct dentry *dentry,
23093 +                      const struct vfsmount *mnt, const int mode)
23094 +{
23095 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23096 +       if (grsec_enable_chroot_mknod && !S_ISFIFO(mode) && !S_ISREG(mode) && 
23097 +           proc_is_chrooted(current)) {
23098 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_MKNOD_CHROOT_MSG, dentry, mnt);
23099 +               return -EPERM;
23100 +       }
23101 +#endif
23102 +       return 0;
23103 +}
23104 +
23105 +int
23106 +gr_handle_chroot_mount(const struct dentry *dentry,
23107 +                      const struct vfsmount *mnt, const char *dev_name)
23108 +{
23109 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23110 +       if (grsec_enable_chroot_mount && proc_is_chrooted(current)) {
23111 +               gr_log_str_fs(GR_DONT_AUDIT, GR_MOUNT_CHROOT_MSG, dev_name, dentry, mnt);
23112 +               return -EPERM;
23113 +       }
23114 +#endif
23115 +       return 0;
23116 +}
23117 +
23118 +int
23119 +gr_handle_chroot_pivot(void)
23120 +{
23121 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23122 +       if (grsec_enable_chroot_pivot && proc_is_chrooted(current)) {
23123 +               gr_log_noargs(GR_DONT_AUDIT, GR_PIVOT_CHROOT_MSG);
23124 +               return -EPERM;
23125 +       }
23126 +#endif
23127 +       return 0;
23128 +}
23129 +
23130 +int
23131 +gr_handle_chroot_chroot(const struct dentry *dentry, const struct vfsmount *mnt)
23132 +{
23133 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23134 +       if (grsec_enable_chroot_double && proc_is_chrooted(current) &&
23135 +           !gr_is_outside_chroot(dentry, mnt)) {
23136 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_CHROOT_MSG, dentry, mnt);
23137 +               return -EPERM;
23138 +       }
23139 +#endif
23140 +       return 0;
23141 +}
23142 +
23143 +void
23144 +gr_handle_chroot_caps(struct task_struct *task)
23145 +{
23146 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23147 +       if (grsec_enable_chroot_caps && proc_is_chrooted(task)) {
23148 +               kernel_cap_t chroot_caps = GR_CHROOT_CAPS;
23149 +               task->cap_permitted =
23150 +                   cap_drop(task->cap_permitted, chroot_caps);
23151 +               task->cap_inheritable =
23152 +                   cap_drop(task->cap_inheritable, chroot_caps);
23153 +               task->cap_effective =
23154 +                   cap_drop(task->cap_effective, chroot_caps);
23155 +       }
23156 +#endif
23157 +       return;
23158 +}
23159 +
23160 +int
23161 +gr_handle_chroot_sysctl(const int op)
23162 +{
23163 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23164 +       if (grsec_enable_chroot_sysctl && proc_is_chrooted(current)
23165 +           && (op & MAY_WRITE))
23166 +               return -EACCES;
23167 +#endif
23168 +       return 0;
23169 +}
23170 +
23171 +void
23172 +gr_handle_chroot_chdir(struct path *path)
23173 +{
23174 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23175 +       if (grsec_enable_chroot_chdir)
23176 +               set_fs_pwd(current->fs, path);
23177 +#endif
23178 +       return;
23179 +}
23180 +
23181 +int
23182 +gr_handle_chroot_chmod(const struct dentry *dentry,
23183 +                      const struct vfsmount *mnt, const int mode)
23184 +{
23185 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23186 +       if (grsec_enable_chroot_chmod &&
23187 +           ((mode & S_ISUID) || ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) &&
23188 +           proc_is_chrooted(current)) {
23189 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_CHMOD_CHROOT_MSG, dentry, mnt);
23190 +               return -EPERM;
23191 +       }
23192 +#endif
23193 +       return 0;
23194 +}
23195 +
23196 +#ifdef CONFIG_SECURITY
23197 +EXPORT_SYMBOL(gr_handle_chroot_caps);
23198 +#endif
23199 diff -urNp linux-2.6.27.10/grsecurity/grsec_disabled.c linux-2.6.27.10/grsecurity/grsec_disabled.c
23200 --- linux-2.6.27.10/grsecurity/grsec_disabled.c 1969-12-31 19:00:00.000000000 -0500
23201 +++ linux-2.6.27.10/grsecurity/grsec_disabled.c 2008-11-18 03:38:45.000000000 -0500
23202 @@ -0,0 +1,418 @@
23203 +#include <linux/kernel.h>
23204 +#include <linux/module.h>
23205 +#include <linux/sched.h>
23206 +#include <linux/file.h>
23207 +#include <linux/fs.h>
23208 +#include <linux/kdev_t.h>
23209 +#include <linux/net.h>
23210 +#include <linux/in.h>
23211 +#include <linux/ip.h>
23212 +#include <linux/skbuff.h>
23213 +#include <linux/sysctl.h>
23214 +
23215 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
23216 +void
23217 +pax_set_initial_flags(struct linux_binprm *bprm)
23218 +{
23219 +       return;
23220 +}
23221 +#endif
23222 +
23223 +#ifdef CONFIG_SYSCTL
23224 +__u32
23225 +gr_handle_sysctl(const struct ctl_table * table, const int op)
23226 +{
23227 +       return 0;
23228 +}
23229 +#endif
23230 +
23231 +int
23232 +gr_acl_is_enabled(void)
23233 +{
23234 +       return 0;
23235 +}
23236 +
23237 +int
23238 +gr_handle_rawio(const struct inode *inode)
23239 +{
23240 +       return 0;
23241 +}
23242 +
23243 +void
23244 +gr_acl_handle_psacct(struct task_struct *task, const long code)
23245 +{
23246 +       return;
23247 +}
23248 +
23249 +int
23250 +gr_handle_ptrace(struct task_struct *task, const long request)
23251 +{
23252 +       return 0;
23253 +}
23254 +
23255 +int
23256 +gr_handle_proc_ptrace(struct task_struct *task)
23257 +{
23258 +       return 0;
23259 +}
23260 +
23261 +void
23262 +gr_learn_resource(const struct task_struct *task,
23263 +                 const int res, const unsigned long wanted, const int gt)
23264 +{
23265 +       return;
23266 +}
23267 +
23268 +int
23269 +gr_set_acls(const int type)
23270 +{
23271 +       return 0;
23272 +}
23273 +
23274 +int
23275 +gr_check_hidden_task(const struct task_struct *tsk)
23276 +{
23277 +       return 0;
23278 +}
23279 +
23280 +int
23281 +gr_check_protected_task(const struct task_struct *task)
23282 +{
23283 +       return 0;
23284 +}
23285 +
23286 +void
23287 +gr_copy_label(struct task_struct *tsk)
23288 +{
23289 +       return;
23290 +}
23291 +
23292 +void
23293 +gr_set_pax_flags(struct task_struct *task)
23294 +{
23295 +       return;
23296 +}
23297 +
23298 +int
23299 +gr_set_proc_label(const struct dentry *dentry, const struct vfsmount *mnt)
23300 +{
23301 +       return 0;
23302 +}
23303 +
23304 +void
23305 +gr_handle_delete(const ino_t ino, const dev_t dev)
23306 +{
23307 +       return;
23308 +}
23309 +
23310 +void
23311 +gr_handle_create(const struct dentry *dentry, const struct vfsmount *mnt)
23312 +{
23313 +       return;
23314 +}
23315 +
23316 +void
23317 +gr_handle_crash(struct task_struct *task, const int sig)
23318 +{
23319 +       return;
23320 +}
23321 +
23322 +int
23323 +gr_check_crash_exec(const struct file *filp)
23324 +{
23325 +       return 0;
23326 +}
23327 +
23328 +int
23329 +gr_check_crash_uid(const uid_t uid)
23330 +{
23331 +       return 0;
23332 +}
23333 +
23334 +void
23335 +gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
23336 +                struct dentry *old_dentry,
23337 +                struct dentry *new_dentry,
23338 +                struct vfsmount *mnt, const __u8 replace)
23339 +{
23340 +       return;
23341 +}
23342 +
23343 +int
23344 +gr_search_socket(const int family, const int type, const int protocol)
23345 +{
23346 +       return 1;
23347 +}
23348 +
23349 +int
23350 +gr_search_connectbind(const int mode, const struct socket *sock,
23351 +                     const struct sockaddr_in *addr)
23352 +{
23353 +       return 1;
23354 +}
23355 +
23356 +int
23357 +gr_task_is_capable(struct task_struct *task, const int cap)
23358 +{
23359 +       return 1;
23360 +}
23361 +
23362 +int
23363 +gr_is_capable_nolog(const int cap)
23364 +{
23365 +       return 1;
23366 +}
23367 +
23368 +void
23369 +gr_handle_alertkill(struct task_struct *task)
23370 +{
23371 +       return;
23372 +}
23373 +
23374 +__u32
23375 +gr_acl_handle_execve(const struct dentry * dentry, const struct vfsmount * mnt)
23376 +{
23377 +       return 1;
23378 +}
23379 +
23380 +__u32
23381 +gr_acl_handle_hidden_file(const struct dentry * dentry,
23382 +                         const struct vfsmount * mnt)
23383 +{
23384 +       return 1;
23385 +}
23386 +
23387 +__u32
23388 +gr_acl_handle_open(const struct dentry * dentry, const struct vfsmount * mnt,
23389 +                  const int fmode)
23390 +{
23391 +       return 1;
23392 +}
23393 +
23394 +__u32
23395 +gr_acl_handle_rmdir(const struct dentry * dentry, const struct vfsmount * mnt)
23396 +{
23397 +       return 1;
23398 +}
23399 +
23400 +__u32
23401 +gr_acl_handle_unlink(const struct dentry * dentry, const struct vfsmount * mnt)
23402 +{
23403 +       return 1;
23404 +}
23405 +
23406 +int
23407 +gr_acl_handle_mmap(const struct file *file, const unsigned long prot,
23408 +                  unsigned int *vm_flags)
23409 +{
23410 +       return 1;
23411 +}
23412 +
23413 +__u32
23414 +gr_acl_handle_truncate(const struct dentry * dentry,
23415 +                      const struct vfsmount * mnt)
23416 +{
23417 +       return 1;
23418 +}
23419 +
23420 +__u32
23421 +gr_acl_handle_utime(const struct dentry * dentry, const struct vfsmount * mnt)
23422 +{
23423 +       return 1;
23424 +}
23425 +
23426 +__u32
23427 +gr_acl_handle_access(const struct dentry * dentry,
23428 +                    const struct vfsmount * mnt, const int fmode)
23429 +{
23430 +       return 1;
23431 +}
23432 +
23433 +__u32
23434 +gr_acl_handle_fchmod(const struct dentry * dentry, const struct vfsmount * mnt,
23435 +                    mode_t mode)
23436 +{
23437 +       return 1;
23438 +}
23439 +
23440 +__u32
23441 +gr_acl_handle_chmod(const struct dentry * dentry, const struct vfsmount * mnt,
23442 +                   mode_t mode)
23443 +{
23444 +       return 1;
23445 +}
23446 +
23447 +__u32
23448 +gr_acl_handle_chown(const struct dentry * dentry, const struct vfsmount * mnt)
23449 +{
23450 +       return 1;
23451 +}
23452 +
23453 +void
23454 +grsecurity_init(void)
23455 +{
23456 +       return;
23457 +}
23458 +
23459 +__u32
23460 +gr_acl_handle_mknod(const struct dentry * new_dentry,
23461 +                   const struct dentry * parent_dentry,
23462 +                   const struct vfsmount * parent_mnt,
23463 +                   const int mode)
23464 +{
23465 +       return 1;
23466 +}
23467 +
23468 +__u32
23469 +gr_acl_handle_mkdir(const struct dentry * new_dentry,
23470 +                   const struct dentry * parent_dentry,
23471 +                   const struct vfsmount * parent_mnt)
23472 +{
23473 +       return 1;
23474 +}
23475 +
23476 +__u32
23477 +gr_acl_handle_symlink(const struct dentry * new_dentry,
23478 +                     const struct dentry * parent_dentry,
23479 +                     const struct vfsmount * parent_mnt, const char *from)
23480 +{
23481 +       return 1;
23482 +}
23483 +
23484 +__u32
23485 +gr_acl_handle_link(const struct dentry * new_dentry,
23486 +                  const struct dentry * parent_dentry,
23487 +                  const struct vfsmount * parent_mnt,
23488 +                  const struct dentry * old_dentry,
23489 +                  const struct vfsmount * old_mnt, const char *to)
23490 +{
23491 +       return 1;
23492 +}
23493 +
23494 +int
23495 +gr_acl_handle_rename(const struct dentry *new_dentry,
23496 +                    const struct dentry *parent_dentry,
23497 +                    const struct vfsmount *parent_mnt,
23498 +                    const struct dentry *old_dentry,
23499 +                    const struct inode *old_parent_inode,
23500 +                    const struct vfsmount *old_mnt, const char *newname)
23501 +{
23502 +       return 0;
23503 +}
23504 +
23505 +int
23506 +gr_acl_handle_filldir(const struct file *file, const char *name,
23507 +                     const int namelen, const ino_t ino)
23508 +{
23509 +       return 1;
23510 +}
23511 +
23512 +int
23513 +gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
23514 +               const time_t shm_createtime, const uid_t cuid, const int shmid)
23515 +{
23516 +       return 1;
23517 +}
23518 +
23519 +int
23520 +gr_search_bind(const struct socket *sock, const struct sockaddr_in *addr)
23521 +{
23522 +       return 1;
23523 +}
23524 +
23525 +int
23526 +gr_search_accept(const struct socket *sock)
23527 +{
23528 +       return 1;
23529 +}
23530 +
23531 +int
23532 +gr_search_listen(const struct socket *sock)
23533 +{
23534 +       return 1;
23535 +}
23536 +
23537 +int
23538 +gr_search_connect(const struct socket *sock, const struct sockaddr_in *addr)
23539 +{
23540 +       return 1;
23541 +}
23542 +
23543 +__u32
23544 +gr_acl_handle_unix(const struct dentry * dentry, const struct vfsmount * mnt)
23545 +{
23546 +       return 1;
23547 +}
23548 +
23549 +__u32
23550 +gr_acl_handle_creat(const struct dentry * dentry,
23551 +                   const struct dentry * p_dentry,
23552 +                   const struct vfsmount * p_mnt, const int fmode,
23553 +                   const int imode)
23554 +{
23555 +       return 1;
23556 +}
23557 +
23558 +void
23559 +gr_acl_handle_exit(void)
23560 +{
23561 +       return;
23562 +}
23563 +
23564 +int
23565 +gr_acl_handle_mprotect(const struct file *file, const unsigned long prot)
23566 +{
23567 +       return 1;
23568 +}
23569 +
23570 +void
23571 +gr_set_role_label(const uid_t uid, const gid_t gid)
23572 +{
23573 +       return;
23574 +}
23575 +
23576 +int
23577 +gr_acl_handle_procpidmem(const struct task_struct *task)
23578 +{
23579 +       return 0;
23580 +}
23581 +
23582 +int
23583 +gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb)
23584 +{
23585 +       return 1;
23586 +}
23587 +
23588 +int
23589 +gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr)
23590 +{
23591 +       return 1;
23592 +}
23593 +
23594 +void
23595 +gr_set_kernel_label(struct task_struct *task)
23596 +{
23597 +       return;
23598 +}
23599 +
23600 +int
23601 +gr_check_user_change(int real, int effective, int fs)
23602 +{
23603 +       return 0;
23604 +}
23605 +
23606 +int
23607 +gr_check_group_change(int real, int effective, int fs)
23608 +{
23609 +       return 0;
23610 +}
23611 +
23612 +
23613 +EXPORT_SYMBOL(gr_task_is_capable);
23614 +EXPORT_SYMBOL(gr_is_capable_nolog);
23615 +EXPORT_SYMBOL(gr_learn_resource);
23616 +EXPORT_SYMBOL(gr_set_kernel_label);
23617 +#ifdef CONFIG_SECURITY
23618 +EXPORT_SYMBOL(gr_check_user_change);
23619 +EXPORT_SYMBOL(gr_check_group_change);
23620 +#endif
23621 diff -urNp linux-2.6.27.10/grsecurity/grsec_exec.c linux-2.6.27.10/grsecurity/grsec_exec.c
23622 --- linux-2.6.27.10/grsecurity/grsec_exec.c     1969-12-31 19:00:00.000000000 -0500
23623 +++ linux-2.6.27.10/grsecurity/grsec_exec.c     2008-11-18 03:38:45.000000000 -0500
23624 @@ -0,0 +1,88 @@
23625 +#include <linux/kernel.h>
23626 +#include <linux/sched.h>
23627 +#include <linux/file.h>
23628 +#include <linux/binfmts.h>
23629 +#include <linux/smp_lock.h>
23630 +#include <linux/fs.h>
23631 +#include <linux/types.h>
23632 +#include <linux/grdefs.h>
23633 +#include <linux/grinternal.h>
23634 +#include <linux/capability.h>
23635 +
23636 +#include <asm/uaccess.h>
23637 +
23638 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23639 +static char gr_exec_arg_buf[132];
23640 +static DECLARE_MUTEX(gr_exec_arg_sem);
23641 +#endif
23642 +
23643 +int
23644 +gr_handle_nproc(void)
23645 +{
23646 +#ifdef CONFIG_GRKERNSEC_EXECVE
23647 +       if (grsec_enable_execve && current->user &&
23648 +           (atomic_read(&current->user->processes) >
23649 +            current->signal->rlim[RLIMIT_NPROC].rlim_cur) &&
23650 +           !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) {
23651 +               gr_log_noargs(GR_DONT_AUDIT, GR_NPROC_MSG);
23652 +               return -EAGAIN;
23653 +       }
23654 +#endif
23655 +       return 0;
23656 +}
23657 +
23658 +void
23659 +gr_handle_exec_args(struct linux_binprm *bprm, const char __user *__user *argv)
23660 +{
23661 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23662 +       char *grarg = gr_exec_arg_buf;
23663 +       unsigned int i, x, execlen = 0;
23664 +       char c;
23665 +
23666 +       if (!((grsec_enable_execlog && grsec_enable_group &&
23667 +              in_group_p(grsec_audit_gid))
23668 +             || (grsec_enable_execlog && !grsec_enable_group)))
23669 +               return;
23670 +
23671 +       down(&gr_exec_arg_sem);
23672 +       memset(grarg, 0, sizeof(gr_exec_arg_buf));
23673 +
23674 +       if (unlikely(argv == NULL))
23675 +               goto log;
23676 +
23677 +       for (i = 0; i < bprm->argc && execlen < 128; i++) {
23678 +               const char __user *p;
23679 +               unsigned int len;
23680 +
23681 +               if (copy_from_user(&p, argv + i, sizeof(p)))
23682 +                       goto log;
23683 +               if (!p)
23684 +                       goto log;
23685 +               len = strnlen_user(p, 128 - execlen);
23686 +               if (len > 128 - execlen)
23687 +                       len = 128 - execlen;
23688 +               else if (len > 0)
23689 +                       len--;
23690 +               if (copy_from_user(grarg + execlen, p, len))
23691 +                       goto log;
23692 +
23693 +               /* rewrite unprintable characters */
23694 +               for (x = 0; x < len; x++) {
23695 +                       c = *(grarg + execlen + x);
23696 +                       if (c < 32 || c > 126)
23697 +                               *(grarg + execlen + x) = ' ';
23698 +               }
23699 +
23700 +               execlen += len;
23701 +               *(grarg + execlen) = ' ';
23702 +               *(grarg + execlen + 1) = '\0';
23703 +               execlen++;
23704 +       }
23705 +
23706 +      log:
23707 +       gr_log_fs_str(GR_DO_AUDIT, GR_EXEC_AUDIT_MSG, bprm->file->f_path.dentry,
23708 +                       bprm->file->f_path.mnt, grarg);
23709 +       up(&gr_exec_arg_sem);
23710 +#endif
23711 +       return;
23712 +}
23713 diff -urNp linux-2.6.27.10/grsecurity/grsec_fifo.c linux-2.6.27.10/grsecurity/grsec_fifo.c
23714 --- linux-2.6.27.10/grsecurity/grsec_fifo.c     1969-12-31 19:00:00.000000000 -0500
23715 +++ linux-2.6.27.10/grsecurity/grsec_fifo.c     2008-11-18 03:38:45.000000000 -0500
23716 @@ -0,0 +1,22 @@
23717 +#include <linux/kernel.h>
23718 +#include <linux/sched.h>
23719 +#include <linux/fs.h>
23720 +#include <linux/file.h>
23721 +#include <linux/grinternal.h>
23722 +
23723 +int
23724 +gr_handle_fifo(const struct dentry *dentry, const struct vfsmount *mnt,
23725 +              const struct dentry *dir, const int flag, const int acc_mode)
23726 +{
23727 +#ifdef CONFIG_GRKERNSEC_FIFO
23728 +       if (grsec_enable_fifo && S_ISFIFO(dentry->d_inode->i_mode) &&
23729 +           !(flag & O_EXCL) && (dir->d_inode->i_mode & S_ISVTX) &&
23730 +           (dentry->d_inode->i_uid != dir->d_inode->i_uid) &&
23731 +           (current->fsuid != dentry->d_inode->i_uid)) {
23732 +               if (!generic_permission(dentry->d_inode, acc_mode, NULL))
23733 +                       gr_log_fs_int2(GR_DONT_AUDIT, GR_FIFO_MSG, dentry, mnt, dentry->d_inode->i_uid, dentry->d_inode->i_gid);
23734 +               return -EACCES;
23735 +       }
23736 +#endif
23737 +       return 0;
23738 +}
23739 diff -urNp linux-2.6.27.10/grsecurity/grsec_fork.c linux-2.6.27.10/grsecurity/grsec_fork.c
23740 --- linux-2.6.27.10/grsecurity/grsec_fork.c     1969-12-31 19:00:00.000000000 -0500
23741 +++ linux-2.6.27.10/grsecurity/grsec_fork.c     2008-11-18 03:38:45.000000000 -0500
23742 @@ -0,0 +1,15 @@
23743 +#include <linux/kernel.h>
23744 +#include <linux/sched.h>
23745 +#include <linux/grsecurity.h>
23746 +#include <linux/grinternal.h>
23747 +#include <linux/errno.h>
23748 +
23749 +void
23750 +gr_log_forkfail(const int retval)
23751 +{
23752 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23753 +       if (grsec_enable_forkfail && retval != -ERESTARTNOINTR)
23754 +               gr_log_int(GR_DONT_AUDIT, GR_FAILFORK_MSG, retval);
23755 +#endif
23756 +       return;
23757 +}
23758 diff -urNp linux-2.6.27.10/grsecurity/grsec_init.c linux-2.6.27.10/grsecurity/grsec_init.c
23759 --- linux-2.6.27.10/grsecurity/grsec_init.c     1969-12-31 19:00:00.000000000 -0500
23760 +++ linux-2.6.27.10/grsecurity/grsec_init.c     2008-11-18 03:38:45.000000000 -0500
23761 @@ -0,0 +1,230 @@
23762 +#include <linux/kernel.h>
23763 +#include <linux/sched.h>
23764 +#include <linux/mm.h>
23765 +#include <linux/smp_lock.h>
23766 +#include <linux/gracl.h>
23767 +#include <linux/slab.h>
23768 +#include <linux/vmalloc.h>
23769 +#include <linux/percpu.h>
23770 +
23771 +int grsec_enable_link;
23772 +int grsec_enable_dmesg;
23773 +int grsec_enable_fifo;
23774 +int grsec_enable_execve;
23775 +int grsec_enable_execlog;
23776 +int grsec_enable_signal;
23777 +int grsec_enable_forkfail;
23778 +int grsec_enable_time;
23779 +int grsec_enable_audit_textrel;
23780 +int grsec_enable_group;
23781 +int grsec_audit_gid;
23782 +int grsec_enable_chdir;
23783 +int grsec_enable_audit_ipc;
23784 +int grsec_enable_mount;
23785 +int grsec_enable_chroot_findtask;
23786 +int grsec_enable_chroot_mount;
23787 +int grsec_enable_chroot_shmat;
23788 +int grsec_enable_chroot_fchdir;
23789 +int grsec_enable_chroot_double;
23790 +int grsec_enable_chroot_pivot;
23791 +int grsec_enable_chroot_chdir;
23792 +int grsec_enable_chroot_chmod;
23793 +int grsec_enable_chroot_mknod;
23794 +int grsec_enable_chroot_nice;
23795 +int grsec_enable_chroot_execlog;
23796 +int grsec_enable_chroot_caps;
23797 +int grsec_enable_chroot_sysctl;
23798 +int grsec_enable_chroot_unix;
23799 +int grsec_enable_tpe;
23800 +int grsec_tpe_gid;
23801 +int grsec_enable_tpe_all;
23802 +int grsec_enable_socket_all;
23803 +int grsec_socket_all_gid;
23804 +int grsec_enable_socket_client;
23805 +int grsec_socket_client_gid;
23806 +int grsec_enable_socket_server;
23807 +int grsec_socket_server_gid;
23808 +int grsec_resource_logging;
23809 +int grsec_lock;
23810 +
23811 +DEFINE_SPINLOCK(grsec_alert_lock);
23812 +unsigned long grsec_alert_wtime = 0;
23813 +unsigned long grsec_alert_fyet = 0;
23814 +
23815 +DEFINE_SPINLOCK(grsec_audit_lock);
23816 +
23817 +DEFINE_RWLOCK(grsec_exec_file_lock);
23818 +
23819 +char *gr_shared_page[4];
23820 +
23821 +char *gr_alert_log_fmt;
23822 +char *gr_audit_log_fmt;
23823 +char *gr_alert_log_buf;
23824 +char *gr_audit_log_buf;
23825 +
23826 +extern struct gr_arg *gr_usermode;
23827 +extern unsigned char *gr_system_salt;
23828 +extern unsigned char *gr_system_sum;
23829 +
23830 +void
23831 +grsecurity_init(void)
23832 +{
23833 +       int j;
23834 +       /* create the per-cpu shared pages */
23835 +
23836 +#ifdef CONFIG_X86
23837 +       memset((char *)(0x41a + PAGE_OFFSET), 0, 36);
23838 +#endif
23839 +
23840 +       for (j = 0; j < 4; j++) {
23841 +               gr_shared_page[j] = (char *)__alloc_percpu(PAGE_SIZE);
23842 +               if (gr_shared_page[j] == NULL) {
23843 +                       panic("Unable to allocate grsecurity shared page");
23844 +                       return;
23845 +               }
23846 +       }
23847 +
23848 +       /* allocate log buffers */
23849 +       gr_alert_log_fmt = kmalloc(512, GFP_KERNEL);
23850 +       if (!gr_alert_log_fmt) {
23851 +               panic("Unable to allocate grsecurity alert log format buffer");
23852 +               return;
23853 +       }
23854 +       gr_audit_log_fmt = kmalloc(512, GFP_KERNEL);
23855 +       if (!gr_audit_log_fmt) {
23856 +               panic("Unable to allocate grsecurity audit log format buffer");
23857 +               return;
23858 +       }
23859 +       gr_alert_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23860 +       if (!gr_alert_log_buf) {
23861 +               panic("Unable to allocate grsecurity alert log buffer");
23862 +               return;
23863 +       }
23864 +       gr_audit_log_buf = (char *) get_zeroed_page(GFP_KERNEL);
23865 +       if (!gr_audit_log_buf) {
23866 +               panic("Unable to allocate grsecurity audit log buffer");
23867 +               return;
23868 +       }
23869 +
23870 +       /* allocate memory for authentication structure */
23871 +       gr_usermode = kmalloc(sizeof(struct gr_arg), GFP_KERNEL);
23872 +       gr_system_salt = kmalloc(GR_SALT_LEN, GFP_KERNEL);
23873 +       gr_system_sum = kmalloc(GR_SHA_LEN, GFP_KERNEL);
23874 +
23875 +       if (!gr_usermode || !gr_system_salt || !gr_system_sum) {
23876 +               panic("Unable to allocate grsecurity authentication structure");
23877 +               return;
23878 +       }
23879 +
23880 +#if !defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_SYSCTL_ON)
23881 +#ifndef CONFIG_GRKERNSEC_SYSCTL
23882 +       grsec_lock = 1;
23883 +#endif
23884 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
23885 +       grsec_enable_audit_textrel = 1;
23886 +#endif
23887 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
23888 +       grsec_enable_group = 1;
23889 +       grsec_audit_gid = CONFIG_GRKERNSEC_AUDIT_GID;
23890 +#endif
23891 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
23892 +       grsec_enable_chdir = 1;
23893 +#endif
23894 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
23895 +       grsec_enable_audit_ipc = 1;
23896 +#endif
23897 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
23898 +       grsec_enable_mount = 1;
23899 +#endif
23900 +#ifdef CONFIG_GRKERNSEC_LINK
23901 +       grsec_enable_link = 1;
23902 +#endif
23903 +#ifdef CONFIG_GRKERNSEC_DMESG
23904 +       grsec_enable_dmesg = 1;
23905 +#endif
23906 +#ifdef CONFIG_GRKERNSEC_FIFO
23907 +       grsec_enable_fifo = 1;
23908 +#endif
23909 +#ifdef CONFIG_GRKERNSEC_EXECVE
23910 +       grsec_enable_execve = 1;
23911 +#endif
23912 +#ifdef CONFIG_GRKERNSEC_EXECLOG
23913 +       grsec_enable_execlog = 1;
23914 +#endif
23915 +#ifdef CONFIG_GRKERNSEC_SIGNAL
23916 +       grsec_enable_signal = 1;
23917 +#endif
23918 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
23919 +       grsec_enable_forkfail = 1;
23920 +#endif
23921 +#ifdef CONFIG_GRKERNSEC_TIME
23922 +       grsec_enable_time = 1;
23923 +#endif
23924 +#ifdef CONFIG_GRKERNSEC_RESLOG
23925 +       grsec_resource_logging = 1;
23926 +#endif
23927 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
23928 +       grsec_enable_chroot_findtask = 1;
23929 +#endif
23930 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
23931 +       grsec_enable_chroot_unix = 1;
23932 +#endif
23933 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
23934 +       grsec_enable_chroot_mount = 1;
23935 +#endif
23936 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
23937 +       grsec_enable_chroot_fchdir = 1;
23938 +#endif
23939 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
23940 +       grsec_enable_chroot_shmat = 1;
23941 +#endif
23942 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
23943 +       grsec_enable_chroot_double = 1;
23944 +#endif
23945 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
23946 +       grsec_enable_chroot_pivot = 1;
23947 +#endif
23948 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
23949 +       grsec_enable_chroot_chdir = 1;
23950 +#endif
23951 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
23952 +       grsec_enable_chroot_chmod = 1;
23953 +#endif
23954 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
23955 +       grsec_enable_chroot_mknod = 1;
23956 +#endif
23957 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
23958 +       grsec_enable_chroot_nice = 1;
23959 +#endif
23960 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
23961 +       grsec_enable_chroot_execlog = 1;
23962 +#endif
23963 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
23964 +       grsec_enable_chroot_caps = 1;
23965 +#endif
23966 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
23967 +       grsec_enable_chroot_sysctl = 1;
23968 +#endif
23969 +#ifdef CONFIG_GRKERNSEC_TPE
23970 +       grsec_enable_tpe = 1;
23971 +       grsec_tpe_gid = CONFIG_GRKERNSEC_TPE_GID;
23972 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
23973 +       grsec_enable_tpe_all = 1;
23974 +#endif
23975 +#endif
23976 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
23977 +       grsec_enable_socket_all = 1;
23978 +       grsec_socket_all_gid = CONFIG_GRKERNSEC_SOCKET_ALL_GID;
23979 +#endif
23980 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
23981 +       grsec_enable_socket_client = 1;
23982 +       grsec_socket_client_gid = CONFIG_GRKERNSEC_SOCKET_CLIENT_GID;
23983 +#endif
23984 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
23985 +       grsec_enable_socket_server = 1;
23986 +       grsec_socket_server_gid = CONFIG_GRKERNSEC_SOCKET_SERVER_GID;
23987 +#endif
23988 +#endif
23989 +
23990 +       return;
23991 +}
23992 diff -urNp linux-2.6.27.10/grsecurity/grsec_ipc.c linux-2.6.27.10/grsecurity/grsec_ipc.c
23993 --- linux-2.6.27.10/grsecurity/grsec_ipc.c      1969-12-31 19:00:00.000000000 -0500
23994 +++ linux-2.6.27.10/grsecurity/grsec_ipc.c      2008-11-18 03:38:45.000000000 -0500
23995 @@ -0,0 +1,81 @@
23996 +#include <linux/kernel.h>
23997 +#include <linux/sched.h>
23998 +#include <linux/types.h>
23999 +#include <linux/ipc.h>
24000 +#include <linux/grsecurity.h>
24001 +#include <linux/grinternal.h>
24002 +
24003 +void
24004 +gr_log_msgget(const int ret, const int msgflg)
24005 +{
24006 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24007 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24008 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24009 +                                         !grsec_enable_group)) && (ret >= 0)
24010 +           && (msgflg & IPC_CREAT))
24011 +               gr_log_noargs(GR_DO_AUDIT, GR_MSGQ_AUDIT_MSG);
24012 +#endif
24013 +       return;
24014 +}
24015 +
24016 +void
24017 +gr_log_msgrm(const uid_t uid, const uid_t cuid)
24018 +{
24019 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24020 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24021 +            grsec_enable_audit_ipc) ||
24022 +           (grsec_enable_audit_ipc && !grsec_enable_group))
24023 +               gr_log_int_int(GR_DO_AUDIT, GR_MSGQR_AUDIT_MSG, uid, cuid);
24024 +#endif
24025 +       return;
24026 +}
24027 +
24028 +void
24029 +gr_log_semget(const int err, const int semflg)
24030 +{
24031 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24032 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24033 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24034 +                                         !grsec_enable_group)) && (err >= 0)
24035 +           && (semflg & IPC_CREAT))
24036 +               gr_log_noargs(GR_DO_AUDIT, GR_SEM_AUDIT_MSG);
24037 +#endif
24038 +       return;
24039 +}
24040 +
24041 +void
24042 +gr_log_semrm(const uid_t uid, const uid_t cuid)
24043 +{
24044 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24045 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24046 +            grsec_enable_audit_ipc) ||
24047 +           (grsec_enable_audit_ipc && !grsec_enable_group))
24048 +               gr_log_int_int(GR_DO_AUDIT, GR_SEMR_AUDIT_MSG, uid, cuid);
24049 +#endif
24050 +       return;
24051 +}
24052 +
24053 +void
24054 +gr_log_shmget(const int err, const int shmflg, const size_t size)
24055 +{
24056 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24057 +       if (((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24058 +             grsec_enable_audit_ipc) || (grsec_enable_audit_ipc &&
24059 +                                         !grsec_enable_group)) && (err >= 0)
24060 +           && (shmflg & IPC_CREAT))
24061 +               gr_log_int(GR_DO_AUDIT, GR_SHM_AUDIT_MSG, size);
24062 +#endif
24063 +       return;
24064 +}
24065 +
24066 +void
24067 +gr_log_shmrm(const uid_t uid, const uid_t cuid)
24068 +{
24069 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
24070 +       if ((grsec_enable_group && in_group_p(grsec_audit_gid) &&
24071 +            grsec_enable_audit_ipc) ||
24072 +           (grsec_enable_audit_ipc && !grsec_enable_group))
24073 +               gr_log_int_int(GR_DO_AUDIT, GR_SHMR_AUDIT_MSG, uid, cuid);
24074 +#endif
24075 +       return;
24076 +}
24077 diff -urNp linux-2.6.27.10/grsecurity/grsec_link.c linux-2.6.27.10/grsecurity/grsec_link.c
24078 --- linux-2.6.27.10/grsecurity/grsec_link.c     1969-12-31 19:00:00.000000000 -0500
24079 +++ linux-2.6.27.10/grsecurity/grsec_link.c     2008-11-18 03:38:45.000000000 -0500
24080 @@ -0,0 +1,39 @@
24081 +#include <linux/kernel.h>
24082 +#include <linux/sched.h>
24083 +#include <linux/fs.h>
24084 +#include <linux/file.h>
24085 +#include <linux/grinternal.h>
24086 +
24087 +int
24088 +gr_handle_follow_link(const struct inode *parent,
24089 +                     const struct inode *inode,
24090 +                     const struct dentry *dentry, const struct vfsmount *mnt)
24091 +{
24092 +#ifdef CONFIG_GRKERNSEC_LINK
24093 +       if (grsec_enable_link && S_ISLNK(inode->i_mode) &&
24094 +           (parent->i_mode & S_ISVTX) && (parent->i_uid != inode->i_uid) &&
24095 +           (parent->i_mode & S_IWOTH) && (current->fsuid != inode->i_uid)) {
24096 +               gr_log_fs_int2(GR_DONT_AUDIT, GR_SYMLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid);
24097 +               return -EACCES;
24098 +       }
24099 +#endif
24100 +       return 0;
24101 +}
24102 +
24103 +int
24104 +gr_handle_hardlink(const struct dentry *dentry,
24105 +                  const struct vfsmount *mnt,
24106 +                  struct inode *inode, const int mode, const char *to)
24107 +{
24108 +#ifdef CONFIG_GRKERNSEC_LINK
24109 +       if (grsec_enable_link && current->fsuid != inode->i_uid &&
24110 +           (!S_ISREG(mode) || (mode & S_ISUID) ||
24111 +            ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) ||
24112 +            (generic_permission(inode, MAY_READ | MAY_WRITE, NULL))) &&
24113 +           !capable(CAP_FOWNER) && current->uid) {
24114 +               gr_log_fs_int2_str(GR_DONT_AUDIT, GR_HARDLINK_MSG, dentry, mnt, inode->i_uid, inode->i_gid, to);
24115 +               return -EPERM;
24116 +       }
24117 +#endif
24118 +       return 0;
24119 +}
24120 diff -urNp linux-2.6.27.10/grsecurity/grsec_log.c linux-2.6.27.10/grsecurity/grsec_log.c
24121 --- linux-2.6.27.10/grsecurity/grsec_log.c      1969-12-31 19:00:00.000000000 -0500
24122 +++ linux-2.6.27.10/grsecurity/grsec_log.c      2008-11-18 03:38:45.000000000 -0500
24123 @@ -0,0 +1,269 @@
24124 +#include <linux/kernel.h>
24125 +#include <linux/sched.h>
24126 +#include <linux/file.h>
24127 +#include <linux/tty.h>
24128 +#include <linux/fs.h>
24129 +#include <linux/grinternal.h>
24130 +
24131 +#define BEGIN_LOCKS(x) \
24132 +       read_lock(&tasklist_lock); \
24133 +       read_lock(&grsec_exec_file_lock); \
24134 +       if (x != GR_DO_AUDIT) \
24135 +               spin_lock(&grsec_alert_lock); \
24136 +       else \
24137 +               spin_lock(&grsec_audit_lock)
24138 +
24139 +#define END_LOCKS(x) \
24140 +       if (x != GR_DO_AUDIT) \
24141 +               spin_unlock(&grsec_alert_lock); \
24142 +       else \
24143 +               spin_unlock(&grsec_audit_lock); \
24144 +       read_unlock(&grsec_exec_file_lock); \
24145 +       read_unlock(&tasklist_lock); \
24146 +       if (x == GR_DONT_AUDIT) \
24147 +               gr_handle_alertkill(current)
24148 +
24149 +enum {
24150 +       FLOODING,
24151 +       NO_FLOODING
24152 +};
24153 +
24154 +extern char *gr_alert_log_fmt;
24155 +extern char *gr_audit_log_fmt;
24156 +extern char *gr_alert_log_buf;
24157 +extern char *gr_audit_log_buf;
24158 +
24159 +static int gr_log_start(int audit)
24160 +{
24161 +       char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
24162 +       char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
24163 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24164 +
24165 +       if (audit == GR_DO_AUDIT)
24166 +               goto set_fmt;
24167 +
24168 +       if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
24169 +               grsec_alert_wtime = jiffies;
24170 +               grsec_alert_fyet = 0;
24171 +       } else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
24172 +               grsec_alert_fyet++;
24173 +       } else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
24174 +               grsec_alert_wtime = jiffies;
24175 +               grsec_alert_fyet++;
24176 +               printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
24177 +               return FLOODING;
24178 +       } else return FLOODING;
24179 +
24180 +set_fmt:
24181 +       memset(buf, 0, PAGE_SIZE);
24182 +       if (current->signal->curr_ip && gr_acl_is_enabled()) {
24183 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
24184 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24185 +       } else if (current->signal->curr_ip) {
24186 +               sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
24187 +               snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
24188 +       } else if (gr_acl_is_enabled()) {
24189 +               sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
24190 +               snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
24191 +       } else {
24192 +               sprintf(fmt, "%s%s", loglevel, "grsec: ");
24193 +               strcpy(buf, fmt);
24194 +       }
24195 +
24196 +       return NO_FLOODING;
24197 +}
24198 +
24199 +static void gr_log_middle(int audit, const char *msg, va_list ap)
24200 +{
24201 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24202 +       unsigned int len = strlen(buf);
24203 +
24204 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24205 +
24206 +       return;
24207 +}
24208 +
24209 +static void gr_log_middle_varargs(int audit, const char *msg, ...)
24210 +{
24211 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24212 +       unsigned int len = strlen(buf);
24213 +       va_list ap;
24214 +
24215 +       va_start(ap, msg);
24216 +       vsnprintf(buf + len, PAGE_SIZE - len - 1, msg, ap);
24217 +       va_end(ap);
24218 +
24219 +       return;
24220 +}
24221 +
24222 +static void gr_log_end(int audit)
24223 +{
24224 +       char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
24225 +       unsigned int len = strlen(buf);
24226 +
24227 +       snprintf(buf + len, PAGE_SIZE - len - 1, DEFAULTSECMSG, DEFAULTSECARGS(current));
24228 +       printk("%s\n", buf);
24229 +
24230 +       return;
24231 +}
24232 +
24233 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...)
24234 +{
24235 +       int logtype;
24236 +       char *result = (audit == GR_DO_AUDIT) ? "successful" : "denied";
24237 +       char *str1, *str2, *str3;
24238 +       int num1, num2;
24239 +       unsigned long ulong1, ulong2;
24240 +       struct dentry *dentry;
24241 +       struct vfsmount *mnt;
24242 +       struct file *file;
24243 +       struct task_struct *task;
24244 +       va_list ap;
24245 +
24246 +       BEGIN_LOCKS(audit);
24247 +       logtype = gr_log_start(audit);
24248 +       if (logtype == FLOODING) {
24249 +               END_LOCKS(audit);
24250 +               return;
24251 +       }
24252 +       va_start(ap, argtypes);
24253 +       switch (argtypes) {
24254 +       case GR_TTYSNIFF:
24255 +               task = va_arg(ap, struct task_struct *);
24256 +               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);
24257 +               break;
24258 +       case GR_SYSCTL_HIDDEN:
24259 +               str1 = va_arg(ap, char *);
24260 +               gr_log_middle_varargs(audit, msg, result, str1);
24261 +               break;
24262 +       case GR_RBAC:
24263 +               dentry = va_arg(ap, struct dentry *);
24264 +               mnt = va_arg(ap, struct vfsmount *);
24265 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt));
24266 +               break;
24267 +       case GR_RBAC_STR:
24268 +               dentry = va_arg(ap, struct dentry *);
24269 +               mnt = va_arg(ap, struct vfsmount *);
24270 +               str1 = va_arg(ap, char *);
24271 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1);
24272 +               break;
24273 +       case GR_STR_RBAC:
24274 +               str1 = va_arg(ap, char *);
24275 +               dentry = va_arg(ap, struct dentry *);
24276 +               mnt = va_arg(ap, struct vfsmount *);
24277 +               gr_log_middle_varargs(audit, msg, result, str1, gr_to_filename(dentry, mnt));
24278 +               break;
24279 +       case GR_RBAC_MODE2:
24280 +               dentry = va_arg(ap, struct dentry *);
24281 +               mnt = va_arg(ap, struct vfsmount *);
24282 +               str1 = va_arg(ap, char *);
24283 +               str2 = va_arg(ap, char *);
24284 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2);
24285 +               break;
24286 +       case GR_RBAC_MODE3:
24287 +               dentry = va_arg(ap, struct dentry *);
24288 +               mnt = va_arg(ap, struct vfsmount *);
24289 +               str1 = va_arg(ap, char *);
24290 +               str2 = va_arg(ap, char *);
24291 +               str3 = va_arg(ap, char *);
24292 +               gr_log_middle_varargs(audit, msg, result, gr_to_filename(dentry, mnt), str1, str2, str3);
24293 +               break;
24294 +       case GR_FILENAME:
24295 +               dentry = va_arg(ap, struct dentry *);
24296 +               mnt = va_arg(ap, struct vfsmount *);
24297 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt));
24298 +               break;
24299 +       case GR_STR_FILENAME:
24300 +               str1 = va_arg(ap, char *);
24301 +               dentry = va_arg(ap, struct dentry *);
24302 +               mnt = va_arg(ap, struct vfsmount *);
24303 +               gr_log_middle_varargs(audit, msg, str1, gr_to_filename(dentry, mnt));
24304 +               break;
24305 +       case GR_FILENAME_STR:
24306 +               dentry = va_arg(ap, struct dentry *);
24307 +               mnt = va_arg(ap, struct vfsmount *);
24308 +               str1 = va_arg(ap, char *);
24309 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), str1);
24310 +               break;
24311 +       case GR_FILENAME_TWO_INT:
24312 +               dentry = va_arg(ap, struct dentry *);
24313 +               mnt = va_arg(ap, struct vfsmount *);
24314 +               num1 = va_arg(ap, int);
24315 +               num2 = va_arg(ap, int);
24316 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2);
24317 +               break;
24318 +       case GR_FILENAME_TWO_INT_STR:
24319 +               dentry = va_arg(ap, struct dentry *);
24320 +               mnt = va_arg(ap, struct vfsmount *);
24321 +               num1 = va_arg(ap, int);
24322 +               num2 = va_arg(ap, int);
24323 +               str1 = va_arg(ap, char *);
24324 +               gr_log_middle_varargs(audit, msg, gr_to_filename(dentry, mnt), num1, num2, str1);
24325 +               break;
24326 +       case GR_TEXTREL:
24327 +               file = va_arg(ap, struct file *);
24328 +               ulong1 = va_arg(ap, unsigned long);
24329 +               ulong2 = va_arg(ap, unsigned long);
24330 +               gr_log_middle_varargs(audit, msg, file ? gr_to_filename(file->f_path.dentry, file->f_path.mnt) : "<anonymous mapping>", ulong1, ulong2);
24331 +               break;
24332 +       case GR_PTRACE:
24333 +               task = va_arg(ap, struct task_struct *);
24334 +               gr_log_middle_varargs(audit, msg, task->exec_file ? gr_to_filename(task->exec_file->f_path.dentry, task->exec_file->f_path.mnt) : "(none)", task->comm, task->pid);
24335 +               break;
24336 +       case GR_RESOURCE:
24337 +               task = va_arg(ap, struct task_struct *);
24338 +               ulong1 = va_arg(ap, unsigned long);
24339 +               str1 = va_arg(ap, char *);
24340 +               ulong2 = va_arg(ap, unsigned long);
24341 +               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);
24342 +               break;
24343 +       case GR_CAP:
24344 +               task = va_arg(ap, struct task_struct *);
24345 +               str1 = va_arg(ap, char *);
24346 +               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);
24347 +               break;
24348 +       case GR_SIG:
24349 +               task = va_arg(ap, struct task_struct *);
24350 +               num1 = va_arg(ap, int);
24351 +               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);
24352 +               break;
24353 +       case GR_CRASH1:
24354 +               task = va_arg(ap, struct task_struct *);
24355 +               ulong1 = va_arg(ap, unsigned long);
24356 +               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);
24357 +               break;
24358 +       case GR_CRASH2:
24359 +               task = va_arg(ap, struct task_struct *);
24360 +               ulong1 = va_arg(ap, unsigned long);
24361 +               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);
24362 +               break;
24363 +       case GR_PSACCT:
24364 +               {
24365 +                       unsigned int wday, cday;
24366 +                       __u8 whr, chr;
24367 +                       __u8 wmin, cmin;
24368 +                       __u8 wsec, csec;
24369 +                       char cur_tty[64] = { 0 };
24370 +                       char parent_tty[64] = { 0 };
24371 +
24372 +                       task = va_arg(ap, struct task_struct *);
24373 +                       wday = va_arg(ap, unsigned int);
24374 +                       cday = va_arg(ap, unsigned int);
24375 +                       whr = va_arg(ap, int);
24376 +                       chr = va_arg(ap, int);
24377 +                       wmin = va_arg(ap, int);
24378 +                       cmin = va_arg(ap, int);
24379 +                       wsec = va_arg(ap, int);
24380 +                       csec = va_arg(ap, int);
24381 +                       ulong1 = va_arg(ap, unsigned long);
24382 +
24383 +                       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);
24384 +               }
24385 +               break;
24386 +       default:
24387 +               gr_log_middle(audit, msg, ap);
24388 +       }
24389 +       va_end(ap);
24390 +       gr_log_end(audit);
24391 +       END_LOCKS(audit);
24392 +}
24393 diff -urNp linux-2.6.27.10/grsecurity/grsec_mem.c linux-2.6.27.10/grsecurity/grsec_mem.c
24394 --- linux-2.6.27.10/grsecurity/grsec_mem.c      1969-12-31 19:00:00.000000000 -0500
24395 +++ linux-2.6.27.10/grsecurity/grsec_mem.c      2008-11-18 03:38:45.000000000 -0500
24396 @@ -0,0 +1,71 @@
24397 +#include <linux/kernel.h>
24398 +#include <linux/sched.h>
24399 +#include <linux/mm.h>
24400 +#include <linux/mman.h>
24401 +#include <linux/grinternal.h>
24402 +
24403 +void
24404 +gr_handle_ioperm(void)
24405 +{
24406 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPERM_MSG);
24407 +       return;
24408 +}
24409 +
24410 +void
24411 +gr_handle_iopl(void)
24412 +{
24413 +       gr_log_noargs(GR_DONT_AUDIT, GR_IOPL_MSG);
24414 +       return;
24415 +}
24416 +
24417 +void
24418 +gr_handle_mem_write(void)
24419 +{
24420 +       gr_log_noargs(GR_DONT_AUDIT, GR_MEM_WRITE_MSG);
24421 +       return;
24422 +}
24423 +
24424 +void
24425 +gr_handle_kmem_write(void)
24426 +{
24427 +       gr_log_noargs(GR_DONT_AUDIT, GR_KMEM_MSG);
24428 +       return;
24429 +}
24430 +
24431 +void
24432 +gr_handle_open_port(void)
24433 +{
24434 +       gr_log_noargs(GR_DONT_AUDIT, GR_PORT_OPEN_MSG);
24435 +       return;
24436 +}
24437 +
24438 +int
24439 +gr_handle_mem_mmap(const unsigned long offset, struct vm_area_struct *vma)
24440 +{
24441 +       unsigned long start, end;
24442 +
24443 +       start = offset;
24444 +       end = start + vma->vm_end - vma->vm_start;
24445 +
24446 +       if (start > end) {
24447 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24448 +               return -EPERM;
24449 +       }
24450 +
24451 +       /* allowed ranges : ISA I/O BIOS */
24452 +       if ((start >= __pa(high_memory))
24453 +#ifdef CONFIG_X86
24454 +           || (start >= 0x000a0000 && end <= 0x00100000)
24455 +           || (start >= 0x00000000 && end <= 0x00001000)
24456 +#endif
24457 +       )
24458 +               return 0;
24459 +
24460 +       if (vma->vm_flags & VM_WRITE) {
24461 +               gr_log_noargs(GR_DONT_AUDIT, GR_MEM_MMAP_MSG);
24462 +               return -EPERM;
24463 +       } else
24464 +               vma->vm_flags &= ~VM_MAYWRITE;
24465 +
24466 +       return 0;
24467 +}
24468 diff -urNp linux-2.6.27.10/grsecurity/grsec_mount.c linux-2.6.27.10/grsecurity/grsec_mount.c
24469 --- linux-2.6.27.10/grsecurity/grsec_mount.c    1969-12-31 19:00:00.000000000 -0500
24470 +++ linux-2.6.27.10/grsecurity/grsec_mount.c    2008-11-18 03:38:45.000000000 -0500
24471 @@ -0,0 +1,34 @@
24472 +#include <linux/kernel.h>
24473 +#include <linux/sched.h>
24474 +#include <linux/grsecurity.h>
24475 +#include <linux/grinternal.h>
24476 +
24477 +void
24478 +gr_log_remount(const char *devname, const int retval)
24479 +{
24480 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24481 +       if (grsec_enable_mount && (retval >= 0))
24482 +               gr_log_str(GR_DO_AUDIT, GR_REMOUNT_AUDIT_MSG, devname ? devname : "none");
24483 +#endif
24484 +       return;
24485 +}
24486 +
24487 +void
24488 +gr_log_unmount(const char *devname, const int retval)
24489 +{
24490 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24491 +       if (grsec_enable_mount && (retval >= 0))
24492 +               gr_log_str(GR_DO_AUDIT, GR_UNMOUNT_AUDIT_MSG, devname ? devname : "none");
24493 +#endif
24494 +       return;
24495 +}
24496 +
24497 +void
24498 +gr_log_mount(const char *from, const char *to, const int retval)
24499 +{
24500 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
24501 +       if (grsec_enable_mount && (retval >= 0))
24502 +               gr_log_str_str(GR_DO_AUDIT, GR_MOUNT_AUDIT_MSG, from, to);
24503 +#endif
24504 +       return;
24505 +}
24506 diff -urNp linux-2.6.27.10/grsecurity/grsec_sig.c linux-2.6.27.10/grsecurity/grsec_sig.c
24507 --- linux-2.6.27.10/grsecurity/grsec_sig.c      1969-12-31 19:00:00.000000000 -0500
24508 +++ linux-2.6.27.10/grsecurity/grsec_sig.c      2008-11-18 03:38:45.000000000 -0500
24509 @@ -0,0 +1,58 @@
24510 +#include <linux/kernel.h>
24511 +#include <linux/sched.h>
24512 +#include <linux/delay.h>
24513 +#include <linux/grsecurity.h>
24514 +#include <linux/grinternal.h>
24515 +
24516 +void
24517 +gr_log_signal(const int sig, const struct task_struct *t)
24518 +{
24519 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24520 +       if (grsec_enable_signal && ((sig == SIGSEGV) || (sig == SIGILL) ||
24521 +                                   (sig == SIGABRT) || (sig == SIGBUS))) {
24522 +               if (t->pid == current->pid) {
24523 +                       gr_log_int(GR_DONT_AUDIT_GOOD, GR_UNISIGLOG_MSG, sig);
24524 +               } else {
24525 +                       gr_log_sig(GR_DONT_AUDIT_GOOD, GR_DUALSIGLOG_MSG, t, sig);
24526 +               }
24527 +       }
24528 +#endif
24529 +       return;
24530 +}
24531 +
24532 +int
24533 +gr_handle_signal(const struct task_struct *p, const int sig)
24534 +{
24535 +#ifdef CONFIG_GRKERNSEC
24536 +       if (current->pid > 1 && gr_check_protected_task(p)) {
24537 +               gr_log_sig(GR_DONT_AUDIT, GR_SIG_ACL_MSG, p, sig);
24538 +               return -EPERM;
24539 +       } else if (gr_pid_is_chrooted((struct task_struct *)p)) {
24540 +               return -EPERM;
24541 +       }
24542 +#endif
24543 +       return 0;
24544 +}
24545 +
24546 +void gr_handle_brute_attach(struct task_struct *p)
24547 +{
24548 +#ifdef CONFIG_GRKERNSEC_BRUTE
24549 +       read_lock(&tasklist_lock);
24550 +       read_lock(&grsec_exec_file_lock);
24551 +       if (p->parent && p->parent->exec_file == p->exec_file)
24552 +               p->parent->brute = 1;
24553 +       read_unlock(&grsec_exec_file_lock);
24554 +       read_unlock(&tasklist_lock);
24555 +#endif
24556 +       return;
24557 +}
24558 +
24559 +void gr_handle_brute_check(void)
24560 +{
24561 +#ifdef CONFIG_GRKERNSEC_BRUTE
24562 +       if (current->brute)
24563 +               msleep(30 * 1000);
24564 +#endif
24565 +       return;
24566 +}
24567 +
24568 diff -urNp linux-2.6.27.10/grsecurity/grsec_sock.c linux-2.6.27.10/grsecurity/grsec_sock.c
24569 --- linux-2.6.27.10/grsecurity/grsec_sock.c     1969-12-31 19:00:00.000000000 -0500
24570 +++ linux-2.6.27.10/grsecurity/grsec_sock.c     2008-11-18 11:35:13.000000000 -0500
24571 @@ -0,0 +1,274 @@
24572 +#include <linux/kernel.h>
24573 +#include <linux/module.h>
24574 +#include <linux/sched.h>
24575 +#include <linux/file.h>
24576 +#include <linux/net.h>
24577 +#include <linux/in.h>
24578 +#include <linux/ip.h>
24579 +#include <net/sock.h>
24580 +#include <net/inet_sock.h>
24581 +#include <linux/grsecurity.h>
24582 +#include <linux/grinternal.h>
24583 +#include <linux/gracl.h>
24584 +
24585 +#if defined(CONFIG_IP_NF_MATCH_STEALTH_MODULE)
24586 +extern struct sock *udp_v4_lookup(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
24587 +EXPORT_SYMBOL(udp_v4_lookup);
24588 +#endif
24589 +
24590 +kernel_cap_t gr_cap_rtnetlink(struct sock *sock);
24591 +EXPORT_SYMBOL(gr_cap_rtnetlink);
24592 +
24593 +extern int gr_search_udp_recvmsg(const struct sock *sk, const struct sk_buff *skb);
24594 +extern int gr_search_udp_sendmsg(const struct sock *sk, const struct sockaddr_in *addr);
24595 +
24596 +EXPORT_SYMBOL(gr_search_udp_recvmsg);
24597 +EXPORT_SYMBOL(gr_search_udp_sendmsg);
24598 +
24599 +#ifdef CONFIG_UNIX_MODULE
24600 +EXPORT_SYMBOL(gr_acl_handle_unix);
24601 +EXPORT_SYMBOL(gr_acl_handle_mknod);
24602 +EXPORT_SYMBOL(gr_handle_chroot_unix);
24603 +EXPORT_SYMBOL(gr_handle_create);
24604 +#endif
24605 +
24606 +#ifdef CONFIG_GRKERNSEC
24607 +#define gr_conn_table_size 32749
24608 +struct conn_table_entry {
24609 +       struct conn_table_entry *next;
24610 +       struct signal_struct *sig;
24611 +};
24612 +
24613 +struct conn_table_entry *gr_conn_table[gr_conn_table_size];
24614 +DEFINE_SPINLOCK(gr_conn_table_lock);
24615 +
24616 +extern const char * gr_socktype_to_name(unsigned char type);
24617 +extern const char * gr_proto_to_name(unsigned char proto);
24618 +
24619 +static __inline__ int 
24620 +conn_hash(__u32 saddr, __u32 daddr, __u16 sport, __u16 dport, unsigned int size)
24621 +{
24622 +       return ((daddr + saddr + (sport << 8) + (dport << 16)) % size);
24623 +}
24624 +
24625 +static __inline__ int
24626 +conn_match(const struct signal_struct *sig, __u32 saddr, __u32 daddr, 
24627 +          __u16 sport, __u16 dport)
24628 +{
24629 +       if (unlikely(sig->gr_saddr == saddr && sig->gr_daddr == daddr &&
24630 +                    sig->gr_sport == sport && sig->gr_dport == dport))
24631 +               return 1;
24632 +       else
24633 +               return 0;
24634 +}
24635 +
24636 +static void gr_add_to_task_ip_table_nolock(struct signal_struct *sig, struct conn_table_entry *newent)
24637 +{
24638 +       struct conn_table_entry **match;
24639 +       unsigned int index;
24640 +
24641 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
24642 +                         sig->gr_sport, sig->gr_dport, 
24643 +                         gr_conn_table_size);
24644 +
24645 +       newent->sig = sig;
24646 +       
24647 +       match = &gr_conn_table[index];
24648 +       newent->next = *match;
24649 +       *match = newent;
24650 +
24651 +       return;
24652 +}
24653 +
24654 +static void gr_del_task_from_ip_table_nolock(struct signal_struct *sig)
24655 +{
24656 +       struct conn_table_entry *match, *last = NULL;
24657 +       unsigned int index;
24658 +
24659 +       index = conn_hash(sig->gr_saddr, sig->gr_daddr, 
24660 +                         sig->gr_sport, sig->gr_dport, 
24661 +                         gr_conn_table_size);
24662 +
24663 +       match = gr_conn_table[index];
24664 +       while (match && !conn_match(match->sig, 
24665 +               sig->gr_saddr, sig->gr_daddr, sig->gr_sport, 
24666 +               sig->gr_dport)) {
24667 +               last = match;
24668 +               match = match->next;
24669 +       }
24670 +
24671 +       if (match) {
24672 +               if (last)
24673 +                       last->next = match->next;
24674 +               else
24675 +                       gr_conn_table[index] = NULL;
24676 +               kfree(match);
24677 +       }
24678 +
24679 +       return;
24680 +}
24681 +
24682 +static struct signal_struct * gr_lookup_task_ip_table(__u32 saddr, __u32 daddr,
24683 +                                            __u16 sport, __u16 dport)
24684 +{
24685 +       struct conn_table_entry *match;
24686 +       unsigned int index;
24687 +
24688 +       index = conn_hash(saddr, daddr, sport, dport, gr_conn_table_size);
24689 +
24690 +       match = gr_conn_table[index];
24691 +       while (match && !conn_match(match->sig, saddr, daddr, sport, dport))
24692 +               match = match->next;
24693 +
24694 +       if (match)
24695 +               return match->sig;
24696 +       else
24697 +               return NULL;
24698 +}
24699 +
24700 +#endif
24701 +
24702 +void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet)
24703 +{
24704 +#ifdef CONFIG_GRKERNSEC
24705 +       struct signal_struct *sig = task->signal;
24706 +       struct conn_table_entry *newent;
24707 +
24708 +       newent = kmalloc(sizeof(struct conn_table_entry), GFP_ATOMIC);
24709 +       if (newent == NULL)
24710 +               return;
24711 +       /* no bh lock needed since we are called with bh disabled */
24712 +       spin_lock(&gr_conn_table_lock);
24713 +       gr_del_task_from_ip_table_nolock(sig);
24714 +       sig->gr_saddr = inet->rcv_saddr;
24715 +       sig->gr_daddr = inet->daddr;
24716 +       sig->gr_sport = inet->sport;
24717 +       sig->gr_dport = inet->dport;
24718 +       gr_add_to_task_ip_table_nolock(sig, newent);
24719 +       spin_unlock(&gr_conn_table_lock);
24720 +#endif
24721 +       return;
24722 +}
24723 +
24724 +void gr_del_task_from_ip_table(struct task_struct *task)
24725 +{
24726 +#ifdef CONFIG_GRKERNSEC
24727 +       spin_lock_bh(&gr_conn_table_lock);
24728 +       gr_del_task_from_ip_table_nolock(task->signal);
24729 +       spin_unlock_bh(&gr_conn_table_lock);
24730 +#endif
24731 +       return;
24732 +}
24733 +
24734 +void
24735 +gr_attach_curr_ip(const struct sock *sk)
24736 +{
24737 +#ifdef CONFIG_GRKERNSEC
24738 +       struct signal_struct *p, *set;
24739 +       const struct inet_sock *inet = inet_sk(sk);     
24740 +
24741 +       if (unlikely(sk->sk_protocol != IPPROTO_TCP))
24742 +               return;
24743 +
24744 +       set = current->signal;
24745 +
24746 +       spin_lock_bh(&gr_conn_table_lock);
24747 +       p = gr_lookup_task_ip_table(inet->daddr, inet->rcv_saddr,
24748 +                                   inet->dport, inet->sport);
24749 +       if (unlikely(p != NULL)) {
24750 +               set->curr_ip = p->curr_ip;
24751 +               set->used_accept = 1;
24752 +               gr_del_task_from_ip_table_nolock(p);
24753 +               spin_unlock_bh(&gr_conn_table_lock);
24754 +               return;
24755 +       }
24756 +       spin_unlock_bh(&gr_conn_table_lock);
24757 +
24758 +       set->curr_ip = inet->daddr;
24759 +       set->used_accept = 1;
24760 +#endif
24761 +       return;
24762 +}
24763 +
24764 +int
24765 +gr_handle_sock_all(const int family, const int type, const int protocol)
24766 +{
24767 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
24768 +       if (grsec_enable_socket_all && in_group_p(grsec_socket_all_gid) &&
24769 +           (family != AF_UNIX) && (family != AF_LOCAL)) {
24770 +               gr_log_int_str2(GR_DONT_AUDIT, GR_SOCK2_MSG, family, gr_socktype_to_name(type), gr_proto_to_name(protocol));
24771 +               return -EACCES;
24772 +       }
24773 +#endif
24774 +       return 0;
24775 +}
24776 +
24777 +int
24778 +gr_handle_sock_server(const struct sockaddr *sck)
24779 +{
24780 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24781 +       if (grsec_enable_socket_server &&
24782 +           in_group_p(grsec_socket_server_gid) &&
24783 +           sck && (sck->sa_family != AF_UNIX) &&
24784 +           (sck->sa_family != AF_LOCAL)) {
24785 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24786 +               return -EACCES;
24787 +       }
24788 +#endif
24789 +       return 0;
24790 +}
24791 +
24792 +int
24793 +gr_handle_sock_server_other(const struct sock *sck)
24794 +{
24795 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
24796 +       if (grsec_enable_socket_server &&
24797 +           in_group_p(grsec_socket_server_gid) &&
24798 +           sck && (sck->sk_family != AF_UNIX) &&
24799 +           (sck->sk_family != AF_LOCAL)) {
24800 +               gr_log_noargs(GR_DONT_AUDIT, GR_BIND_MSG);
24801 +               return -EACCES;
24802 +       }
24803 +#endif
24804 +       return 0;
24805 +}
24806 +
24807 +int
24808 +gr_handle_sock_client(const struct sockaddr *sck)
24809 +{
24810 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
24811 +       if (grsec_enable_socket_client && in_group_p(grsec_socket_client_gid) &&
24812 +           sck && (sck->sa_family != AF_UNIX) &&
24813 +           (sck->sa_family != AF_LOCAL)) {
24814 +               gr_log_noargs(GR_DONT_AUDIT, GR_CONNECT_MSG);
24815 +               return -EACCES;
24816 +       }
24817 +#endif
24818 +       return 0;
24819 +}
24820 +
24821 +kernel_cap_t
24822 +gr_cap_rtnetlink(struct sock *sock)
24823 +{
24824 +#ifdef CONFIG_GRKERNSEC
24825 +       if (!gr_acl_is_enabled())
24826 +               return current->cap_effective;
24827 +       else if (sock->sk_protocol == NETLINK_ISCSI &&
24828 +                cap_raised(current->cap_effective, CAP_SYS_ADMIN) &&
24829 +                gr_task_is_capable(current, CAP_SYS_ADMIN))
24830 +               return current->cap_effective;
24831 +       else if (sock->sk_protocol == NETLINK_AUDIT &&
24832 +                cap_raised(current->cap_effective, CAP_AUDIT_WRITE) &&
24833 +                gr_task_is_capable(current, CAP_AUDIT_WRITE) &&
24834 +                cap_raised(current->cap_effective, CAP_AUDIT_CONTROL) &&
24835 +                gr_task_is_capable(current, CAP_AUDIT_CONTROL))
24836 +               return current->cap_effective;
24837 +       else if (cap_raised(current->cap_effective, CAP_NET_ADMIN) &&
24838 +                gr_task_is_capable(current, CAP_NET_ADMIN))
24839 +               return current->cap_effective;
24840 +       else
24841 +               return __cap_empty_set;
24842 +#else
24843 +       return current->cap_effective;
24844 +#endif
24845 +}
24846 diff -urNp linux-2.6.27.10/grsecurity/grsec_sysctl.c linux-2.6.27.10/grsecurity/grsec_sysctl.c
24847 --- linux-2.6.27.10/grsecurity/grsec_sysctl.c   1969-12-31 19:00:00.000000000 -0500
24848 +++ linux-2.6.27.10/grsecurity/grsec_sysctl.c   2008-11-18 03:38:45.000000000 -0500
24849 @@ -0,0 +1,435 @@
24850 +#include <linux/kernel.h>
24851 +#include <linux/sched.h>
24852 +#include <linux/sysctl.h>
24853 +#include <linux/grsecurity.h>
24854 +#include <linux/grinternal.h>
24855 +
24856 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24857 +int grsec_modstop;
24858 +#endif
24859 +
24860 +int
24861 +gr_handle_sysctl_mod(const char *dirname, const char *name, const int op)
24862 +{
24863 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24864 +       if (!strcmp(dirname, "grsecurity") && grsec_lock && (op & MAY_WRITE)) {
24865 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24866 +               return -EACCES;
24867 +       }
24868 +#endif
24869 +#ifdef CONFIG_GRKERNSEC_MODSTOP
24870 +       if (!strcmp(dirname, "grsecurity") && !strcmp(name, "disable_modules") &&
24871 +           grsec_modstop && (op & MAY_WRITE)) {
24872 +               gr_log_str(GR_DONT_AUDIT, GR_SYSCTL_MSG, name);
24873 +               return -EACCES;
24874 +       }
24875 +#endif
24876 +       return 0;
24877 +}
24878 +
24879 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
24880 +ctl_table grsecurity_table[] = {
24881 +#ifdef CONFIG_GRKERNSEC_SYSCTL
24882 +#ifdef CONFIG_GRKERNSEC_LINK
24883 +       {
24884 +               .ctl_name       = CTL_UNNUMBERED,
24885 +               .procname       = "linking_restrictions",
24886 +               .data           = &grsec_enable_link,
24887 +               .maxlen         = sizeof(int),
24888 +               .mode           = 0600,
24889 +               .proc_handler   = &proc_dointvec,
24890 +       },
24891 +#endif
24892 +#ifdef CONFIG_GRKERNSEC_FIFO
24893 +       {
24894 +               .ctl_name       = CTL_UNNUMBERED,
24895 +               .procname       = "fifo_restrictions",
24896 +               .data           = &grsec_enable_fifo,
24897 +               .maxlen         = sizeof(int),
24898 +               .mode           = 0600,
24899 +               .proc_handler   = &proc_dointvec,
24900 +       },
24901 +#endif
24902 +#ifdef CONFIG_GRKERNSEC_EXECVE
24903 +       {
24904 +               .ctl_name       = CTL_UNNUMBERED,
24905 +               .procname       = "execve_limiting",
24906 +               .data           = &grsec_enable_execve,
24907 +               .maxlen         = sizeof(int),
24908 +               .mode           = 0600,
24909 +               .proc_handler   = &proc_dointvec,
24910 +       },
24911 +#endif
24912 +#ifdef CONFIG_GRKERNSEC_EXECLOG
24913 +       {
24914 +               .ctl_name       = CTL_UNNUMBERED,
24915 +               .procname       = "exec_logging",
24916 +               .data           = &grsec_enable_execlog,
24917 +               .maxlen         = sizeof(int),
24918 +               .mode           = 0600,
24919 +               .proc_handler   = &proc_dointvec,
24920 +       },
24921 +#endif
24922 +#ifdef CONFIG_GRKERNSEC_SIGNAL
24923 +       {
24924 +               .ctl_name       = CTL_UNNUMBERED,
24925 +               .procname       = "signal_logging",
24926 +               .data           = &grsec_enable_signal,
24927 +               .maxlen         = sizeof(int),
24928 +               .mode           = 0600,
24929 +               .proc_handler   = &proc_dointvec,
24930 +       },
24931 +#endif
24932 +#ifdef CONFIG_GRKERNSEC_FORKFAIL
24933 +       {
24934 +               .ctl_name       = CTL_UNNUMBERED,
24935 +               .procname       = "forkfail_logging",
24936 +               .data           = &grsec_enable_forkfail,
24937 +               .maxlen         = sizeof(int),
24938 +               .mode           = 0600,
24939 +               .proc_handler   = &proc_dointvec,
24940 +       },
24941 +#endif
24942 +#ifdef CONFIG_GRKERNSEC_TIME
24943 +       {
24944 +               .ctl_name       = CTL_UNNUMBERED,
24945 +               .procname       = "timechange_logging",
24946 +               .data           = &grsec_enable_time,
24947 +               .maxlen         = sizeof(int),
24948 +               .mode           = 0600,
24949 +               .proc_handler   = &proc_dointvec,
24950 +       },
24951 +#endif
24952 +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT
24953 +       {
24954 +               .ctl_name       = CTL_UNNUMBERED,
24955 +               .procname       = "chroot_deny_shmat",
24956 +               .data           = &grsec_enable_chroot_shmat,
24957 +               .maxlen         = sizeof(int),
24958 +               .mode           = 0600,
24959 +               .proc_handler   = &proc_dointvec,
24960 +       },
24961 +#endif
24962 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
24963 +       {
24964 +               .ctl_name       = CTL_UNNUMBERED,
24965 +               .procname       = "chroot_deny_unix",
24966 +               .data           = &grsec_enable_chroot_unix,
24967 +               .maxlen         = sizeof(int),
24968 +               .mode           = 0600,
24969 +               .proc_handler   = &proc_dointvec,
24970 +       },
24971 +#endif
24972 +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT
24973 +       {
24974 +               .ctl_name       = CTL_UNNUMBERED,
24975 +               .procname       = "chroot_deny_mount",
24976 +               .data           = &grsec_enable_chroot_mount,
24977 +               .maxlen         = sizeof(int),
24978 +               .mode           = 0600,
24979 +               .proc_handler   = &proc_dointvec,
24980 +       },
24981 +#endif
24982 +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
24983 +       {
24984 +               .ctl_name       = CTL_UNNUMBERED,
24985 +               .procname       = "chroot_deny_fchdir",
24986 +               .data           = &grsec_enable_chroot_fchdir,
24987 +               .maxlen         = sizeof(int),
24988 +               .mode           = 0600,
24989 +               .proc_handler   = &proc_dointvec,
24990 +       },
24991 +#endif
24992 +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE
24993 +       {
24994 +               .ctl_name       = CTL_UNNUMBERED,
24995 +               .procname       = "chroot_deny_chroot",
24996 +               .data           = &grsec_enable_chroot_double,
24997 +               .maxlen         = sizeof(int),
24998 +               .mode           = 0600,
24999 +               .proc_handler   = &proc_dointvec,
25000 +       },
25001 +#endif
25002 +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT
25003 +       {
25004 +               .ctl_name       = CTL_UNNUMBERED,
25005 +               .procname       = "chroot_deny_pivot",
25006 +               .data           = &grsec_enable_chroot_pivot,
25007 +               .maxlen         = sizeof(int),
25008 +               .mode           = 0600,
25009 +               .proc_handler   = &proc_dointvec,
25010 +       },
25011 +#endif
25012 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR
25013 +       {
25014 +               .ctl_name       = CTL_UNNUMBERED,
25015 +               .procname       = "chroot_enforce_chdir",
25016 +               .data           = &grsec_enable_chroot_chdir,
25017 +               .maxlen         = sizeof(int),
25018 +               .mode           = 0600,
25019 +               .proc_handler   = &proc_dointvec,
25020 +       },
25021 +#endif
25022 +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD
25023 +       {
25024 +               .ctl_name       = CTL_UNNUMBERED,
25025 +               .procname       = "chroot_deny_chmod",
25026 +               .data           = &grsec_enable_chroot_chmod,
25027 +               .maxlen         = sizeof(int),
25028 +               .mode           = 0600,
25029 +               .proc_handler   = &proc_dointvec,
25030 +       },
25031 +#endif
25032 +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD
25033 +       {
25034 +               .ctl_name       = CTL_UNNUMBERED,
25035 +               .procname       = "chroot_deny_mknod",
25036 +               .data           = &grsec_enable_chroot_mknod,
25037 +               .maxlen         = sizeof(int),
25038 +               .mode           = 0600,
25039 +               .proc_handler   = &proc_dointvec,
25040 +       },
25041 +#endif
25042 +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE
25043 +       {
25044 +               .ctl_name       = CTL_UNNUMBERED,
25045 +               .procname       = "chroot_restrict_nice",
25046 +               .data           = &grsec_enable_chroot_nice,
25047 +               .maxlen         = sizeof(int),
25048 +               .mode           = 0600,
25049 +               .proc_handler   = &proc_dointvec,
25050 +       },
25051 +#endif
25052 +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG
25053 +       {
25054 +               .ctl_name       = CTL_UNNUMBERED,
25055 +               .procname       = "chroot_execlog",
25056 +               .data           = &grsec_enable_chroot_execlog,
25057 +               .maxlen         = sizeof(int),
25058 +               .mode           = 0600,
25059 +               .proc_handler   = &proc_dointvec,
25060 +       },
25061 +#endif
25062 +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS
25063 +       {
25064 +               .ctl_name       = CTL_UNNUMBERED,
25065 +               .procname       = "chroot_caps",
25066 +               .data           = &grsec_enable_chroot_caps,
25067 +               .maxlen         = sizeof(int),
25068 +               .mode           = 0600,
25069 +               .proc_handler   = &proc_dointvec,
25070 +       },
25071 +#endif
25072 +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL
25073 +       {
25074 +               .ctl_name       = CTL_UNNUMBERED,
25075 +               .procname       = "chroot_deny_sysctl",
25076 +               .data           = &grsec_enable_chroot_sysctl,
25077 +               .maxlen         = sizeof(int),
25078 +               .mode           = 0600,
25079 +               .proc_handler   = &proc_dointvec,
25080 +       },
25081 +#endif
25082 +#ifdef CONFIG_GRKERNSEC_TPE
25083 +       {
25084 +               .ctl_name       = CTL_UNNUMBERED,
25085 +               .procname       = "tpe",
25086 +               .data           = &grsec_enable_tpe,
25087 +               .maxlen         = sizeof(int),
25088 +               .mode           = 0600,
25089 +               .proc_handler   = &proc_dointvec,
25090 +       },
25091 +       {
25092 +               .ctl_name       = CTL_UNNUMBERED,
25093 +               .procname       = "tpe_gid",
25094 +               .data           = &grsec_tpe_gid,
25095 +               .maxlen         = sizeof(int),
25096 +               .mode           = 0600,
25097 +               .proc_handler   = &proc_dointvec,
25098 +       },
25099 +#endif
25100 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
25101 +       {
25102 +               .ctl_name       = CTL_UNNUMBERED,
25103 +               .procname       = "tpe_restrict_all",
25104 +               .data           = &grsec_enable_tpe_all,
25105 +               .maxlen         = sizeof(int),
25106 +               .mode           = 0600,
25107 +               .proc_handler   = &proc_dointvec,
25108 +       },
25109 +#endif
25110 +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL
25111 +       {
25112 +               .ctl_name       = CTL_UNNUMBERED,
25113 +               .procname       = "socket_all",
25114 +               .data           = &grsec_enable_socket_all,
25115 +               .maxlen         = sizeof(int),
25116 +               .mode           = 0600,
25117 +               .proc_handler   = &proc_dointvec,
25118 +       },
25119 +       {
25120 +               .ctl_name       = CTL_UNNUMBERED,
25121 +               .procname       = "socket_all_gid",
25122 +               .data           = &grsec_socket_all_gid,
25123 +               .maxlen         = sizeof(int),
25124 +               .mode           = 0600,
25125 +               .proc_handler   = &proc_dointvec,
25126 +       },
25127 +#endif
25128 +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT
25129 +       {
25130 +               .ctl_name       = CTL_UNNUMBERED,
25131 +               .procname       = "socket_client",
25132 +               .data           = &grsec_enable_socket_client,
25133 +               .maxlen         = sizeof(int),
25134 +               .mode           = 0600,
25135 +               .proc_handler   = &proc_dointvec,
25136 +       },
25137 +       {
25138 +               .ctl_name       = CTL_UNNUMBERED,
25139 +               .procname       = "socket_client_gid",
25140 +               .data           = &grsec_socket_client_gid,
25141 +               .maxlen         = sizeof(int),
25142 +               .mode           = 0600,
25143 +               .proc_handler   = &proc_dointvec,
25144 +       },
25145 +#endif
25146 +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER
25147 +       {
25148 +               .ctl_name       = CTL_UNNUMBERED,
25149 +               .procname       = "socket_server",
25150 +               .data           = &grsec_enable_socket_server,
25151 +               .maxlen         = sizeof(int),
25152 +               .mode           = 0600,
25153 +               .proc_handler   = &proc_dointvec,
25154 +       },
25155 +       {
25156 +               .ctl_name       = CTL_UNNUMBERED,
25157 +               .procname       = "socket_server_gid",
25158 +               .data           = &grsec_socket_server_gid,
25159 +               .maxlen         = sizeof(int),
25160 +               .mode           = 0600,
25161 +               .proc_handler   = &proc_dointvec,
25162 +       },
25163 +#endif
25164 +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP
25165 +       {
25166 +               .ctl_name       = CTL_UNNUMBERED,
25167 +               .procname       = "audit_group",
25168 +               .data           = &grsec_enable_group,
25169 +               .maxlen         = sizeof(int),
25170 +               .mode           = 0600,
25171 +               .proc_handler   = &proc_dointvec,
25172 +       },
25173 +       {
25174 +               .ctl_name       = CTL_UNNUMBERED,
25175 +               .procname       = "audit_gid",
25176 +               .data           = &grsec_audit_gid,
25177 +               .maxlen         = sizeof(int),
25178 +               .mode           = 0600,
25179 +               .proc_handler   = &proc_dointvec,
25180 +       },
25181 +#endif
25182 +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR
25183 +       {
25184 +               .ctl_name       = CTL_UNNUMBERED,
25185 +               .procname       = "audit_chdir",
25186 +               .data           = &grsec_enable_chdir,
25187 +               .maxlen         = sizeof(int),
25188 +               .mode           = 0600,
25189 +               .proc_handler   = &proc_dointvec,
25190 +       },
25191 +#endif
25192 +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT
25193 +       {
25194 +               .ctl_name       = CTL_UNNUMBERED,
25195 +               .procname       = "audit_mount",
25196 +               .data           = &grsec_enable_mount,
25197 +               .maxlen         = sizeof(int),
25198 +               .mode           = 0600,
25199 +               .proc_handler   = &proc_dointvec,
25200 +       },
25201 +#endif
25202 +#ifdef CONFIG_GRKERNSEC_AUDIT_IPC
25203 +       {
25204 +               .ctl_name       = CTL_UNNUMBERED,
25205 +               .procname       = "audit_ipc",
25206 +               .data           = &grsec_enable_audit_ipc,
25207 +               .maxlen         = sizeof(int),
25208 +               .mode           = 0600,
25209 +               .proc_handler   = &proc_dointvec,
25210 +       },
25211 +#endif
25212 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25213 +       {
25214 +               .ctl_name       = CTL_UNNUMBERED,
25215 +               .procname       = "audit_textrel",
25216 +               .data           = &grsec_enable_audit_textrel,
25217 +               .maxlen         = sizeof(int),
25218 +               .mode           = 0600,
25219 +               .proc_handler   = &proc_dointvec,
25220 +       },
25221 +#endif
25222 +#ifdef CONFIG_GRKERNSEC_DMESG
25223 +       {
25224 +               .ctl_name       = CTL_UNNUMBERED,
25225 +               .procname       = "dmesg",
25226 +               .data           = &grsec_enable_dmesg,
25227 +               .maxlen         = sizeof(int),
25228 +               .mode           = 0600,
25229 +               .proc_handler   = &proc_dointvec,
25230 +       },
25231 +#endif
25232 +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK
25233 +       {
25234 +               .ctl_name       = CTL_UNNUMBERED,
25235 +               .procname       = "chroot_findtask",
25236 +               .data           = &grsec_enable_chroot_findtask,
25237 +               .maxlen         = sizeof(int),
25238 +               .mode           = 0600,
25239 +               .proc_handler   = &proc_dointvec,
25240 +       },
25241 +#endif
25242 +#ifdef CONFIG_GRKERNSEC_RESLOG
25243 +       {
25244 +               .ctl_name       = CTL_UNNUMBERED,
25245 +               .procname       = "resource_logging",
25246 +               .data           = &grsec_resource_logging,
25247 +               .maxlen         = sizeof(int),
25248 +               .mode           = 0600,
25249 +               .proc_handler   = &proc_dointvec,
25250 +       },
25251 +#endif
25252 +       {
25253 +               .ctl_name       = CTL_UNNUMBERED,
25254 +               .procname       = "grsec_lock",
25255 +               .data           = &grsec_lock,
25256 +               .maxlen         = sizeof(int),
25257 +               .mode           = 0600,
25258 +               .proc_handler   = &proc_dointvec,
25259 +       },
25260 +#endif
25261 +#ifdef CONFIG_GRKERNSEC_MODSTOP
25262 +       {
25263 +               .ctl_name       = CTL_UNNUMBERED,
25264 +               .procname       = "disable_modules",
25265 +               .data           = &grsec_modstop,
25266 +               .maxlen         = sizeof(int),
25267 +               .mode           = 0600,
25268 +               .proc_handler   = &proc_dointvec,
25269 +       },
25270 +#endif
25271 +       { .ctl_name = 0 }
25272 +};
25273 +#endif
25274 +
25275 +int gr_check_modstop(void)
25276 +{
25277 +#ifdef CONFIG_GRKERNSEC_MODSTOP
25278 +       if (grsec_modstop == 1) {
25279 +               gr_log_noargs(GR_DONT_AUDIT, GR_STOPMOD_MSG);
25280 +               return 1;
25281 +       }
25282 +#endif
25283 +       return 0;
25284 +}
25285 diff -urNp linux-2.6.27.10/grsecurity/grsec_textrel.c linux-2.6.27.10/grsecurity/grsec_textrel.c
25286 --- linux-2.6.27.10/grsecurity/grsec_textrel.c  1969-12-31 19:00:00.000000000 -0500
25287 +++ linux-2.6.27.10/grsecurity/grsec_textrel.c  2008-11-18 03:38:45.000000000 -0500
25288 @@ -0,0 +1,16 @@
25289 +#include <linux/kernel.h>
25290 +#include <linux/sched.h>
25291 +#include <linux/mm.h>
25292 +#include <linux/file.h>
25293 +#include <linux/grinternal.h>
25294 +#include <linux/grsecurity.h>
25295 +
25296 +void
25297 +gr_log_textrel(struct vm_area_struct * vma)
25298 +{
25299 +#ifdef CONFIG_GRKERNSEC_AUDIT_TEXTREL
25300 +       if (grsec_enable_audit_textrel)
25301 +               gr_log_textrel_ulong_ulong(GR_DO_AUDIT, GR_TEXTREL_AUDIT_MSG, vma->vm_file, vma->vm_start, vma->vm_pgoff);
25302 +#endif
25303 +       return;
25304 +}
25305 diff -urNp linux-2.6.27.10/grsecurity/grsec_time.c linux-2.6.27.10/grsecurity/grsec_time.c
25306 --- linux-2.6.27.10/grsecurity/grsec_time.c     1969-12-31 19:00:00.000000000 -0500
25307 +++ linux-2.6.27.10/grsecurity/grsec_time.c     2008-11-18 03:38:45.000000000 -0500
25308 @@ -0,0 +1,13 @@
25309 +#include <linux/kernel.h>
25310 +#include <linux/sched.h>
25311 +#include <linux/grinternal.h>
25312 +
25313 +void
25314 +gr_log_timechange(void)
25315 +{
25316 +#ifdef CONFIG_GRKERNSEC_TIME
25317 +       if (grsec_enable_time)
25318 +               gr_log_noargs(GR_DONT_AUDIT_GOOD, GR_TIME_MSG);
25319 +#endif
25320 +       return;
25321 +}
25322 diff -urNp linux-2.6.27.10/grsecurity/grsec_tpe.c linux-2.6.27.10/grsecurity/grsec_tpe.c
25323 --- linux-2.6.27.10/grsecurity/grsec_tpe.c      1969-12-31 19:00:00.000000000 -0500
25324 +++ linux-2.6.27.10/grsecurity/grsec_tpe.c      2008-11-18 03:38:45.000000000 -0500
25325 @@ -0,0 +1,37 @@
25326 +#include <linux/kernel.h>
25327 +#include <linux/sched.h>
25328 +#include <linux/file.h>
25329 +#include <linux/fs.h>
25330 +#include <linux/grinternal.h>
25331 +
25332 +extern int gr_acl_tpe_check(void);
25333 +
25334 +int
25335 +gr_tpe_allow(const struct file *file)
25336 +{
25337 +#ifdef CONFIG_GRKERNSEC
25338 +       struct inode *inode = file->f_path.dentry->d_parent->d_inode;
25339 +
25340 +       if (current->uid && ((grsec_enable_tpe &&
25341 +#ifdef CONFIG_GRKERNSEC_TPE_INVERT
25342 +           !in_group_p(grsec_tpe_gid)
25343 +#else
25344 +           in_group_p(grsec_tpe_gid)
25345 +#endif
25346 +           ) || gr_acl_tpe_check()) &&
25347 +           (inode->i_uid || (!inode->i_uid && ((inode->i_mode & S_IWGRP) ||
25348 +                                               (inode->i_mode & S_IWOTH))))) {
25349 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
25350 +               return 0;
25351 +       }
25352 +#ifdef CONFIG_GRKERNSEC_TPE_ALL
25353 +       if (current->uid && grsec_enable_tpe && grsec_enable_tpe_all &&
25354 +           ((inode->i_uid && (inode->i_uid != current->uid)) ||
25355 +            (inode->i_mode & S_IWGRP) || (inode->i_mode & S_IWOTH))) {
25356 +               gr_log_fs_generic(GR_DONT_AUDIT, GR_EXEC_TPE_MSG, file->f_path.dentry, file->f_path.mnt);
25357 +               return 0;
25358 +       }
25359 +#endif
25360 +#endif
25361 +       return 1;
25362 +}
25363 diff -urNp linux-2.6.27.10/grsecurity/grsum.c linux-2.6.27.10/grsecurity/grsum.c
25364 --- linux-2.6.27.10/grsecurity/grsum.c  1969-12-31 19:00:00.000000000 -0500
25365 +++ linux-2.6.27.10/grsecurity/grsum.c  2008-11-18 03:38:45.000000000 -0500
25366 @@ -0,0 +1,59 @@
25367 +#include <linux/err.h>
25368 +#include <linux/kernel.h>
25369 +#include <linux/sched.h>
25370 +#include <linux/mm.h>
25371 +#include <linux/scatterlist.h>
25372 +#include <linux/crypto.h>
25373 +#include <linux/gracl.h>
25374 +
25375 +
25376 +#if !defined(CONFIG_CRYPTO) || defined(CONFIG_CRYPTO_MODULE) || !defined(CONFIG_CRYPTO_SHA256) || defined(CONFIG_CRYPTO_SHA256_MODULE)
25377 +#error "crypto and sha256 must be built into the kernel"
25378 +#endif
25379 +
25380 +int
25381 +chkpw(struct gr_arg *entry, unsigned char *salt, unsigned char *sum)
25382 +{
25383 +       char *p;
25384 +       struct crypto_hash *tfm;
25385 +       struct hash_desc desc;
25386 +       struct scatterlist sg;
25387 +       unsigned char temp_sum[GR_SHA_LEN];
25388 +       volatile int retval = 0;
25389 +       volatile int dummy = 0;
25390 +       unsigned int i;
25391 +
25392 +       tfm = crypto_alloc_hash("sha256", 0, CRYPTO_ALG_ASYNC);
25393 +       if (IS_ERR(tfm)) {
25394 +               /* should never happen, since sha256 should be built in */
25395 +               return 1;
25396 +       }
25397 +
25398 +       desc.tfm = tfm;
25399 +       desc.flags = 0;
25400 +
25401 +       crypto_hash_init(&desc);
25402 +
25403 +       p = salt;
25404 +       sg_set_buf(&sg, p, GR_SALT_LEN);
25405 +       crypto_hash_update(&desc, &sg, sg.length);
25406 +
25407 +       p = entry->pw;
25408 +       sg_set_buf(&sg, p, strlen(p));
25409 +       
25410 +       crypto_hash_update(&desc, &sg, sg.length);
25411 +
25412 +       crypto_hash_final(&desc, temp_sum);
25413 +
25414 +       memset(entry->pw, 0, GR_PW_LEN);
25415 +
25416 +       for (i = 0; i < GR_SHA_LEN; i++)
25417 +               if (sum[i] != temp_sum[i])
25418 +                       retval = 1;
25419 +               else
25420 +                       dummy = 1;      // waste a cycle
25421 +
25422 +       crypto_free_hash(tfm);
25423 +
25424 +       return retval;
25425 +}
25426 diff -urNp linux-2.6.27.10/grsecurity/Kconfig linux-2.6.27.10/grsecurity/Kconfig
25427 --- linux-2.6.27.10/grsecurity/Kconfig  1969-12-31 19:00:00.000000000 -0500
25428 +++ linux-2.6.27.10/grsecurity/Kconfig  2008-11-18 11:18:57.000000000 -0500
25429 @@ -0,0 +1,863 @@
25430 +#
25431 +# grecurity configuration
25432 +#
25433 +
25434 +menu "Grsecurity"
25435 +
25436 +config GRKERNSEC
25437 +       bool "Grsecurity"
25438 +       select CRYPTO
25439 +       select CRYPTO_SHA256
25440 +       select SECURITY
25441 +       select SECURITY_CAPABILITIES
25442 +       help
25443 +         If you say Y here, you will be able to configure many features
25444 +         that will enhance the security of your system.  It is highly
25445 +         recommended that you say Y here and read through the help
25446 +         for each option so that you fully understand the features and
25447 +         can evaluate their usefulness for your machine.
25448 +
25449 +choice
25450 +       prompt "Security Level"
25451 +       depends on GRKERNSEC
25452 +       default GRKERNSEC_CUSTOM
25453 +
25454 +config GRKERNSEC_LOW
25455 +       bool "Low"
25456 +       select GRKERNSEC_LINK
25457 +       select GRKERNSEC_FIFO
25458 +       select GRKERNSEC_EXECVE
25459 +       select GRKERNSEC_RANDNET
25460 +       select GRKERNSEC_DMESG
25461 +       select GRKERNSEC_CHROOT_CHDIR
25462 +       select GRKERNSEC_MODSTOP if (MODULES)
25463 +
25464 +       help
25465 +         If you choose this option, several of the grsecurity options will
25466 +         be enabled that will give you greater protection against a number
25467 +         of attacks, while assuring that none of your software will have any
25468 +         conflicts with the additional security measures.  If you run a lot
25469 +         of unusual software, or you are having problems with the higher
25470 +         security levels, you should say Y here.  With this option, the
25471 +         following features are enabled:
25472 +
25473 +         - Linking restrictions
25474 +         - FIFO restrictions
25475 +         - Enforcing RLIMIT_NPROC on execve
25476 +         - Restricted dmesg
25477 +         - Enforced chdir("/") on chroot
25478 +         - Runtime module disabling
25479 +
25480 +config GRKERNSEC_MEDIUM
25481 +       bool "Medium"
25482 +       select PAX
25483 +       select PAX_EI_PAX
25484 +       select PAX_PT_PAX_FLAGS
25485 +       select PAX_HAVE_ACL_FLAGS
25486 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25487 +       select GRKERNSEC_CHROOT_SYSCTL
25488 +       select GRKERNSEC_LINK
25489 +       select GRKERNSEC_FIFO
25490 +       select GRKERNSEC_EXECVE
25491 +       select GRKERNSEC_DMESG
25492 +       select GRKERNSEC_RANDNET
25493 +       select GRKERNSEC_FORKFAIL
25494 +       select GRKERNSEC_TIME
25495 +       select GRKERNSEC_SIGNAL
25496 +       select GRKERNSEC_CHROOT
25497 +       select GRKERNSEC_CHROOT_UNIX
25498 +       select GRKERNSEC_CHROOT_MOUNT
25499 +       select GRKERNSEC_CHROOT_PIVOT
25500 +       select GRKERNSEC_CHROOT_DOUBLE
25501 +       select GRKERNSEC_CHROOT_CHDIR
25502 +       select GRKERNSEC_CHROOT_MKNOD
25503 +       select GRKERNSEC_PROC
25504 +       select GRKERNSEC_PROC_USERGROUP
25505 +       select GRKERNSEC_MODSTOP if (MODULES)
25506 +       select PAX_RANDUSTACK
25507 +       select PAX_ASLR
25508 +       select PAX_RANDMMAP
25509 +       select PAX_REFCOUNT if (X86)
25510 +
25511 +       help
25512 +         If you say Y here, several features in addition to those included
25513 +         in the low additional security level will be enabled.  These
25514 +         features provide even more security to your system, though in rare
25515 +         cases they may be incompatible with very old or poorly written
25516 +         software.  If you enable this option, make sure that your auth
25517 +         service (identd) is running as gid 1001.  With this option, 
25518 +         the following features (in addition to those provided in the 
25519 +         low additional security level) will be enabled:
25520 +
25521 +         - Failed fork logging
25522 +         - Time change logging
25523 +         - Signal logging
25524 +         - Deny mounts in chroot
25525 +         - Deny double chrooting
25526 +         - Deny sysctl writes in chroot
25527 +         - Deny mknod in chroot
25528 +         - Deny access to abstract AF_UNIX sockets out of chroot
25529 +         - Deny pivot_root in chroot
25530 +         - Denied writes of /dev/kmem, /dev/mem, and /dev/port
25531 +         - /proc restrictions with special GID set to 10 (usually wheel)
25532 +         - Address Space Layout Randomization (ASLR)
25533 +
25534 +config GRKERNSEC_HIGH
25535 +       bool "High"
25536 +       select GRKERNSEC_LINK
25537 +       select GRKERNSEC_FIFO
25538 +       select GRKERNSEC_EXECVE
25539 +       select GRKERNSEC_DMESG
25540 +       select GRKERNSEC_FORKFAIL
25541 +       select GRKERNSEC_TIME
25542 +       select GRKERNSEC_SIGNAL
25543 +       select GRKERNSEC_CHROOT_SHMAT
25544 +       select GRKERNSEC_CHROOT_UNIX
25545 +       select GRKERNSEC_CHROOT_MOUNT
25546 +       select GRKERNSEC_CHROOT_FCHDIR
25547 +       select GRKERNSEC_CHROOT_PIVOT
25548 +       select GRKERNSEC_CHROOT_DOUBLE
25549 +       select GRKERNSEC_CHROOT_CHDIR
25550 +       select GRKERNSEC_CHROOT_MKNOD
25551 +       select GRKERNSEC_CHROOT_CAPS
25552 +       select GRKERNSEC_CHROOT_SYSCTL
25553 +       select GRKERNSEC_CHROOT_FINDTASK
25554 +       select GRKERNSEC_PROC
25555 +       select GRKERNSEC_PROC_MEMMAP if (PAX_NOEXEC || PAX_ASLR)
25556 +       select GRKERNSEC_HIDESYM
25557 +       select GRKERNSEC_BRUTE
25558 +       select GRKERNSEC_PROC_USERGROUP
25559 +       select GRKERNSEC_KMEM
25560 +       select GRKERNSEC_RESLOG
25561 +       select GRKERNSEC_RANDNET
25562 +       select GRKERNSEC_PROC_ADD
25563 +       select GRKERNSEC_CHROOT_CHMOD
25564 +       select GRKERNSEC_CHROOT_NICE
25565 +       select GRKERNSEC_AUDIT_MOUNT
25566 +       select GRKERNSEC_MODSTOP if (MODULES)
25567 +       select PAX
25568 +       select PAX_RANDUSTACK
25569 +       select PAX_ASLR
25570 +       select PAX_RANDMMAP
25571 +       select PAX_NOEXEC
25572 +       select PAX_MPROTECT
25573 +       select PAX_EI_PAX
25574 +       select PAX_PT_PAX_FLAGS
25575 +       select PAX_HAVE_ACL_FLAGS
25576 +       select PAX_KERNEXEC if (X86 && !EFI && !COMPAT_VDSO && !PARAVIRT && (!X86_32 || X86_WP_WORKS_OK))
25577 +       select PAX_MEMORY_UDEREF if (!X86_64 && !COMPAT_VDSO)
25578 +       select PAX_RANDKSTACK if (X86_TSC && !X86_64)
25579 +       select PAX_SEGMEXEC if (X86 && !X86_64)
25580 +       select PAX_PAGEEXEC if (!X86)
25581 +       select PAX_EMUPLT if (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
25582 +       select PAX_DLRESOLVE if (SPARC32 || SPARC64)
25583 +       select PAX_SYSCALL if (PPC32)
25584 +       select PAX_EMUTRAMP if (PARISC)
25585 +       select PAX_EMUSIGRT if (PARISC)
25586 +       select PAX_ETEXECRELOCS if (ALPHA || IA64 || PARISC)
25587 +       select PAX_REFCOUNT if (X86)
25588 +       help
25589 +         If you say Y here, many of the features of grsecurity will be
25590 +         enabled, which will protect you against many kinds of attacks
25591 +         against your system.  The heightened security comes at a cost
25592 +         of an increased chance of incompatibilities with rare software
25593 +         on your machine.  Since this security level enables PaX, you should
25594 +         view <http://pax.grsecurity.net> and read about the PaX
25595 +         project.  While you are there, download chpax and run it on
25596 +         binaries that cause problems with PaX.  Also remember that
25597 +         since the /proc restrictions are enabled, you must run your
25598 +         identd as gid 1001.  This security level enables the following 
25599 +         features in addition to those listed in the low and medium 
25600 +         security levels:
25601 +
25602 +         - Additional /proc restrictions
25603 +         - Chmod restrictions in chroot
25604 +         - No signals, ptrace, or viewing of processes outside of chroot
25605 +         - Capability restrictions in chroot
25606 +         - Deny fchdir out of chroot
25607 +         - Priority restrictions in chroot
25608 +         - Segmentation-based implementation of PaX
25609 +         - Mprotect restrictions
25610 +         - Removal of addresses from /proc/<pid>/[smaps|maps|stat]
25611 +         - Kernel stack randomization
25612 +         - Mount/unmount/remount logging
25613 +         - Kernel symbol hiding
25614 +         - Prevention of memory exhaustion-based exploits
25615 +config GRKERNSEC_CUSTOM
25616 +       bool "Custom"
25617 +       help
25618 +         If you say Y here, you will be able to configure every grsecurity
25619 +         option, which allows you to enable many more features that aren't
25620 +         covered in the basic security levels.  These additional features
25621 +         include TPE, socket restrictions, and the sysctl system for
25622 +         grsecurity.  It is advised that you read through the help for
25623 +         each option to determine its usefulness in your situation.
25624 +
25625 +endchoice
25626 +
25627 +menu "Address Space Protection"
25628 +depends on GRKERNSEC
25629 +
25630 +config GRKERNSEC_KMEM
25631 +       bool "Deny writing to /dev/kmem, /dev/mem, and /dev/port"
25632 +       help
25633 +         If you say Y here, /dev/kmem and /dev/mem won't be allowed to
25634 +         be written to via mmap or otherwise to modify the running kernel.
25635 +         /dev/port will also not be allowed to be opened. If you have module
25636 +         support disabled, enabling this will close up four ways that are
25637 +         currently used  to insert malicious code into the running kernel.
25638 +         Even with all these features enabled, we still highly recommend that
25639 +         you use the RBAC system, as it is still possible for an attacker to
25640 +         modify the running kernel through privileged I/O granted by ioperm/iopl.
25641 +         If you are not using XFree86, you may be able to stop this additional
25642 +         case by enabling the 'Disable privileged I/O' option. Though nothing
25643 +         legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem,
25644 +         but only to video memory, which is the only writing we allow in this
25645 +         case.  If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will
25646 +         not be allowed to mprotect it with PROT_WRITE later.
25647 +         It is highly recommended that you say Y here if you meet all the
25648 +         conditions above.
25649 +
25650 +config GRKERNSEC_IO
25651 +       bool "Disable privileged I/O"
25652 +       depends on X86
25653 +       select RTC
25654 +       help
25655 +         If you say Y here, all ioperm and iopl calls will return an error.
25656 +         Ioperm and iopl can be used to modify the running kernel.
25657 +         Unfortunately, some programs need this access to operate properly,
25658 +         the most notable of which are XFree86 and hwclock.  hwclock can be
25659 +         remedied by having RTC support in the kernel, so CONFIG_RTC is
25660 +         enabled if this option is enabled, to ensure that hwclock operates
25661 +         correctly.  XFree86 still will not operate correctly with this option
25662 +         enabled, so DO NOT CHOOSE Y IF YOU USE XFree86.  If you use XFree86
25663 +         and you still want to protect your kernel against modification,
25664 +         use the RBAC system.
25665 +
25666 +config GRKERNSEC_PROC_MEMMAP
25667 +       bool "Remove addresses from /proc/<pid>/[smaps|maps|stat]"
25668 +       depends on PAX_NOEXEC || PAX_ASLR
25669 +       help
25670 +         If you say Y here, the /proc/<pid>/maps and /proc/<pid>/stat files will
25671 +         give no information about the addresses of its mappings if
25672 +         PaX features that rely on random addresses are enabled on the task.
25673 +         If you use PaX it is greatly recommended that you say Y here as it
25674 +         closes up a hole that makes the full ASLR useless for suid
25675 +         binaries.
25676 +
25677 +config GRKERNSEC_BRUTE
25678 +       bool "Deter exploit bruteforcing"
25679 +       help
25680 +         If you say Y here, attempts to bruteforce exploits against forking
25681 +         daemons such as apache or sshd will be deterred.  When a child of a
25682 +         forking daemon is killed by PaX or crashes due to an illegal
25683 +         instruction, the parent process will be delayed 30 seconds upon every
25684 +         subsequent fork until the administrator is able to assess the
25685 +         situation and restart the daemon.  It is recommended that you also
25686 +         enable signal logging in the auditing section so that logs are
25687 +         generated when a process performs an illegal instruction.
25688 +
25689 +config GRKERNSEC_MODSTOP
25690 +       bool "Runtime module disabling"
25691 +       depends on MODULES
25692 +       help
25693 +         If you say Y here, you will be able to disable the ability to (un)load
25694 +         modules at runtime.  This feature is useful if you need the ability
25695 +         to load kernel modules at boot time, but do not want to allow an
25696 +         attacker to load a rootkit kernel module into the system, or to remove
25697 +         a loaded kernel module important to system functioning.  You should
25698 +         enable the /dev/mem protection feature as well, since rootkits can be
25699 +         inserted into the kernel via other methods than kernel modules.  Since
25700 +         an untrusted module could still be loaded by modifying init scripts and
25701 +         rebooting the system, it is also recommended that you enable the RBAC
25702 +         system.  If you enable this option, a sysctl option with name
25703 +         "disable_modules" will be created.  Setting this option to "1" disables
25704 +         module loading.  After this option is set, no further writes to it are
25705 +         allowed until the system is rebooted.
25706 +
25707 +config GRKERNSEC_HIDESYM
25708 +       bool "Hide kernel symbols"
25709 +       help
25710 +         If you say Y here, getting information on loaded modules, and
25711 +         displaying all kernel symbols through a syscall will be restricted
25712 +         to users with CAP_SYS_MODULE.  This option is only effective
25713 +         provided the following conditions are met:
25714 +         1) The kernel using grsecurity is not precompiled by some distribution
25715 +         2) You are using the RBAC system and hiding other files such as your
25716 +            kernel image and System.map
25717 +         3) You have the additional /proc restrictions enabled, which removes
25718 +            /proc/kcore
25719 +         If the above conditions are met, this option will aid to provide a
25720 +         useful protection against local and remote kernel exploitation of
25721 +         overflows and arbitrary read/write vulnerabilities.
25722 +
25723 +endmenu
25724 +menu "Role Based Access Control Options"
25725 +depends on GRKERNSEC
25726 +
25727 +config GRKERNSEC_ACL_HIDEKERN
25728 +       bool "Hide kernel processes"
25729 +       help
25730 +         If you say Y here, all kernel threads will be hidden to all
25731 +         processes but those whose subject has the "view hidden processes"
25732 +         flag.
25733 +
25734 +config GRKERNSEC_ACL_MAXTRIES
25735 +       int "Maximum tries before password lockout"
25736 +       default 3
25737 +       help
25738 +         This option enforces the maximum number of times a user can attempt
25739 +         to authorize themselves with the grsecurity RBAC system before being
25740 +         denied the ability to attempt authorization again for a specified time.
25741 +         The lower the number, the harder it will be to brute-force a password.
25742 +
25743 +config GRKERNSEC_ACL_TIMEOUT
25744 +       int "Time to wait after max password tries, in seconds"
25745 +       default 30
25746 +       help
25747 +         This option specifies the time the user must wait after attempting to
25748 +         authorize to the RBAC system with the maximum number of invalid
25749 +         passwords.  The higher the number, the harder it will be to brute-force
25750 +         a password.
25751 +
25752 +endmenu
25753 +menu "Filesystem Protections"
25754 +depends on GRKERNSEC
25755 +
25756 +config GRKERNSEC_PROC
25757 +       bool "Proc restrictions"
25758 +       help
25759 +         If you say Y here, the permissions of the /proc filesystem
25760 +         will be altered to enhance system security and privacy.  You MUST
25761 +         choose either a user only restriction or a user and group restriction.
25762 +         Depending upon the option you choose, you can either restrict users to
25763 +         see only the processes they themselves run, or choose a group that can
25764 +         view all processes and files normally restricted to root if you choose
25765 +         the "restrict to user only" option.  NOTE: If you're running identd as
25766 +         a non-root user, you will have to run it as the group you specify here.
25767 +
25768 +config GRKERNSEC_PROC_USER
25769 +       bool "Restrict /proc to user only"
25770 +       depends on GRKERNSEC_PROC
25771 +       help
25772 +         If you say Y here, non-root users will only be able to view their own
25773 +         processes, and restricts them from viewing network-related information,
25774 +         and viewing kernel symbol and module information.
25775 +
25776 +config GRKERNSEC_PROC_USERGROUP
25777 +       bool "Allow special group"
25778 +       depends on GRKERNSEC_PROC && !GRKERNSEC_PROC_USER
25779 +       help
25780 +         If you say Y here, you will be able to select a group that will be
25781 +         able to view all processes, network-related information, and
25782 +         kernel and symbol information.  This option is useful if you want
25783 +         to run identd as a non-root user.
25784 +
25785 +config GRKERNSEC_PROC_GID
25786 +       int "GID for special group"
25787 +       depends on GRKERNSEC_PROC_USERGROUP
25788 +       default 1001
25789 +
25790 +config GRKERNSEC_PROC_ADD
25791 +       bool "Additional restrictions"
25792 +       depends on GRKERNSEC_PROC_USER || GRKERNSEC_PROC_USERGROUP
25793 +       help
25794 +         If you say Y here, additional restrictions will be placed on
25795 +         /proc that keep normal users from viewing device information and 
25796 +         slabinfo information that could be useful for exploits.
25797 +
25798 +config GRKERNSEC_LINK
25799 +       bool "Linking restrictions"
25800 +       help
25801 +         If you say Y here, /tmp race exploits will be prevented, since users
25802 +         will no longer be able to follow symlinks owned by other users in
25803 +         world-writable +t directories (i.e. /tmp), unless the owner of the
25804 +         symlink is the owner of the directory. users will also not be
25805 +         able to hardlink to files they do not own.  If the sysctl option is
25806 +         enabled, a sysctl option with name "linking_restrictions" is created.
25807 +
25808 +config GRKERNSEC_FIFO
25809 +       bool "FIFO restrictions"
25810 +       help
25811 +         If you say Y here, users will not be able to write to FIFOs they don't
25812 +         own in world-writable +t directories (i.e. /tmp), unless the owner of
25813 +         the FIFO is the same owner of the directory it's held in.  If the sysctl
25814 +         option is enabled, a sysctl option with name "fifo_restrictions" is
25815 +         created.
25816 +
25817 +config GRKERNSEC_CHROOT
25818 +       bool "Chroot jail restrictions"
25819 +       help
25820 +         If you say Y here, you will be able to choose several options that will
25821 +         make breaking out of a chrooted jail much more difficult.  If you
25822 +         encounter no software incompatibilities with the following options, it
25823 +         is recommended that you enable each one.
25824 +
25825 +config GRKERNSEC_CHROOT_MOUNT
25826 +       bool "Deny mounts"
25827 +       depends on GRKERNSEC_CHROOT
25828 +       help
25829 +         If you say Y here, processes inside a chroot will not be able to
25830 +         mount or remount filesystems.  If the sysctl option is enabled, a
25831 +         sysctl option with name "chroot_deny_mount" is created.
25832 +
25833 +config GRKERNSEC_CHROOT_DOUBLE
25834 +       bool "Deny double-chroots"
25835 +       depends on GRKERNSEC_CHROOT
25836 +       help
25837 +         If you say Y here, processes inside a chroot will not be able to chroot
25838 +         again outside the chroot.  This is a widely used method of breaking
25839 +         out of a chroot jail and should not be allowed.  If the sysctl 
25840 +         option is enabled, a sysctl option with name 
25841 +         "chroot_deny_chroot" is created.
25842 +
25843 +config GRKERNSEC_CHROOT_PIVOT
25844 +       bool "Deny pivot_root in chroot"
25845 +       depends on GRKERNSEC_CHROOT
25846 +       help
25847 +         If you say Y here, processes inside a chroot will not be able to use
25848 +         a function called pivot_root() that was introduced in Linux 2.3.41.  It
25849 +         works similar to chroot in that it changes the root filesystem.  This
25850 +         function could be misused in a chrooted process to attempt to break out
25851 +         of the chroot, and therefore should not be allowed.  If the sysctl
25852 +         option is enabled, a sysctl option with name "chroot_deny_pivot" is
25853 +         created.
25854 +
25855 +config GRKERNSEC_CHROOT_CHDIR
25856 +       bool "Enforce chdir(\"/\") on all chroots"
25857 +       depends on GRKERNSEC_CHROOT
25858 +       help
25859 +         If you say Y here, the current working directory of all newly-chrooted
25860 +         applications will be set to the the root directory of the chroot.
25861 +         The man page on chroot(2) states:
25862 +         Note that this call does not change  the  current  working
25863 +         directory,  so  that `.' can be outside the tree rooted at
25864 +         `/'.  In particular, the  super-user  can  escape  from  a
25865 +         `chroot jail' by doing `mkdir foo; chroot foo; cd ..'.
25866 +
25867 +         It is recommended that you say Y here, since it's not known to break
25868 +         any software.  If the sysctl option is enabled, a sysctl option with
25869 +         name "chroot_enforce_chdir" is created.
25870 +
25871 +config GRKERNSEC_CHROOT_CHMOD
25872 +       bool "Deny (f)chmod +s"
25873 +       depends on GRKERNSEC_CHROOT
25874 +       help
25875 +         If you say Y here, processes inside a chroot will not be able to chmod
25876 +         or fchmod files to make them have suid or sgid bits.  This protects
25877 +         against another published method of breaking a chroot.  If the sysctl
25878 +         option is enabled, a sysctl option with name "chroot_deny_chmod" is
25879 +         created.
25880 +
25881 +config GRKERNSEC_CHROOT_FCHDIR
25882 +       bool "Deny fchdir out of chroot"
25883 +       depends on GRKERNSEC_CHROOT
25884 +       help
25885 +         If you say Y here, a well-known method of breaking chroots by fchdir'ing
25886 +         to a file descriptor of the chrooting process that points to a directory
25887 +         outside the filesystem will be stopped.  If the sysctl option
25888 +         is enabled, a sysctl option with name "chroot_deny_fchdir" is created.
25889 +
25890 +config GRKERNSEC_CHROOT_MKNOD
25891 +       bool "Deny mknod"
25892 +       depends on GRKERNSEC_CHROOT
25893 +       help
25894 +         If you say Y here, processes inside a chroot will not be allowed to
25895 +         mknod.  The problem with using mknod inside a chroot is that it
25896 +         would allow an attacker to create a device entry that is the same
25897 +         as one on the physical root of your system, which could range from
25898 +         anything from the console device to a device for your harddrive (which
25899 +         they could then use to wipe the drive or steal data).  It is recommended
25900 +         that you say Y here, unless you run into software incompatibilities.
25901 +         If the sysctl option is enabled, a sysctl option with name
25902 +         "chroot_deny_mknod" is created.
25903 +
25904 +config GRKERNSEC_CHROOT_SHMAT
25905 +       bool "Deny shmat() out of chroot"
25906 +       depends on GRKERNSEC_CHROOT
25907 +       help
25908 +         If you say Y here, processes inside a chroot will not be able to attach
25909 +         to shared memory segments that were created outside of the chroot jail.
25910 +         It is recommended that you say Y here.  If the sysctl option is enabled,
25911 +         a sysctl option with name "chroot_deny_shmat" is created.
25912 +
25913 +config GRKERNSEC_CHROOT_UNIX
25914 +       bool "Deny access to abstract AF_UNIX sockets out of chroot"
25915 +       depends on GRKERNSEC_CHROOT
25916 +       help
25917 +         If you say Y here, processes inside a chroot will not be able to
25918 +         connect to abstract (meaning not belonging to a filesystem) Unix
25919 +         domain sockets that were bound outside of a chroot.  It is recommended
25920 +         that you say Y here.  If the sysctl option is enabled, a sysctl option
25921 +         with name "chroot_deny_unix" is created.
25922 +
25923 +config GRKERNSEC_CHROOT_FINDTASK
25924 +       bool "Protect outside processes"
25925 +       depends on GRKERNSEC_CHROOT
25926 +       help
25927 +         If you say Y here, processes inside a chroot will not be able to
25928 +         kill, send signals with fcntl, ptrace, capget, getpgid, getsid,
25929 +         or view any process outside of the chroot.  If the sysctl
25930 +         option is enabled, a sysctl option with name "chroot_findtask" is
25931 +         created.
25932 +
25933 +config GRKERNSEC_CHROOT_NICE
25934 +       bool "Restrict priority changes"
25935 +       depends on GRKERNSEC_CHROOT
25936 +       help
25937 +         If you say Y here, processes inside a chroot will not be able to raise
25938 +         the priority of processes in the chroot, or alter the priority of
25939 +         processes outside the chroot.  This provides more security than simply
25940 +         removing CAP_SYS_NICE from the process' capability set.  If the
25941 +         sysctl option is enabled, a sysctl option with name "chroot_restrict_nice"
25942 +         is created.
25943 +
25944 +config GRKERNSEC_CHROOT_SYSCTL
25945 +       bool "Deny sysctl writes"
25946 +       depends on GRKERNSEC_CHROOT
25947 +       help
25948 +         If you say Y here, an attacker in a chroot will not be able to
25949 +         write to sysctl entries, either by sysctl(2) or through a /proc
25950 +         interface.  It is strongly recommended that you say Y here. If the
25951 +         sysctl option is enabled, a sysctl option with name
25952 +         "chroot_deny_sysctl" is created.
25953 +
25954 +config GRKERNSEC_CHROOT_CAPS
25955 +       bool "Capability restrictions"
25956 +       depends on GRKERNSEC_CHROOT
25957 +       help
25958 +         If you say Y here, the capabilities on all root processes within a
25959 +         chroot jail will be lowered to stop module insertion, raw i/o,
25960 +         system and net admin tasks, rebooting the system, modifying immutable
25961 +         files, modifying IPC owned by another, and changing the system time.
25962 +         This is left an option because it can break some apps.  Disable this
25963 +         if your chrooted apps are having problems performing those kinds of
25964 +         tasks.  If the sysctl option is enabled, a sysctl option with
25965 +         name "chroot_caps" is created.
25966 +
25967 +endmenu
25968 +menu "Kernel Auditing"
25969 +depends on GRKERNSEC
25970 +
25971 +config GRKERNSEC_AUDIT_GROUP
25972 +       bool "Single group for auditing"
25973 +       help
25974 +         If you say Y here, the exec, chdir, (un)mount, and ipc logging features
25975 +         will only operate on a group you specify.  This option is recommended
25976 +         if you only want to watch certain users instead of having a large
25977 +         amount of logs from the entire system.  If the sysctl option is enabled,
25978 +         a sysctl option with name "audit_group" is created.
25979 +
25980 +config GRKERNSEC_AUDIT_GID
25981 +       int "GID for auditing"
25982 +       depends on GRKERNSEC_AUDIT_GROUP
25983 +       default 1007
25984 +
25985 +config GRKERNSEC_EXECLOG
25986 +       bool "Exec logging"
25987 +       help
25988 +         If you say Y here, all execve() calls will be logged (since the
25989 +         other exec*() calls are frontends to execve(), all execution
25990 +         will be logged).  Useful for shell-servers that like to keep track
25991 +         of their users.  If the sysctl option is enabled, a sysctl option with
25992 +         name "exec_logging" is created.
25993 +         WARNING: This option when enabled will produce a LOT of logs, especially
25994 +         on an active system.
25995 +
25996 +config GRKERNSEC_RESLOG
25997 +       bool "Resource logging"
25998 +       help
25999 +         If you say Y here, all attempts to overstep resource limits will
26000 +         be logged with the resource name, the requested size, and the current
26001 +         limit.  It is highly recommended that you say Y here.  If the sysctl
26002 +         option is enabled, a sysctl option with name "resource_logging" is
26003 +         created.  If the RBAC system is enabled, the sysctl value is ignored.
26004 +
26005 +config GRKERNSEC_CHROOT_EXECLOG
26006 +       bool "Log execs within chroot"
26007 +       help
26008 +         If you say Y here, all executions inside a chroot jail will be logged
26009 +         to syslog.  This can cause a large amount of logs if certain
26010 +         applications (eg. djb's daemontools) are installed on the system, and
26011 +         is therefore left as an option.  If the sysctl option is enabled, a
26012 +         sysctl option with name "chroot_execlog" is created.
26013 +
26014 +config GRKERNSEC_AUDIT_CHDIR
26015 +       bool "Chdir logging"
26016 +       help
26017 +         If you say Y here, all chdir() calls will be logged.  If the sysctl
26018 +         option is enabled, a sysctl option with name "audit_chdir" is created.
26019 +
26020 +config GRKERNSEC_AUDIT_MOUNT
26021 +       bool "(Un)Mount logging"
26022 +       help
26023 +         If you say Y here, all mounts and unmounts will be logged.  If the
26024 +         sysctl option is enabled, a sysctl option with name "audit_mount" is
26025 +         created.
26026 +
26027 +config GRKERNSEC_AUDIT_IPC
26028 +       bool "IPC logging"
26029 +       help
26030 +         If you say Y here, creation and removal of message queues, semaphores,
26031 +         and shared memory will be logged.  If the sysctl option is enabled, a
26032 +         sysctl option with name "audit_ipc" is created.
26033 +
26034 +config GRKERNSEC_SIGNAL
26035 +       bool "Signal logging"
26036 +       help
26037 +         If you say Y here, certain important signals will be logged, such as
26038 +         SIGSEGV, which will as a result inform you of when a error in a program
26039 +         occurred, which in some cases could mean a possible exploit attempt.
26040 +         If the sysctl option is enabled, a sysctl option with name
26041 +         "signal_logging" is created.
26042 +
26043 +config GRKERNSEC_FORKFAIL
26044 +       bool "Fork failure logging"
26045 +       help
26046 +         If you say Y here, all failed fork() attempts will be logged.
26047 +         This could suggest a fork bomb, or someone attempting to overstep
26048 +         their process limit.  If the sysctl option is enabled, a sysctl option
26049 +         with name "forkfail_logging" is created.
26050 +
26051 +config GRKERNSEC_TIME
26052 +       bool "Time change logging"
26053 +       help
26054 +         If you say Y here, any changes of the system clock will be logged.
26055 +         If the sysctl option is enabled, a sysctl option with name
26056 +         "timechange_logging" is created.
26057 +
26058 +config GRKERNSEC_PROC_IPADDR
26059 +       bool "/proc/<pid>/ipaddr support"
26060 +       help
26061 +         If you say Y here, a new entry will be added to each /proc/<pid>
26062 +         directory that contains the IP address of the person using the task.
26063 +         The IP is carried across local TCP and AF_UNIX stream sockets.
26064 +         This information can be useful for IDS/IPSes to perform remote response
26065 +         to a local attack.  The entry is readable by only the owner of the
26066 +         process (and root if he has CAP_DAC_OVERRIDE, which can be removed via
26067 +         the RBAC system), and thus does not create privacy concerns.
26068 +
26069 +config GRKERNSEC_AUDIT_TEXTREL
26070 +       bool 'ELF text relocations logging (READ HELP)'
26071 +       depends on PAX_MPROTECT
26072 +       help
26073 +         If you say Y here, text relocations will be logged with the filename
26074 +         of the offending library or binary.  The purpose of the feature is
26075 +         to help Linux distribution developers get rid of libraries and
26076 +         binaries that need text relocations which hinder the future progress
26077 +         of PaX.  Only Linux distribution developers should say Y here, and
26078 +         never on a production machine, as this option creates an information
26079 +         leak that could aid an attacker in defeating the randomization of
26080 +         a single memory region.  If the sysctl option is enabled, a sysctl
26081 +         option with name "audit_textrel" is created.
26082 +
26083 +endmenu
26084 +
26085 +menu "Executable Protections"
26086 +depends on GRKERNSEC
26087 +
26088 +config GRKERNSEC_EXECVE
26089 +       bool "Enforce RLIMIT_NPROC on execs"
26090 +       help
26091 +         If you say Y here, users with a resource limit on processes will
26092 +         have the value checked during execve() calls.  The current system
26093 +         only checks the system limit during fork() calls.  If the sysctl option
26094 +         is enabled, a sysctl option with name "execve_limiting" is created.
26095 +
26096 +config GRKERNSEC_DMESG
26097 +       bool "Dmesg(8) restriction"
26098 +       help
26099 +         If you say Y here, non-root users will not be able to use dmesg(8)
26100 +         to view up to the last 4kb of messages in the kernel's log buffer.
26101 +         If the sysctl option is enabled, a sysctl option with name "dmesg" is
26102 +         created.
26103 +
26104 +config GRKERNSEC_TPE
26105 +       bool "Trusted Path Execution (TPE)"
26106 +       help
26107 +         If you say Y here, you will be able to choose a gid to add to the
26108 +         supplementary groups of users you want to mark as "untrusted."
26109 +         These users will not be able to execute any files that are not in
26110 +         root-owned directories writable only by root.  If the sysctl option
26111 +         is enabled, a sysctl option with name "tpe" is created.
26112 +
26113 +config GRKERNSEC_TPE_ALL
26114 +       bool "Partially restrict non-root users"
26115 +       depends on GRKERNSEC_TPE
26116 +       help
26117 +         If you say Y here, All non-root users other than the ones in the
26118 +         group specified in the main TPE option will only be allowed to
26119 +         execute files in directories they own that are not group or
26120 +         world-writable, or in directories owned by root and writable only by
26121 +         root.  If the sysctl option is enabled, a sysctl option with name
26122 +         "tpe_restrict_all" is created.
26123 +
26124 +config GRKERNSEC_TPE_INVERT
26125 +       bool "Invert GID option"
26126 +       depends on GRKERNSEC_TPE
26127 +       help
26128 +         If you say Y here, the group you specify in the TPE configuration will
26129 +         decide what group TPE restrictions will be *disabled* for.  This
26130 +         option is useful if you want TPE restrictions to be applied to most
26131 +         users on the system.
26132 +
26133 +config GRKERNSEC_TPE_GID
26134 +       int "GID for untrusted users"
26135 +       depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT
26136 +       default 1005
26137 +       help
26138 +         If you have selected the "Invert GID option" above, setting this
26139 +         GID determines what group TPE restrictions will be *disabled* for.
26140 +         If you have not selected the "Invert GID option" above, setting this
26141 +         GID determines what group TPE restrictions will be *enabled* for.
26142 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
26143 +         is created.
26144 +
26145 +config GRKERNSEC_TPE_GID
26146 +       int "GID for trusted users"
26147 +       depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT
26148 +       default 1005
26149 +       help
26150 +         If you have selected the "Invert GID option" above, setting this
26151 +         GID determines what group TPE restrictions will be *disabled* for.
26152 +         If you have not selected the "Invert GID option" above, setting this
26153 +         GID determines what group TPE restrictions will be *enabled* for.
26154 +         If the sysctl option is enabled, a sysctl option with name "tpe_gid"
26155 +         is created.
26156 +
26157 +endmenu
26158 +menu "Network Protections"
26159 +depends on GRKERNSEC
26160 +
26161 +config GRKERNSEC_RANDNET
26162 +       bool "Larger entropy pools"
26163 +       help
26164 +         If you say Y here, the entropy pools used for many features of Linux
26165 +         and grsecurity will be doubled in size.  Since several grsecurity
26166 +         features use additional randomness, it is recommended that you say Y
26167 +         here.  Saying Y here has a similar effect as modifying
26168 +         /proc/sys/kernel/random/poolsize.
26169 +
26170 +config GRKERNSEC_SOCKET
26171 +       bool "Socket restrictions"
26172 +       help
26173 +         If you say Y here, you will be able to choose from several options.
26174 +         If you assign a GID on your system and add it to the supplementary
26175 +         groups of users you want to restrict socket access to, this patch
26176 +         will perform up to three things, based on the option(s) you choose.
26177 +
26178 +config GRKERNSEC_SOCKET_ALL
26179 +       bool "Deny any sockets to group"
26180 +       depends on GRKERNSEC_SOCKET
26181 +       help
26182 +         If you say Y here, you will be able to choose a GID of whose users will
26183 +         be unable to connect to other hosts from your machine or run server
26184 +         applications from your machine.  If the sysctl option is enabled, a
26185 +         sysctl option with name "socket_all" is created.
26186 +
26187 +config GRKERNSEC_SOCKET_ALL_GID
26188 +       int "GID to deny all sockets for"
26189 +       depends on GRKERNSEC_SOCKET_ALL
26190 +       default 1004
26191 +       help
26192 +         Here you can choose the GID to disable socket access for. Remember to
26193 +         add the users you want socket access disabled for to the GID
26194 +         specified here.  If the sysctl option is enabled, a sysctl option
26195 +         with name "socket_all_gid" is created.
26196 +
26197 +config GRKERNSEC_SOCKET_CLIENT
26198 +       bool "Deny client sockets to group"
26199 +       depends on GRKERNSEC_SOCKET
26200 +       help
26201 +         If you say Y here, you will be able to choose a GID of whose users will
26202 +         be unable to connect to other hosts from your machine, but will be
26203 +         able to run servers.  If this option is enabled, all users in the group
26204 +         you specify will have to use passive mode when initiating ftp transfers
26205 +         from the shell on your machine.  If the sysctl option is enabled, a
26206 +         sysctl option with name "socket_client" is created.
26207 +
26208 +config GRKERNSEC_SOCKET_CLIENT_GID
26209 +       int "GID to deny client sockets for"
26210 +       depends on GRKERNSEC_SOCKET_CLIENT
26211 +       default 1003
26212 +       help
26213 +         Here you can choose the GID to disable client socket access for.
26214 +         Remember to add the users you want client socket access disabled for to
26215 +         the GID specified here.  If the sysctl option is enabled, a sysctl
26216 +         option with name "socket_client_gid" is created.
26217 +
26218 +config GRKERNSEC_SOCKET_SERVER
26219 +       bool "Deny server sockets to group"
26220 +       depends on GRKERNSEC_SOCKET
26221 +       help
26222 +         If you say Y here, you will be able to choose a GID of whose users will
26223 +         be unable to run server applications from your machine.  If the sysctl
26224 +         option is enabled, a sysctl option with name "socket_server" is created.
26225 +
26226 +config GRKERNSEC_SOCKET_SERVER_GID
26227 +       int "GID to deny server sockets for"
26228 +       depends on GRKERNSEC_SOCKET_SERVER
26229 +       default 1002
26230 +       help
26231 +         Here you can choose the GID to disable server socket access for.
26232 +         Remember to add the users you want server socket access disabled for to
26233 +         the GID specified here.  If the sysctl option is enabled, a sysctl
26234 +         option with name "socket_server_gid" is created.
26235 +
26236 +endmenu
26237 +menu "Sysctl support"
26238 +depends on GRKERNSEC && SYSCTL
26239 +
26240 +config GRKERNSEC_SYSCTL
26241 +       bool "Sysctl support"
26242 +       help
26243 +         If you say Y here, you will be able to change the options that
26244 +         grsecurity runs with at bootup, without having to recompile your
26245 +         kernel.  You can echo values to files in /proc/sys/kernel/grsecurity
26246 +         to enable (1) or disable (0) various features.  All the sysctl entries
26247 +         are mutable until the "grsec_lock" entry is set to a non-zero value.
26248 +         All features enabled in the kernel configuration are disabled at boot
26249 +         if you do not say Y to the "Turn on features by default" option.
26250 +         All options should be set at startup, and the grsec_lock entry should
26251 +         be set to a non-zero value after all the options are set.
26252 +         *THIS IS EXTREMELY IMPORTANT*
26253 +
26254 +config GRKERNSEC_SYSCTL_ON
26255 +       bool "Turn on features by default"
26256 +       depends on GRKERNSEC_SYSCTL
26257 +       help
26258 +         If you say Y here, instead of having all features enabled in the
26259 +         kernel configuration disabled at boot time, the features will be
26260 +         enabled at boot time.  It is recommended you say Y here unless
26261 +         there is some reason you would want all sysctl-tunable features to
26262 +         be disabled by default.  As mentioned elsewhere, it is important
26263 +         to enable the grsec_lock entry once you have finished modifying
26264 +         the sysctl entries.
26265 +
26266 +endmenu
26267 +menu "Logging Options"
26268 +depends on GRKERNSEC
26269 +
26270 +config GRKERNSEC_FLOODTIME
26271 +       int "Seconds in between log messages (minimum)"
26272 +       default 10
26273 +       help
26274 +         This option allows you to enforce the number of seconds between
26275 +         grsecurity log messages.  The default should be suitable for most
26276 +         people, however, if you choose to change it, choose a value small enough
26277 +         to allow informative logs to be produced, but large enough to
26278 +         prevent flooding.
26279 +
26280 +config GRKERNSEC_FLOODBURST
26281 +       int "Number of messages in a burst (maximum)"
26282 +       default 4
26283 +       help
26284 +         This option allows you to choose the maximum number of messages allowed
26285 +         within the flood time interval you chose in a separate option.  The
26286 +         default should be suitable for most people, however if you find that
26287 +         many of your logs are being interpreted as flooding, you may want to
26288 +         raise this value.
26289 +
26290 +endmenu
26291 +
26292 +endmenu
26293 diff -urNp linux-2.6.27.10/grsecurity/Makefile linux-2.6.27.10/grsecurity/Makefile
26294 --- linux-2.6.27.10/grsecurity/Makefile 1969-12-31 19:00:00.000000000 -0500
26295 +++ linux-2.6.27.10/grsecurity/Makefile 2008-11-18 03:38:45.000000000 -0500
26296 @@ -0,0 +1,20 @@
26297 +# grsecurity's ACL system was originally written in 2001 by Michael Dalton
26298 +# during 2001-2005 it has been completely redesigned by Brad Spengler
26299 +# into an RBAC system
26300 +#
26301 +# All code in this directory and various hooks inserted throughout the kernel
26302 +# are copyright Brad Spengler, and released under the GPL v2 or higher
26303 +
26304 +obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
26305 +       grsec_mount.o grsec_sig.o grsec_sock.o grsec_sysctl.o \
26306 +       grsec_time.o grsec_tpe.o grsec_ipc.o grsec_link.o grsec_textrel.o
26307 +
26308 +obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_ip.o gracl_segv.o \
26309 +       gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
26310 +       gracl_learn.o grsec_log.o
26311 +obj-$(CONFIG_GRKERNSEC_RESLOG) += gracl_res.o
26312 +
26313 +ifndef CONFIG_GRKERNSEC
26314 +obj-y += grsec_disabled.o
26315 +endif
26316 +
26317 diff -urNp linux-2.6.27.10/include/asm-cris/kmap_types.h linux-2.6.27.10/include/asm-cris/kmap_types.h
26318 --- linux-2.6.27.10/include/asm-cris/kmap_types.h       2008-11-07 12:55:34.000000000 -0500
26319 +++ linux-2.6.27.10/include/asm-cris/kmap_types.h       2008-11-18 03:38:45.000000000 -0500
26320 @@ -19,6 +19,7 @@ enum km_type {
26321         KM_IRQ1,
26322         KM_SOFTIRQ0,
26323         KM_SOFTIRQ1,
26324 +       KM_CLEARPAGE,
26325         KM_TYPE_NR
26326  };
26327  
26328 diff -urNp linux-2.6.27.10/include/asm-frv/kmap_types.h linux-2.6.27.10/include/asm-frv/kmap_types.h
26329 --- linux-2.6.27.10/include/asm-frv/kmap_types.h        2008-11-07 12:55:34.000000000 -0500
26330 +++ linux-2.6.27.10/include/asm-frv/kmap_types.h        2008-11-18 03:38:45.000000000 -0500
26331 @@ -23,6 +23,7 @@ enum km_type {
26332         KM_IRQ1,
26333         KM_SOFTIRQ0,
26334         KM_SOFTIRQ1,
26335 +       KM_CLEARPAGE,
26336         KM_TYPE_NR
26337  };
26338  
26339 diff -urNp linux-2.6.27.10/include/asm-generic/futex.h linux-2.6.27.10/include/asm-generic/futex.h
26340 --- linux-2.6.27.10/include/asm-generic/futex.h 2008-11-07 12:55:34.000000000 -0500
26341 +++ linux-2.6.27.10/include/asm-generic/futex.h 2008-11-18 03:38:45.000000000 -0500
26342 @@ -6,7 +6,7 @@
26343  #include <asm/errno.h>
26344  
26345  static inline int
26346 -futex_atomic_op_inuser (int encoded_op, int __user *uaddr)
26347 +futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
26348  {
26349         int op = (encoded_op >> 28) & 7;
26350         int cmp = (encoded_op >> 24) & 15;
26351 @@ -48,7 +48,7 @@ futex_atomic_op_inuser (int encoded_op, 
26352  }
26353  
26354  static inline int
26355 -futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
26356 +futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval, int newval)
26357  {
26358         return -ENOSYS;
26359  }
26360 diff -urNp linux-2.6.27.10/include/asm-generic/vmlinux.lds.h linux-2.6.27.10/include/asm-generic/vmlinux.lds.h
26361 --- linux-2.6.27.10/include/asm-generic/vmlinux.lds.h   2008-11-07 12:55:34.000000000 -0500
26362 +++ linux-2.6.27.10/include/asm-generic/vmlinux.lds.h   2008-11-18 03:38:45.000000000 -0500
26363 @@ -59,6 +59,7 @@
26364         .rodata           : AT(ADDR(.rodata) - LOAD_OFFSET) {           \
26365                 VMLINUX_SYMBOL(__start_rodata) = .;                     \
26366                 *(.rodata) *(.rodata.*)                                 \
26367 +               *(.data.read_only)                                      \
26368                 *(__vermagic)           /* Kernel version magic */      \
26369                 *(__markers_strings)    /* Markers: strings */          \
26370         }                                                               \
26371 diff -urNp linux-2.6.27.10/include/asm-m32r/kmap_types.h linux-2.6.27.10/include/asm-m32r/kmap_types.h
26372 --- linux-2.6.27.10/include/asm-m32r/kmap_types.h       2008-11-07 12:55:34.000000000 -0500
26373 +++ linux-2.6.27.10/include/asm-m32r/kmap_types.h       2008-11-18 03:38:45.000000000 -0500
26374 @@ -21,7 +21,8 @@ D(9)  KM_IRQ0,
26375  D(10)  KM_IRQ1,
26376  D(11)  KM_SOFTIRQ0,
26377  D(12)  KM_SOFTIRQ1,
26378 -D(13)  KM_TYPE_NR
26379 +D(13)  KM_CLEARPAGE,
26380 +D(14)  KM_TYPE_NR
26381  };
26382  
26383  #undef D
26384 diff -urNp linux-2.6.27.10/include/asm-m68k/kmap_types.h linux-2.6.27.10/include/asm-m68k/kmap_types.h
26385 --- linux-2.6.27.10/include/asm-m68k/kmap_types.h       2008-11-07 12:55:34.000000000 -0500
26386 +++ linux-2.6.27.10/include/asm-m68k/kmap_types.h       2008-11-18 03:38:45.000000000 -0500
26387 @@ -15,6 +15,7 @@ enum km_type {
26388         KM_IRQ1,
26389         KM_SOFTIRQ0,
26390         KM_SOFTIRQ1,
26391 +       KM_CLEARPAGE,
26392         KM_TYPE_NR
26393  };
26394  
26395 diff -urNp linux-2.6.27.10/include/asm-mips/elf.h linux-2.6.27.10/include/asm-mips/elf.h
26396 --- linux-2.6.27.10/include/asm-mips/elf.h      2008-11-07 12:55:34.000000000 -0500
26397 +++ linux-2.6.27.10/include/asm-mips/elf.h      2008-11-18 03:38:45.000000000 -0500
26398 @@ -368,4 +368,11 @@ extern int dump_task_fpu(struct task_str
26399  #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
26400  #endif
26401  
26402 +#ifdef CONFIG_PAX_ASLR
26403 +#define PAX_ELF_ET_DYN_BASE    (test_thread_flag(TIF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL)
26404 +
26405 +#define PAX_DELTA_MMAP_LEN     (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26406 +#define PAX_DELTA_STACK_LEN    (test_thread_flag(TIF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT)
26407 +#endif
26408 +
26409  #endif /* _ASM_ELF_H */
26410 diff -urNp linux-2.6.27.10/include/asm-mips/kmap_types.h linux-2.6.27.10/include/asm-mips/kmap_types.h
26411 --- linux-2.6.27.10/include/asm-mips/kmap_types.h       2008-11-07 12:55:34.000000000 -0500
26412 +++ linux-2.6.27.10/include/asm-mips/kmap_types.h       2008-11-18 03:38:45.000000000 -0500
26413 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
26414  D(10)  KM_IRQ1,
26415  D(11)  KM_SOFTIRQ0,
26416  D(12)  KM_SOFTIRQ1,
26417 -D(13)  KM_TYPE_NR
26418 +D(13)  KM_CLEARPAGE,
26419 +D(14)  KM_TYPE_NR
26420  };
26421  
26422  #undef D
26423 diff -urNp linux-2.6.27.10/include/asm-mips/page.h linux-2.6.27.10/include/asm-mips/page.h
26424 --- linux-2.6.27.10/include/asm-mips/page.h     2008-11-07 12:55:34.000000000 -0500
26425 +++ linux-2.6.27.10/include/asm-mips/page.h     2008-11-18 03:38:45.000000000 -0500
26426 @@ -82,7 +82,7 @@ extern void copy_user_highpage(struct pa
26427    #ifdef CONFIG_CPU_MIPS32
26428      typedef struct { unsigned long pte_low, pte_high; } pte_t;
26429      #define pte_val(x)    ((x).pte_low | ((unsigned long long)(x).pte_high << 32))
26430 -    #define __pte(x)      ({ pte_t __pte = {(x), ((unsigned long long)(x)) >> 32}; __pte; })
26431 +    #define __pte(x)      ({ pte_t __pte = {(x), (x) >> 32}; __pte; })
26432    #else
26433       typedef struct { unsigned long long pte; } pte_t;
26434       #define pte_val(x)        ((x).pte)
26435 diff -urNp linux-2.6.27.10/include/asm-mips/system.h linux-2.6.27.10/include/asm-mips/system.h
26436 --- linux-2.6.27.10/include/asm-mips/system.h   2008-11-07 12:55:34.000000000 -0500
26437 +++ linux-2.6.27.10/include/asm-mips/system.h   2008-11-18 03:38:45.000000000 -0500
26438 @@ -215,6 +215,6 @@ extern void per_cpu_trap_init(void);
26439   */
26440  #define __ARCH_WANT_UNLOCKED_CTXSW
26441  
26442 -extern unsigned long arch_align_stack(unsigned long sp);
26443 +#define arch_align_stack(x) ((x) & ALMASK)
26444  
26445  #endif /* _ASM_SYSTEM_H */
26446 diff -urNp linux-2.6.27.10/include/asm-mn10300/kmap_types.h linux-2.6.27.10/include/asm-mn10300/kmap_types.h
26447 --- linux-2.6.27.10/include/asm-mn10300/kmap_types.h    2008-11-07 12:55:34.000000000 -0500
26448 +++ linux-2.6.27.10/include/asm-mn10300/kmap_types.h    2008-11-18 03:39:50.000000000 -0500
26449 @@ -25,6 +25,7 @@ enum km_type {
26450         KM_IRQ1,
26451         KM_SOFTIRQ0,
26452         KM_SOFTIRQ1,
26453 +       KM_CLEARPAGE,
26454         KM_TYPE_NR
26455  };
26456  
26457 diff -urNp linux-2.6.27.10/include/asm-parisc/elf.h linux-2.6.27.10/include/asm-parisc/elf.h
26458 --- linux-2.6.27.10/include/asm-parisc/elf.h    2008-11-07 12:55:34.000000000 -0500
26459 +++ linux-2.6.27.10/include/asm-parisc/elf.h    2008-11-18 03:38:45.000000000 -0500
26460 @@ -333,6 +333,13 @@ struct pt_regs;    /* forward declaration..
26461  
26462  #define ELF_ET_DYN_BASE         (TASK_UNMAPPED_BASE + 0x01000000)
26463  
26464 +#ifdef CONFIG_PAX_ASLR
26465 +#define PAX_ELF_ET_DYN_BASE    0x10000UL
26466 +
26467 +#define PAX_DELTA_MMAP_LEN     16
26468 +#define PAX_DELTA_STACK_LEN    16
26469 +#endif
26470 +
26471  /* This yields a mask that user programs can use to figure out what
26472     instruction set this CPU supports.  This could be done in user space,
26473     but it's not easy, and we've already done it here.  */
26474 diff -urNp linux-2.6.27.10/include/asm-parisc/kmap_types.h linux-2.6.27.10/include/asm-parisc/kmap_types.h
26475 --- linux-2.6.27.10/include/asm-parisc/kmap_types.h     2008-11-07 12:55:34.000000000 -0500
26476 +++ linux-2.6.27.10/include/asm-parisc/kmap_types.h     2008-11-18 03:38:45.000000000 -0500
26477 @@ -22,7 +22,8 @@ D(9)  KM_IRQ0,
26478  D(10)  KM_IRQ1,
26479  D(11)  KM_SOFTIRQ0,
26480  D(12)  KM_SOFTIRQ1,
26481 -D(13)  KM_TYPE_NR
26482 +D(13)  KM_CLEARPAGE,
26483 +D(14)  KM_TYPE_NR
26484  };
26485  
26486  #undef D
26487 diff -urNp linux-2.6.27.10/include/asm-parisc/pgtable.h linux-2.6.27.10/include/asm-parisc/pgtable.h
26488 --- linux-2.6.27.10/include/asm-parisc/pgtable.h        2008-11-07 12:55:34.000000000 -0500
26489 +++ linux-2.6.27.10/include/asm-parisc/pgtable.h        2008-11-18 03:38:45.000000000 -0500
26490 @@ -202,6 +202,17 @@
26491  #define PAGE_EXECREAD   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED)
26492  #define PAGE_COPY       PAGE_EXECREAD
26493  #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
26494 +
26495 +#ifdef CONFIG_PAX_PAGEEXEC
26496 +# define PAGE_SHARED_NOEXEC    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_ACCESSED)
26497 +# define PAGE_COPY_NOEXEC      __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26498 +# define PAGE_READONLY_NOEXEC  __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_ACCESSED)
26499 +#else
26500 +# define PAGE_SHARED_NOEXEC    PAGE_SHARED
26501 +# define PAGE_COPY_NOEXEC      PAGE_COPY
26502 +# define PAGE_READONLY_NOEXEC  PAGE_READONLY
26503 +#endif
26504 +
26505  #define PAGE_KERNEL    __pgprot(_PAGE_KERNEL)
26506  #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
26507  #define PAGE_KERNEL_UNC        __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
26508 diff -urNp linux-2.6.27.10/include/asm-um/kmap_types.h linux-2.6.27.10/include/asm-um/kmap_types.h
26509 --- linux-2.6.27.10/include/asm-um/kmap_types.h 2008-11-07 12:55:34.000000000 -0500
26510 +++ linux-2.6.27.10/include/asm-um/kmap_types.h 2008-11-18 03:38:45.000000000 -0500
26511 @@ -23,6 +23,7 @@ enum km_type {
26512         KM_IRQ1,
26513         KM_SOFTIRQ0,
26514         KM_SOFTIRQ1,
26515 +       KM_CLEARPAGE,
26516         KM_TYPE_NR
26517  };
26518  
26519 diff -urNp linux-2.6.27.10/include/asm-um/page.h linux-2.6.27.10/include/asm-um/page.h
26520 --- linux-2.6.27.10/include/asm-um/page.h       2008-11-07 12:55:34.000000000 -0500
26521 +++ linux-2.6.27.10/include/asm-um/page.h       2008-11-18 03:38:45.000000000 -0500
26522 @@ -14,6 +14,9 @@
26523  #define PAGE_SIZE      (_AC(1, UL) << PAGE_SHIFT)
26524  #define PAGE_MASK      (~(PAGE_SIZE-1))
26525  
26526 +#define ktla_ktva(addr)                        (addr)
26527 +#define ktva_ktla(addr)                        (addr)
26528 +
26529  #ifndef __ASSEMBLY__
26530  
26531  struct page;
26532 diff -urNp linux-2.6.27.10/include/asm-x86/alternative.h linux-2.6.27.10/include/asm-x86/alternative.h
26533 --- linux-2.6.27.10/include/asm-x86/alternative.h       2008-11-07 12:55:34.000000000 -0500
26534 +++ linux-2.6.27.10/include/asm-x86/alternative.h       2008-11-18 03:38:45.000000000 -0500
26535 @@ -96,7 +96,7 @@ const unsigned char *const *find_nop_tab
26536                       "  .byte 662b-661b\n"     /* sourcelen */         \
26537                       "  .byte 664f-663f\n"     /* replacementlen */    \
26538                       ".previous\n"                                     \
26539 -                     ".section .altinstr_replacement,\"ax\"\n"         \
26540 +                     ".section .altinstr_replacement,\"a\"\n"          \
26541                       "663:\n\t" newinstr "\n664:\n"  /* replacement */ \
26542                       ".previous" :: "i" (feature) : "memory")
26543  
26544 @@ -120,7 +120,7 @@ const unsigned char *const *find_nop_tab
26545                       "  .byte 662b-661b\n"     /* sourcelen */         \
26546                       "  .byte 664f-663f\n"     /* replacementlen */    \
26547                       ".previous\n"                                     \
26548 -                     ".section .altinstr_replacement,\"ax\"\n"         \
26549 +                     ".section .altinstr_replacement,\"a\"\n"          \
26550                       "663:\n\t" newinstr "\n664:\n"  /* replacement */ \
26551                       ".previous" :: "i" (feature), ##input)
26552  
26553 @@ -135,7 +135,7 @@ const unsigned char *const *find_nop_tab
26554                       "  .byte 662b-661b\n"     /* sourcelen */         \
26555                       "  .byte 664f-663f\n"     /* replacementlen */    \
26556                       ".previous\n"                                     \
26557 -                     ".section .altinstr_replacement,\"ax\"\n"         \
26558 +                     ".section .altinstr_replacement,\"a\"\n"          \
26559                       "663:\n\t" newinstr "\n664:\n"  /* replacement */ \
26560                       ".previous" : output : [feat] "i" (feature), ##input)
26561  
26562 diff -urNp linux-2.6.27.10/include/asm-x86/atomic_32.h linux-2.6.27.10/include/asm-x86/atomic_32.h
26563 --- linux-2.6.27.10/include/asm-x86/atomic_32.h 2008-11-07 12:55:34.000000000 -0500
26564 +++ linux-2.6.27.10/include/asm-x86/atomic_32.h 2008-11-18 03:38:45.000000000 -0500
26565 @@ -47,7 +47,15 @@ typedef struct {
26566   */
26567  static inline void atomic_add(int i, atomic_t *v)
26568  {
26569 -       asm volatile(LOCK_PREFIX "addl %1,%0"
26570 +       asm volatile(LOCK_PREFIX "addl %1,%0\n"
26571 +
26572 +#ifdef CONFIG_PAX_REFCOUNT
26573 +                    "jno 0f\n"
26574 +                    LOCK_PREFIX "subl %1,%0\n"
26575 +                    "into\n0:\n"
26576 +                    _ASM_EXTABLE(0b, 0b)
26577 +#endif
26578 +
26579                      : "+m" (v->counter)
26580                      : "ir" (i));
26581  }
26582 @@ -61,7 +69,15 @@ static inline void atomic_add(int i, ato
26583   */
26584  static inline void atomic_sub(int i, atomic_t *v)
26585  {
26586 -       asm volatile(LOCK_PREFIX "subl %1,%0"
26587 +       asm volatile(LOCK_PREFIX "subl %1,%0\n"
26588 +
26589 +#ifdef CONFIG_PAX_REFCOUNT
26590 +                    "jno 0f\n"
26591 +                    LOCK_PREFIX "addl %1,%0\n"
26592 +                    "into\n0:\n"
26593 +                    _ASM_EXTABLE(0b, 0b)
26594 +#endif
26595 +
26596                      : "+m" (v->counter)
26597                      : "ir" (i));
26598  }
26599 @@ -79,7 +95,16 @@ static inline int atomic_sub_and_test(in
26600  {
26601         unsigned char c;
26602  
26603 -       asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26604 +       asm volatile(LOCK_PREFIX "subl %2,%0\n"
26605 +
26606 +#ifdef CONFIG_PAX_REFCOUNT
26607 +                    "jno 0f\n"
26608 +                    LOCK_PREFIX "addl %2,%0\n"
26609 +                    "into\n0:\n"
26610 +                    _ASM_EXTABLE(0b, 0b)
26611 +#endif
26612 +
26613 +                    "sete %1\n"
26614                      : "+m" (v->counter), "=qm" (c)
26615                      : "ir" (i) : "memory");
26616         return c;
26617 @@ -93,7 +118,18 @@ static inline int atomic_sub_and_test(in
26618   */
26619  static inline void atomic_inc(atomic_t *v)
26620  {
26621 -       asm volatile(LOCK_PREFIX "incl %0"
26622 +       asm volatile(LOCK_PREFIX "incl %0\n"
26623 +
26624 +#ifdef CONFIG_PAX_REFCOUNT
26625 +                    "into\n0:\n"
26626 +                    ".pushsection .fixup,\"ax\"\n"
26627 +                    "1:\n"
26628 +                    LOCK_PREFIX "decl %0\n"
26629 +                    "jmp 0b\n"
26630 +                    ".popsection\n"
26631 +                    _ASM_EXTABLE(0b, 1b)
26632 +#endif
26633 +
26634                      : "+m" (v->counter));
26635  }
26636  
26637 @@ -105,7 +141,18 @@ static inline void atomic_inc(atomic_t *
26638   */
26639  static inline void atomic_dec(atomic_t *v)
26640  {
26641 -       asm volatile(LOCK_PREFIX "decl %0"
26642 +       asm volatile(LOCK_PREFIX "decl %0\n"
26643 +
26644 +#ifdef CONFIG_PAX_REFCOUNT
26645 +                    "into\n0:\n"
26646 +                    ".pushsection .fixup,\"ax\"\n"
26647 +                    "1: \n"
26648 +                    LOCK_PREFIX "incl %0\n"
26649 +                    "jmp 0b\n"
26650 +                    ".popsection\n"
26651 +                    _ASM_EXTABLE(0b, 1b)
26652 +#endif
26653 +
26654                      : "+m" (v->counter));
26655  }
26656  
26657 @@ -121,7 +168,19 @@ static inline int atomic_dec_and_test(at
26658  {
26659         unsigned char c;
26660  
26661 -       asm volatile(LOCK_PREFIX "decl %0; sete %1"
26662 +       asm volatile(LOCK_PREFIX "decl %0\n"
26663 +
26664 +#ifdef CONFIG_PAX_REFCOUNT
26665 +                    "into\n0:\n"
26666 +                    ".pushsection .fixup,\"ax\"\n"
26667 +                    "1: \n"
26668 +                    LOCK_PREFIX "incl %0\n"
26669 +                    "jmp 0b\n"
26670 +                    ".popsection\n"
26671 +                    _ASM_EXTABLE(0b, 1b)
26672 +#endif
26673 +
26674 +                    "sete %1\n"
26675                      : "+m" (v->counter), "=qm" (c)
26676                      : : "memory");
26677         return c != 0;
26678 @@ -139,7 +198,19 @@ static inline int atomic_inc_and_test(at
26679  {
26680         unsigned char c;
26681  
26682 -       asm volatile(LOCK_PREFIX "incl %0; sete %1"
26683 +       asm volatile(LOCK_PREFIX "incl %0\n"
26684 +
26685 +#ifdef CONFIG_PAX_REFCOUNT
26686 +                    "into\n0:\n"
26687 +                    ".pushsection .fixup,\"ax\"\n"
26688 +                    "1: \n"
26689 +                    LOCK_PREFIX "decl %0\n"
26690 +                    "jmp 0b\n"
26691 +                    ".popsection\n"
26692 +                    _ASM_EXTABLE(0b, 1b)
26693 +#endif
26694 +
26695 +                    "sete %1\n"
26696                      : "+m" (v->counter), "=qm" (c)
26697                      : : "memory");
26698         return c != 0;
26699 @@ -158,7 +229,16 @@ static inline int atomic_add_negative(in
26700  {
26701         unsigned char c;
26702  
26703 -       asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26704 +       asm volatile(LOCK_PREFIX "addl %2,%0\n"
26705 +
26706 +#ifdef CONFIG_PAX_REFCOUNT
26707 +                    "jno 0f\n"
26708 +                    LOCK_PREFIX "subl %2,%0\n"
26709 +                    "into\n0:\n"
26710 +                    _ASM_EXTABLE(0b, 0b)
26711 +#endif
26712 +
26713 +                    "sets %1\n"
26714                      : "+m" (v->counter), "=qm" (c)
26715                      : "ir" (i) : "memory");
26716         return c;
26717 @@ -181,7 +261,15 @@ static inline int atomic_add_return(int 
26718  #endif
26719         /* Modern 486+ processor */
26720         __i = i;
26721 -       asm volatile(LOCK_PREFIX "xaddl %0, %1"
26722 +       asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26723 +
26724 +#ifdef CONFIG_PAX_REFCOUNT
26725 +                    "jno 0f\n"
26726 +                    "movl %0, %1\n"
26727 +                    "into\n0:\n"
26728 +                    _ASM_EXTABLE(0b, 0b)
26729 +#endif
26730 +
26731                      : "+r" (i), "+m" (v->counter)
26732                      : : "memory");
26733         return i + __i;
26734 diff -urNp linux-2.6.27.10/include/asm-x86/atomic_64.h linux-2.6.27.10/include/asm-x86/atomic_64.h
26735 --- linux-2.6.27.10/include/asm-x86/atomic_64.h 2008-11-07 12:55:34.000000000 -0500
26736 +++ linux-2.6.27.10/include/asm-x86/atomic_64.h 2008-11-18 03:38:45.000000000 -0500
26737 @@ -48,7 +48,15 @@ typedef struct {
26738   */
26739  static inline void atomic_add(int i, atomic_t *v)
26740  {
26741 -       asm volatile(LOCK_PREFIX "addl %1,%0"
26742 +       asm volatile(LOCK_PREFIX "addl %1,%0\n"
26743 +
26744 +#ifdef CONFIG_PAX_REFCOUNT
26745 +                    "jno 0f\n"
26746 +                    LOCK_PREFIX "subl %1,%0\n"
26747 +                    "int $4\n0:\n"
26748 +                    _ASM_EXTABLE(0b, 0b)
26749 +#endif
26750 +
26751                      : "=m" (v->counter)
26752                      : "ir" (i), "m" (v->counter));
26753  }
26754 @@ -62,7 +70,15 @@ static inline void atomic_add(int i, ato
26755   */
26756  static inline void atomic_sub(int i, atomic_t *v)
26757  {
26758 -       asm volatile(LOCK_PREFIX "subl %1,%0"
26759 +       asm volatile(LOCK_PREFIX "subl %1,%0\n"
26760 +
26761 +#ifdef CONFIG_PAX_REFCOUNT
26762 +                    "jno 0f\n"
26763 +                    LOCK_PREFIX "addl %1,%0\n"
26764 +                    "int $4\n0:\n"
26765 +                    _ASM_EXTABLE(0b, 0b)
26766 +#endif
26767 +
26768                      : "=m" (v->counter)
26769                      : "ir" (i), "m" (v->counter));
26770  }
26771 @@ -80,7 +96,16 @@ static inline int atomic_sub_and_test(in
26772  {
26773         unsigned char c;
26774  
26775 -       asm volatile(LOCK_PREFIX "subl %2,%0; sete %1"
26776 +       asm volatile(LOCK_PREFIX "subl %2,%0\n"
26777 +
26778 +#ifdef CONFIG_PAX_REFCOUNT
26779 +                    "jno 0f\n"
26780 +                    LOCK_PREFIX "addl %2,%0\n"
26781 +                    "int $4\n0:\n"
26782 +                    _ASM_EXTABLE(0b, 0b)
26783 +#endif
26784 +
26785 +                    "sete %1\n"
26786                      : "=m" (v->counter), "=qm" (c)
26787                      : "ir" (i), "m" (v->counter) : "memory");
26788         return c;
26789 @@ -94,7 +119,19 @@ static inline int atomic_sub_and_test(in
26790   */
26791  static inline void atomic_inc(atomic_t *v)
26792  {
26793 -       asm volatile(LOCK_PREFIX "incl %0"
26794 +       asm volatile(LOCK_PREFIX "incl %0\n"
26795 +
26796 +#ifdef CONFIG_PAX_REFCOUNT
26797 +                    "jno 0f\n"
26798 +                    "int $4\n0:\n"
26799 +                    ".pushsection .fixup,\"ax\"\n"
26800 +                    "1:\n"
26801 +                    LOCK_PREFIX "decl %0\n"
26802 +                    "jmp 0b\n"
26803 +                    ".popsection\n"
26804 +                    _ASM_EXTABLE(0b, 1b)
26805 +#endif
26806 +
26807                      : "=m" (v->counter)
26808                      : "m" (v->counter));
26809  }
26810 @@ -107,7 +144,19 @@ static inline void atomic_inc(atomic_t *
26811   */
26812  static inline void atomic_dec(atomic_t *v)
26813  {
26814 -       asm volatile(LOCK_PREFIX "decl %0"
26815 +       asm volatile(LOCK_PREFIX "decl %0\n"
26816 +
26817 +#ifdef CONFIG_PAX_REFCOUNT
26818 +                    "jno 0f\n"
26819 +                    "int $4\n0:\n"
26820 +                    ".pushsection .fixup,\"ax\"\n"
26821 +                    "1: \n"
26822 +                    LOCK_PREFIX "incl %0\n"
26823 +                    "jmp 0b\n"
26824 +                    ".popsection\n"
26825 +                    _ASM_EXTABLE(0b, 1b)
26826 +#endif
26827 +
26828                      : "=m" (v->counter)
26829                      : "m" (v->counter));
26830  }
26831 @@ -124,7 +173,20 @@ static inline int atomic_dec_and_test(at
26832  {
26833         unsigned char c;
26834  
26835 -       asm volatile(LOCK_PREFIX "decl %0; sete %1"
26836 +       asm volatile(LOCK_PREFIX "decl %0\n"
26837 +
26838 +#ifdef CONFIG_PAX_REFCOUNT
26839 +                    "jno 0f\n"
26840 +                    "int $4\n0:\n"
26841 +                    ".pushsection .fixup,\"ax\"\n"
26842 +                    "1: \n"
26843 +                    LOCK_PREFIX "incl %0\n"
26844 +                    "jmp 0b\n"
26845 +                    ".popsection\n"
26846 +                    _ASM_EXTABLE(0b, 1b)
26847 +#endif
26848 +
26849 +                    "sete %1\n"
26850                      : "=m" (v->counter), "=qm" (c)
26851                      : "m" (v->counter) : "memory");
26852         return c != 0;
26853 @@ -142,7 +204,20 @@ static inline int atomic_inc_and_test(at
26854  {
26855         unsigned char c;
26856  
26857 -       asm volatile(LOCK_PREFIX "incl %0; sete %1"
26858 +       asm volatile(LOCK_PREFIX "incl %0\n"
26859 +
26860 +#ifdef CONFIG_PAX_REFCOUNT
26861 +                    "jno 0f\n"
26862 +                    "int $4\n0:\n"
26863 +                    ".pushsection .fixup,\"ax\"\n"
26864 +                    "1: \n"
26865 +                    LOCK_PREFIX "decl %0\n"
26866 +                    "jmp 0b\n"
26867 +                    ".popsection\n"
26868 +                    _ASM_EXTABLE(0b, 1b)
26869 +#endif
26870 +
26871 +                    "sete %1\n"
26872                      : "=m" (v->counter), "=qm" (c)
26873                      : "m" (v->counter) : "memory");
26874         return c != 0;
26875 @@ -161,7 +236,16 @@ static inline int atomic_add_negative(in
26876  {
26877         unsigned char c;
26878  
26879 -       asm volatile(LOCK_PREFIX "addl %2,%0; sets %1"
26880 +       asm volatile(LOCK_PREFIX "addl %2,%0\n"
26881 +
26882 +#ifdef CONFIG_PAX_REFCOUNT
26883 +                    "jno 0f\n"
26884 +                    LOCK_PREFIX "subl %2,%0\n"
26885 +                    "int $4\n0:\n"
26886 +                    _ASM_EXTABLE(0b, 0b)
26887 +#endif
26888 +
26889 +                    "sets %1\n"
26890                      : "=m" (v->counter), "=qm" (c)
26891                      : "ir" (i), "m" (v->counter) : "memory");
26892         return c;
26893 @@ -177,7 +261,15 @@ static inline int atomic_add_negative(in
26894  static inline int atomic_add_return(int i, atomic_t *v)
26895  {
26896         int __i = i;
26897 -       asm volatile(LOCK_PREFIX "xaddl %0, %1"
26898 +       asm volatile(LOCK_PREFIX "xaddl %0, %1\n"
26899 +
26900 +#ifdef CONFIG_PAX_REFCOUNT
26901 +                    "jno 0f\n"
26902 +                    "movl %0, %1\n"
26903 +                    "int $4\n0:\n"
26904 +                    _ASM_EXTABLE(0b, 0b)
26905 +#endif
26906 +
26907                      : "+r" (i), "+m" (v->counter)
26908                      : : "memory");
26909         return i + __i;
26910 @@ -226,7 +318,15 @@ typedef struct {
26911   */
26912  static inline void atomic64_add(long i, atomic64_t *v)
26913  {
26914 -       asm volatile(LOCK_PREFIX "addq %1,%0"
26915 +       asm volatile(LOCK_PREFIX "addq %1,%0\n"
26916 +
26917 +#ifdef CONFIG_PAX_REFCOUNT
26918 +                    "jno 0f\n"
26919 +                    LOCK_PREFIX "subq %1,%0\n"
26920 +                    "int $4\n0:\n"
26921 +                    _ASM_EXTABLE(0b, 0b)
26922 +#endif
26923 +
26924                      : "=m" (v->counter)
26925                      : "er" (i), "m" (v->counter));
26926  }
26927 @@ -240,7 +340,15 @@ static inline void atomic64_add(long i, 
26928   */
26929  static inline void atomic64_sub(long i, atomic64_t *v)
26930  {
26931 -       asm volatile(LOCK_PREFIX "subq %1,%0"
26932 +       asm volatile(LOCK_PREFIX "subq %1,%0\n"
26933 +
26934 +#ifdef CONFIG_PAX_REFCOUNT
26935 +                    "jno 0f\n"
26936 +                    LOCK_PREFIX "addq %1,%0\n"
26937 +                    "int $4\n0:\n"
26938 +                    _ASM_EXTABLE(0b, 0b)
26939 +#endif
26940 +
26941                      : "=m" (v->counter)
26942                      : "er" (i), "m" (v->counter));
26943  }
26944 @@ -258,7 +366,16 @@ static inline int atomic64_sub_and_test(
26945  {
26946         unsigned char c;
26947  
26948 -       asm volatile(LOCK_PREFIX "subq %2,%0; sete %1"
26949 +       asm volatile(LOCK_PREFIX "subq %2,%0\n"
26950 +
26951 +#ifdef CONFIG_PAX_REFCOUNT
26952 +                    "jno 0f\n"
26953 +                    LOCK_PREFIX "addq %2,%0\n"
26954 +                    "int $4\n0:\n"
26955 +                    _ASM_EXTABLE(0b, 0b)
26956 +#endif
26957 +
26958 +                    "sete %1\n"
26959                      : "=m" (v->counter), "=qm" (c)
26960                      : "er" (i), "m" (v->counter) : "memory");
26961         return c;
26962 @@ -272,7 +389,19 @@ static inline int atomic64_sub_and_test(
26963   */
26964  static inline void atomic64_inc(atomic64_t *v)
26965  {
26966 -       asm volatile(LOCK_PREFIX "incq %0"
26967 +       asm volatile(LOCK_PREFIX "incq %0\n"
26968 +
26969 +#ifdef CONFIG_PAX_REFCOUNT
26970 +                    "jno 0f\n"
26971 +                    "int $4\n0:\n"
26972 +                    ".pushsection .fixup,\"ax\"\n"
26973 +                    "1:\n"
26974 +                    LOCK_PREFIX "decq %0\n"
26975 +                    "jmp 0b\n"
26976 +                    ".popsection\n"
26977 +                    _ASM_EXTABLE(0b, 1b)
26978 +#endif
26979 +
26980                      : "=m" (v->counter)
26981                      : "m" (v->counter));
26982  }
26983 @@ -285,7 +414,19 @@ static inline void atomic64_inc(atomic64
26984   */
26985  static inline void atomic64_dec(atomic64_t *v)
26986  {
26987 -       asm volatile(LOCK_PREFIX "decq %0"
26988 +       asm volatile(LOCK_PREFIX "decq %0\n"
26989 +
26990 +#ifdef CONFIG_PAX_REFCOUNT
26991 +                    "jno 0f\n"
26992 +                    "int $4\n0:\n"
26993 +                    ".pushsection .fixup,\"ax\"\n"
26994 +                    "1: \n"
26995 +                    LOCK_PREFIX "incq %0\n"
26996 +                    "jmp 0b\n"
26997 +                    ".popsection\n"
26998 +                    _ASM_EXTABLE(0b, 1b)
26999 +#endif
27000 +
27001                      : "=m" (v->counter)
27002                      : "m" (v->counter));
27003  }
27004 @@ -302,7 +443,20 @@ static inline int atomic64_dec_and_test(
27005  {
27006         unsigned char c;
27007  
27008 -       asm volatile(LOCK_PREFIX "decq %0; sete %1"
27009 +       asm volatile(LOCK_PREFIX "decq %0\n"
27010 +
27011 +#ifdef CONFIG_PAX_REFCOUNT
27012 +                    "jno 0f\n"
27013 +                    "int $4\n0:\n"
27014 +                    ".pushsection .fixup,\"ax\"\n"
27015 +                    "1: \n"
27016 +                    LOCK_PREFIX "incq %0\n"
27017 +                    "jmp 0b\n"
27018 +                    ".popsection\n"
27019 +                    _ASM_EXTABLE(0b, 1b)
27020 +#endif
27021 +
27022 +                    "sete %1\n"
27023                      : "=m" (v->counter), "=qm" (c)
27024                      : "m" (v->counter) : "memory");
27025         return c != 0;
27026 @@ -320,7 +474,20 @@ static inline int atomic64_inc_and_test(
27027  {
27028         unsigned char c;
27029  
27030 -       asm volatile(LOCK_PREFIX "incq %0; sete %1"
27031 +       asm volatile(LOCK_PREFIX "incq %0\n"
27032 +
27033 +#ifdef CONFIG_PAX_REFCOUNT
27034 +                    "jno 0f\n"
27035 +                    "int $4\n0:\n"
27036 +                    ".pushsection .fixup,\"ax\"\n"
27037 +                    "1: \n"
27038 +                    LOCK_PREFIX "decq %0\n"
27039 +                    "jmp 0b\n"
27040 +                    ".popsection\n"
27041 +                    _ASM_EXTABLE(0b, 1b)
27042 +#endif
27043 +
27044 +                    "sete %1\n"
27045                      : "=m" (v->counter), "=qm" (c)
27046                      : "m" (v->counter) : "memory");
27047         return c != 0;
27048 @@ -339,7 +506,16 @@ static inline int atomic64_add_negative(
27049  {
27050         unsigned char c;
27051  
27052 -       asm volatile(LOCK_PREFIX "addq %2,%0; sets %1"
27053 +       asm volatile(LOCK_PREFIX "addq %2,%0\n"
27054 +
27055 +#ifdef CONFIG_PAX_REFCOUNT
27056 +                    "jno 0f\n"
27057 +                    LOCK_PREFIX "subq %2,%0\n"
27058 +                    "int $4\n0:\n"
27059 +                    _ASM_EXTABLE(0b, 0b)
27060 +#endif
27061 +
27062 +                    "sets %1\n"
27063                      : "=m" (v->counter), "=qm" (c)
27064                      : "er" (i), "m" (v->counter) : "memory");
27065         return c;
27066 @@ -355,7 +531,15 @@ static inline int atomic64_add_negative(
27067  static inline long atomic64_add_return(long i, atomic64_t *v)
27068  {
27069         long __i = i;
27070 -       asm volatile(LOCK_PREFIX "xaddq %0, %1;"
27071 +       asm volatile(LOCK_PREFIX "xaddq %0, %1\n"
27072 +
27073 +#ifdef CONFIG_PAX_REFCOUNT
27074 +                    "jno 0f\n"
27075 +                    "movq %0, %1\n"
27076 +                    "int $4\n0:\n"
27077 +                    _ASM_EXTABLE(0b, 0b)
27078 +#endif
27079 +
27080                      : "+r" (i), "+m" (v->counter)
27081                      : : "memory");
27082         return i + __i;
27083 diff -urNp linux-2.6.27.10/include/asm-x86/boot.h linux-2.6.27.10/include/asm-x86/boot.h
27084 --- linux-2.6.27.10/include/asm-x86/boot.h      2008-11-07 12:55:34.000000000 -0500
27085 +++ linux-2.6.27.10/include/asm-x86/boot.h      2008-11-18 03:38:45.000000000 -0500
27086 @@ -13,10 +13,15 @@
27087  #define ASK_VGA                0xfffd          /* ask for it at bootup */
27088  
27089  /* Physical address where kernel should be loaded. */
27090 -#define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
27091 +#define ____LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \
27092                                 + (CONFIG_PHYSICAL_ALIGN - 1)) \
27093                                 & ~(CONFIG_PHYSICAL_ALIGN - 1))
27094  
27095 +#ifndef __ASSEMBLY__
27096 +extern unsigned char __LOAD_PHYSICAL_ADDR[];
27097 +#define LOAD_PHYSICAL_ADDR ((unsigned long)__LOAD_PHYSICAL_ADDR)
27098 +#endif
27099 +
27100  #ifdef CONFIG_X86_64
27101  #define BOOT_HEAP_SIZE 0x7000
27102  #define BOOT_STACK_SIZE        0x4000
27103 diff -urNp linux-2.6.27.10/include/asm-x86/cache.h linux-2.6.27.10/include/asm-x86/cache.h
27104 --- linux-2.6.27.10/include/asm-x86/cache.h     2008-11-07 12:55:34.000000000 -0500
27105 +++ linux-2.6.27.10/include/asm-x86/cache.h     2008-11-18 03:38:45.000000000 -0500
27106 @@ -6,6 +6,7 @@
27107  #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
27108  
27109  #define __read_mostly __attribute__((__section__(".data.read_mostly")))
27110 +#define __read_only __attribute__((__section__(".data.read_only")))
27111  
27112  #ifdef CONFIG_X86_VSMP
27113  /* vSMP Internode cacheline shift */
27114 diff -urNp linux-2.6.27.10/include/asm-x86/checksum_32.h linux-2.6.27.10/include/asm-x86/checksum_32.h
27115 --- linux-2.6.27.10/include/asm-x86/checksum_32.h       2008-11-07 12:55:34.000000000 -0500
27116 +++ linux-2.6.27.10/include/asm-x86/checksum_32.h       2008-11-18 03:38:45.000000000 -0500
27117 @@ -31,6 +31,14 @@ asmlinkage __wsum csum_partial_copy_gene
27118                                             int len, __wsum sum,
27119                                             int *src_err_ptr, int *dst_err_ptr);
27120  
27121 +asmlinkage __wsum csum_partial_copy_generic_to_user(const void *src, void *dst,
27122 +                                                 int len, __wsum sum,
27123 +                                                 int *src_err_ptr, int *dst_err_ptr);
27124 +
27125 +asmlinkage __wsum csum_partial_copy_generic_from_user(const void *src, void *dst,
27126 +                                                 int len, __wsum sum,
27127 +                                                 int *src_err_ptr, int *dst_err_ptr);
27128 +
27129  /*
27130   *     Note: when you get a NULL pointer exception here this means someone
27131   *     passed in an incorrect kernel address to one of these functions.
27132 @@ -50,7 +58,7 @@ static inline __wsum csum_partial_copy_f
27133                                                  int *err_ptr)
27134  {
27135         might_sleep();
27136 -       return csum_partial_copy_generic((__force void *)src, dst,
27137 +       return csum_partial_copy_generic_from_user((__force void *)src, dst,
27138                                          len, sum, err_ptr, NULL);
27139  }
27140  
27141 @@ -177,7 +185,7 @@ static inline __wsum csum_and_copy_to_us
27142  {
27143         might_sleep();
27144         if (access_ok(VERIFY_WRITE, dst, len))
27145 -               return csum_partial_copy_generic(src, (__force void *)dst,
27146 +               return csum_partial_copy_generic_to_user(src, (__force void *)dst,
27147                                                  len, sum, NULL, err_ptr);
27148  
27149         if (len)
27150 diff -urNp linux-2.6.27.10/include/asm-x86/desc.h linux-2.6.27.10/include/asm-x86/desc.h
27151 --- linux-2.6.27.10/include/asm-x86/desc.h      2008-11-07 12:55:34.000000000 -0500
27152 +++ linux-2.6.27.10/include/asm-x86/desc.h      2008-11-18 03:38:45.000000000 -0500
27153 @@ -16,6 +16,7 @@ static inline void fill_ldt(struct desc_
27154         desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
27155         desc->type = (info->read_exec_only ^ 1) << 1;
27156         desc->type |= info->contents << 2;
27157 +       desc->type |= info->seg_not_present ^ 1;
27158         desc->s = 1;
27159         desc->dpl = 0x3;
27160         desc->p = info->seg_not_present ^ 1;
27161 @@ -27,16 +28,12 @@ static inline void fill_ldt(struct desc_
27162  }
27163  
27164  extern struct desc_ptr idt_descr;
27165 -extern gate_desc idt_table[];
27166 -
27167 -struct gdt_page {
27168 -       struct desc_struct gdt[GDT_ENTRIES];
27169 -} __attribute__((aligned(PAGE_SIZE)));
27170 -DECLARE_PER_CPU(struct gdt_page, gdt_page);
27171 +extern gate_desc idt_table[256];
27172  
27173 +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)];
27174  static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
27175  {
27176 -       return per_cpu(gdt_page, cpu).gdt;
27177 +       return cpu_gdt_table[cpu];
27178  }
27179  
27180  #ifdef CONFIG_X86_64
27181 @@ -65,7 +62,6 @@ static inline void pack_gate(gate_desc *
27182         gate->b = (base & 0xffff0000) |
27183                   (((0x80 | type | (dpl << 5)) & 0xff) << 8);
27184  }
27185 -
27186  #endif
27187  
27188  static inline int desc_empty(const void *ptr)
27189 @@ -102,19 +98,48 @@ static inline int desc_empty(const void 
27190  static inline void native_write_idt_entry(gate_desc *idt, int entry,
27191                                           const gate_desc *gate)
27192  {
27193 +
27194 +#ifdef CONFIG_PAX_KERNEXEC
27195 +       unsigned long cr0;
27196 +
27197 +       pax_open_kernel(cr0);
27198 +#endif
27199 +
27200         memcpy(&idt[entry], gate, sizeof(*gate));
27201 +
27202 +#ifdef CONFIG_PAX_KERNEXEC
27203 +       pax_close_kernel(cr0);
27204 +#endif
27205 +
27206  }
27207  
27208  static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
27209                                           const void *desc)
27210  {
27211 +
27212 +#ifdef CONFIG_PAX_KERNEXEC
27213 +       unsigned long cr0;
27214 +
27215 +       pax_open_kernel(cr0);
27216 +#endif
27217 +
27218         memcpy(&ldt[entry], desc, 8);
27219 +
27220 +#ifdef CONFIG_PAX_KERNEXEC
27221 +       pax_close_kernel(cr0);
27222 +#endif
27223 +
27224  }
27225  
27226  static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
27227                                           const void *desc, int type)
27228  {
27229         unsigned int size;
27230 +
27231 +#ifdef CONFIG_PAX_KERNEXEC
27232 +       unsigned long cr0;
27233 +#endif
27234 +
27235         switch (type) {
27236         case DESC_TSS:
27237                 size = sizeof(tss_desc);
27238 @@ -126,7 +151,17 @@ static inline void native_write_gdt_entr
27239                 size = sizeof(struct desc_struct);
27240                 break;
27241         }
27242 +
27243 +#ifdef CONFIG_PAX_KERNEXEC
27244 +       pax_open_kernel(cr0);
27245 +#endif
27246 +
27247         memcpy(&gdt[entry], desc, size);
27248 +
27249 +#ifdef CONFIG_PAX_KERNEXEC
27250 +       pax_close_kernel(cr0);
27251 +#endif
27252 +
27253  }
27254  
27255  static inline void pack_descriptor(struct desc_struct *desc, unsigned long base,
27256 @@ -198,7 +233,19 @@ static inline void native_set_ldt(const 
27257  
27258  static inline void native_load_tr_desc(void)
27259  {
27260 +
27261 +#ifdef CONFIG_PAX_KERNEXEC
27262 +       unsigned long cr0;
27263 +
27264 +       pax_open_kernel(cr0);
27265 +#endif
27266 +
27267         asm volatile("ltr %w0"::"q" (GDT_ENTRY_TSS*8));
27268 +
27269 +#ifdef CONFIG_PAX_KERNEXEC
27270 +       pax_close_kernel(cr0);
27271 +#endif
27272 +
27273  }
27274  
27275  static inline void native_load_gdt(const struct desc_ptr *dtr)
27276 @@ -233,8 +280,19 @@ static inline void native_load_tls(struc
27277         unsigned int i;
27278         struct desc_struct *gdt = get_cpu_gdt_table(cpu);
27279  
27280 +#ifdef CONFIG_PAX_KERNEXEC
27281 +       unsigned long cr0;
27282 +
27283 +       pax_open_kernel(cr0);
27284 +#endif
27285 +
27286         for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
27287                 gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
27288 +
27289 +#ifdef CONFIG_PAX_KERNEXEC
27290 +       pax_close_kernel(cr0);
27291 +#endif
27292 +
27293  }
27294  
27295  #define _LDT_empty(info)                               \
27296 @@ -372,6 +430,18 @@ static inline void set_system_gate_ist(i
27297         _set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
27298  }
27299  
27300 +#ifdef CONFIG_X86_32
27301 +static inline void set_user_cs(unsigned long base, unsigned long limit, int cpu)
27302 +{
27303 +       struct desc_struct d;
27304 +
27305 +       if (likely(limit))
27306 +               limit = (limit - 1UL) >> PAGE_SHIFT;
27307 +       pack_descriptor(&d, base, limit, 0xFB, 0xC);
27308 +       write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, &d, DESCTYPE_S);
27309 +}
27310 +#endif
27311 +
27312  #else
27313  /*
27314   * GET_DESC_BASE reads the descriptor base of the specified segment.
27315 diff -urNp linux-2.6.27.10/include/asm-x86/e820.h linux-2.6.27.10/include/asm-x86/e820.h
27316 --- linux-2.6.27.10/include/asm-x86/e820.h      2008-11-07 12:55:34.000000000 -0500
27317 +++ linux-2.6.27.10/include/asm-x86/e820.h      2008-11-18 03:38:45.000000000 -0500
27318 @@ -131,7 +131,7 @@ extern char *memory_setup(void);
27319  #define ISA_END_ADDRESS                0x100000
27320  #define is_ISA_range(s, e) ((s) >= ISA_START_ADDRESS && (e) < ISA_END_ADDRESS)
27321  
27322 -#define BIOS_BEGIN             0x000a0000
27323 +#define BIOS_BEGIN             0x000c0000
27324  #define BIOS_END               0x00100000
27325  
27326  #ifdef __KERNEL__
27327 diff -urNp linux-2.6.27.10/include/asm-x86/elf.h linux-2.6.27.10/include/asm-x86/elf.h
27328 --- linux-2.6.27.10/include/asm-x86/elf.h       2008-11-07 12:55:34.000000000 -0500
27329 +++ linux-2.6.27.10/include/asm-x86/elf.h       2008-11-18 03:38:45.000000000 -0500
27330 @@ -251,7 +251,25 @@ extern int force_personality32;
27331     the loader.  We need to make sure that it is out of the way of the program
27332     that it will "exec", and that there is sufficient room for the brk.  */
27333  
27334 +#ifdef CONFIG_PAX_SEGMEXEC
27335 +#define ELF_ET_DYN_BASE                ((current->mm->pax_flags & MF_PAX_SEGMEXEC) ? SEGMEXEC_TASK_SIZE/3*2 : TASK_SIZE/3*2)
27336 +#else
27337  #define ELF_ET_DYN_BASE                (TASK_SIZE / 3 * 2)
27338 +#endif
27339 +
27340 +#ifdef CONFIG_PAX_ASLR
27341 +#ifdef CONFIG_X86_32
27342 +#define PAX_ELF_ET_DYN_BASE    0x10000000UL
27343 +
27344 +#define PAX_DELTA_MMAP_LEN     (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
27345 +#define PAX_DELTA_STACK_LEN    (current->mm->pax_flags & MF_PAX_SEGMEXEC ? 15 : 16)
27346 +#else
27347 +#define PAX_ELF_ET_DYN_BASE    0x400000UL
27348 +
27349 +#define PAX_DELTA_MMAP_LEN     ((test_thread_flag(TIF_IA32)) ? 16 : 32)
27350 +#define PAX_DELTA_STACK_LEN    ((test_thread_flag(TIF_IA32)) ? 16 : 32)
27351 +#endif
27352 +#endif
27353  
27354  /* This yields a mask that user programs can use to figure out what
27355     instruction set this CPU supports.  This could be done in user space,
27356 @@ -303,8 +321,7 @@ do {                                                                        \
27357  #define ARCH_DLINFO                                                    \
27358  do {                                                                   \
27359         if (vdso_enabled)                                               \
27360 -               NEW_AUX_ENT(AT_SYSINFO_EHDR,                            \
27361 -                           (unsigned long)current->mm->context.vdso);  \
27362 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, current->mm->context.vdso);\
27363  } while (0)
27364  
27365  #define AT_SYSINFO             32
27366 @@ -315,7 +332,7 @@ do {                                                                        \
27367  
27368  #endif /* !CONFIG_X86_32 */
27369  
27370 -#define VDSO_CURRENT_BASE      ((unsigned long)current->mm->context.vdso)
27371 +#define VDSO_CURRENT_BASE      (current->mm->context.vdso)
27372  
27373  #define VDSO_ENTRY                                                     \
27374         ((unsigned long)VDSO32_SYMBOL(VDSO_CURRENT_BASE, vsyscall))
27375 @@ -329,7 +346,4 @@ extern int arch_setup_additional_pages(s
27376  extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
27377  #define compat_arch_setup_additional_pages     syscall32_setup_pages
27378  
27379 -extern unsigned long arch_randomize_brk(struct mm_struct *mm);
27380 -#define arch_randomize_brk arch_randomize_brk
27381 -
27382  #endif
27383 diff -urNp linux-2.6.27.10/include/asm-x86/futex.h linux-2.6.27.10/include/asm-x86/futex.h
27384 --- linux-2.6.27.10/include/asm-x86/futex.h     2008-11-07 12:55:34.000000000 -0500
27385 +++ linux-2.6.27.10/include/asm-x86/futex.h     2008-11-18 03:38:45.000000000 -0500
27386 @@ -11,6 +11,40 @@
27387  #include <asm/processor.h>
27388  #include <asm/system.h>
27389  
27390 +#ifdef CONFIG_X86_32
27391 +#define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg)    \
27392 +       asm volatile(                                           \
27393 +                    "movw\t%w6, %%ds\n"                        \
27394 +                    "1:\t" insn "\n"                           \
27395 +                    "2:\tpushl\t%%ss\n"                        \
27396 +                    "\tpopl\t%%ds\n"                           \
27397 +                    "\t.section .fixup,\"ax\"\n"               \
27398 +                    "3:\tmov\t%3, %1\n"                        \
27399 +                    "\tjmp\t2b\n"                              \
27400 +                    "\t.previous\n"                            \
27401 +                    _ASM_EXTABLE(1b, 3b)                       \
27402 +                    : "=r" (oldval), "=r" (ret), "+m" (*uaddr) \
27403 +                    : "i" (-EFAULT), "0" (oparg), "1" (0), "r" (__USER_DS))
27404 +
27405 +#define __futex_atomic_op2(insn, ret, oldval, uaddr, oparg)    \
27406 +       asm volatile("movw\t%w7, %%es\n"                        \
27407 +                    "1:\tmovl\t%%es:%2, %0\n"                  \
27408 +                    "\tmovl\t%0, %3\n"                         \
27409 +                    "\t" insn "\n"                             \
27410 +                    "2:\tlock; cmpxchgl %3, %%es:%2\n"         \
27411 +                    "\tjnz\t1b\n"                              \
27412 +                    "3:\tpushl\t%%ss\n"                        \
27413 +                    "\tpopl\t%%es\n"                           \
27414 +                    "\t.section .fixup,\"ax\"\n"               \
27415 +                    "4:\tmov\t%5, %1\n"                        \
27416 +                    "\tjmp\t3b\n"                              \
27417 +                    "\t.previous\n"                            \
27418 +                    _ASM_EXTABLE(1b, 4b)                       \
27419 +                    _ASM_EXTABLE(2b, 4b)                       \
27420 +                    : "=&a" (oldval), "=&r" (ret),             \
27421 +                      "+m" (*uaddr), "=&r" (tem)               \
27422 +                    : "r" (oparg), "i" (-EFAULT), "1" (0), "r" (__USER_DS))
27423 +#else
27424  #define __futex_atomic_op1(insn, ret, oldval, uaddr, oparg)    \
27425         asm volatile("1:\t" insn "\n"                           \
27426                      "2:\t.section .fixup,\"ax\"\n"             \
27427 @@ -36,8 +70,9 @@
27428                      : "=&a" (oldval), "=&r" (ret),             \
27429                        "+m" (*uaddr), "=&r" (tem)               \
27430                      : "r" (oparg), "i" (-EFAULT), "1" (0))
27431 +#endif
27432  
27433 -static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
27434 +static inline int futex_atomic_op_inuser(int encoded_op, u32 __user *uaddr)
27435  {
27436         int op = (encoded_op >> 28) & 7;
27437         int cmp = (encoded_op >> 24) & 15;
27438 @@ -61,11 +96,20 @@ static inline int futex_atomic_op_inuser
27439  
27440         switch (op) {
27441         case FUTEX_OP_SET:
27442 +#ifdef CONFIG_X86_32
27443 +               __futex_atomic_op1("xchgl %0, %%ds:%2", ret, oldval, uaddr, oparg);
27444 +#else
27445                 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);
27446 +#endif
27447                 break;
27448         case FUTEX_OP_ADD:
27449 +#ifdef CONFIG_X86_32
27450 +               __futex_atomic_op1("lock ; xaddl %0, %%ds:%2", ret, oldval,
27451 +                                  uaddr, oparg);
27452 +#else
27453                 __futex_atomic_op1("lock; xaddl %0, %2", ret, oldval,
27454                                    uaddr, oparg);
27455 +#endif
27456                 break;
27457         case FUTEX_OP_OR:
27458                 __futex_atomic_op2("orl %4, %3", ret, oldval, uaddr, oparg);
27459 @@ -109,7 +153,7 @@ static inline int futex_atomic_op_inuser
27460         return ret;
27461  }
27462  
27463 -static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
27464 +static inline int futex_atomic_cmpxchg_inatomic(u32 __user *uaddr, int oldval,
27465                                                 int newval)
27466  {
27467  
27468 @@ -122,14 +166,27 @@ static inline int futex_atomic_cmpxchg_i
27469         if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
27470                 return -EFAULT;
27471  
27472 -       asm volatile("1:\tlock; cmpxchgl %3, %1\n"
27473 +       asm volatile(
27474 +#ifdef CONFIG_X86_32
27475 +                    "\tmovw %w5, %%ds\n"
27476 +                    "1:\tlock; cmpxchgl %3, %1\n"
27477 +                    "2:\tpushl   %%ss\n"
27478 +                    "\tpopl    %%ds\n"
27479 +                    "\t.section .fixup, \"ax\"\n"
27480 +#else
27481 +                    "1:\tlock; cmpxchgl %3, %1\n"
27482                      "2:\t.section .fixup, \"ax\"\n"
27483 +#endif
27484                      "3:\tmov     %2, %0\n"
27485                      "\tjmp     2b\n"
27486                      "\t.previous\n"
27487                      _ASM_EXTABLE(1b, 3b)
27488                      : "=a" (oldval), "+m" (*uaddr)
27489 +#ifdef CONFIG_X86_32
27490 +                    : "i" (-EFAULT), "r" (newval), "0" (oldval), "r" (__USER_DS)
27491 +#else
27492                      : "i" (-EFAULT), "r" (newval), "0" (oldval)
27493 +#endif
27494                      : "memory"
27495         );
27496  
27497 diff -urNp linux-2.6.27.10/include/asm-x86/i387.h linux-2.6.27.10/include/asm-x86/i387.h
27498 --- linux-2.6.27.10/include/asm-x86/i387.h      2008-11-07 12:55:34.000000000 -0500
27499 +++ linux-2.6.27.10/include/asm-x86/i387.h      2008-11-18 03:38:45.000000000 -0500
27500 @@ -159,13 +159,8 @@ static inline void restore_fpu(struct ta
27501  }
27502  
27503  /* We need a safe address that is cheap to find and that is already
27504 -   in L1 during context switch. The best choices are unfortunately
27505 -   different for UP and SMP */
27506 -#ifdef CONFIG_SMP
27507 -#define safe_address (__per_cpu_offset[0])
27508 -#else
27509 -#define safe_address (kstat_cpu(0).cpustat.user)
27510 -#endif
27511 +   in L1 during context switch. */
27512 +#define safe_address (init_tss[smp_processor_id()].x86_tss.sp0)
27513  
27514  /*
27515   * These must be called with preempt disabled
27516 diff -urNp linux-2.6.27.10/include/asm-x86/io_64.h linux-2.6.27.10/include/asm-x86/io_64.h
27517 --- linux-2.6.27.10/include/asm-x86/io_64.h     2008-11-07 12:55:34.000000000 -0500
27518 +++ linux-2.6.27.10/include/asm-x86/io_64.h     2008-11-18 03:38:45.000000000 -0500
27519 @@ -158,6 +158,17 @@ static inline void *phys_to_virt(unsigne
27520  }
27521  #endif
27522  
27523 +#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
27524 +static inline int valid_phys_addr_range (unsigned long addr, size_t count)
27525 +{
27526 +       return ((addr + count + PAGE_SIZE - 1) >> PAGE_SHIFT) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27527 +}
27528 +
27529 +static inline int valid_mmap_phys_addr_range (unsigned long pfn, size_t count)
27530 +{
27531 +       return (pfn + (count >> PAGE_SHIFT)) < (1 << (boot_cpu_data.x86_phys_bits - PAGE_SHIFT)) ? 1 : 0;
27532 +}
27533 +
27534  /*
27535   * Change "struct page" to physical address.
27536   */
27537 diff -urNp linux-2.6.27.10/include/asm-x86/irqflags.h linux-2.6.27.10/include/asm-x86/irqflags.h
27538 --- linux-2.6.27.10/include/asm-x86/irqflags.h  2008-11-07 12:55:34.000000000 -0500
27539 +++ linux-2.6.27.10/include/asm-x86/irqflags.h  2008-11-18 03:38:45.000000000 -0500
27540 @@ -141,6 +141,8 @@ static inline unsigned long __raw_local_
27541  #define INTERRUPT_RETURN               iret
27542  #define ENABLE_INTERRUPTS_SYSEXIT      sti; sysexit
27543  #define GET_CR0_INTO_EAX               movl %cr0, %eax
27544 +#define GET_CR0_INTO_EDX               movl %cr0, %edx
27545 +#define SET_CR0_FROM_EDX               movl %edx, %cr0
27546  #endif
27547  
27548  
27549 diff -urNp linux-2.6.27.10/include/asm-x86/kmap_types.h linux-2.6.27.10/include/asm-x86/kmap_types.h
27550 --- linux-2.6.27.10/include/asm-x86/kmap_types.h        2008-11-07 12:55:34.000000000 -0500
27551 +++ linux-2.6.27.10/include/asm-x86/kmap_types.h        2008-11-18 03:38:45.000000000 -0500
27552 @@ -21,7 +21,8 @@ D(9)  KM_IRQ0,
27553  D(10)  KM_IRQ1,
27554  D(11)  KM_SOFTIRQ0,
27555  D(12)  KM_SOFTIRQ1,
27556 -D(13)  KM_TYPE_NR
27557 +D(13)  KM_CLEARPAGE,
27558 +D(14)  KM_TYPE_NR
27559  };
27560  
27561  #undef D
27562 diff -urNp linux-2.6.27.10/include/asm-x86/linkage.h linux-2.6.27.10/include/asm-x86/linkage.h
27563 --- linux-2.6.27.10/include/asm-x86/linkage.h   2008-11-07 12:55:34.000000000 -0500
27564 +++ linux-2.6.27.10/include/asm-x86/linkage.h   2008-11-18 03:38:45.000000000 -0500
27565 @@ -7,6 +7,11 @@
27566  #ifdef CONFIG_X86_64
27567  #define __ALIGN .p2align 4,,15
27568  #define __ALIGN_STR ".p2align 4,,15"
27569 +#else
27570 +#ifdef CONFIG_X86_ALIGNMENT_16
27571 +#define __ALIGN .align 16,0x90
27572 +#define __ALIGN_STR ".align 16,0x90"
27573 +#endif
27574  #endif
27575  
27576  #ifdef CONFIG_X86_32
27577 @@ -52,10 +57,5 @@
27578  
27579  #endif
27580  
27581 -#ifdef CONFIG_X86_ALIGNMENT_16
27582 -#define __ALIGN .align 16,0x90
27583 -#define __ALIGN_STR ".align 16,0x90"
27584 -#endif
27585 -
27586  #endif
27587  
27588 diff -urNp linux-2.6.27.10/include/asm-x86/local.h linux-2.6.27.10/include/asm-x86/local.h
27589 --- linux-2.6.27.10/include/asm-x86/local.h     2008-11-07 12:55:34.000000000 -0500
27590 +++ linux-2.6.27.10/include/asm-x86/local.h     2008-11-18 03:38:45.000000000 -0500
27591 @@ -18,26 +18,90 @@ typedef struct {
27592  
27593  static inline void local_inc(local_t *l)
27594  {
27595 -       asm volatile(_ASM_INC "%0"
27596 +       asm volatile(_ASM_INC "%0\n"
27597 +
27598 +#ifdef CONFIG_PAX_REFCOUNT
27599 +#ifdef CONFIG_X86_32
27600 +                    "into\n0:\n"
27601 +#else
27602 +                    "jno 0f\n"
27603 +                    "int $4\n0:\n"
27604 +#endif
27605 +                    ".pushsection .fixup,\"ax\"\n"
27606 +                    "1:\n"
27607 +                    _ASM_DEC "%0\n"
27608 +                    "jmp 0b\n"
27609 +                    ".popsection\n"
27610 +                    _ASM_EXTABLE(0b, 1b)
27611 +#endif
27612 +
27613                      : "+m" (l->a.counter));
27614  }
27615  
27616  static inline void local_dec(local_t *l)
27617  {
27618 -       asm volatile(_ASM_DEC "%0"
27619 +       asm volatile(_ASM_DEC "%0\n"
27620 +
27621 +#ifdef CONFIG_PAX_REFCOUNT
27622 +#ifdef CONFIG_X86_32
27623 +                    "into\n0:\n"
27624 +#else
27625 +                    "jno 0f\n"
27626 +                    "int $4\n0:\n"
27627 +#endif
27628 +                    ".pushsection .fixup,\"ax\"\n"
27629 +                    "1:\n"
27630 +                    _ASM_INC "%0\n"
27631 +                    "jmp 0b\n"
27632 +                    ".popsection\n"
27633 +                    _ASM_EXTABLE(0b, 1b)
27634 +#endif
27635 +
27636                      : "+m" (l->a.counter));
27637  }
27638  
27639  static inline void local_add(long i, local_t *l)
27640  {
27641 -       asm volatile(_ASM_ADD "%1,%0"
27642 +       asm volatile(_ASM_ADD "%1,%0\n"
27643 +
27644 +#ifdef CONFIG_PAX_REFCOUNT
27645 +#ifdef CONFIG_X86_32
27646 +                    "into\n0:\n"
27647 +#else
27648 +                    "jno 0f\n"
27649 +                    "int $4\n0:\n"
27650 +#endif
27651 +                    ".pushsection .fixup,\"ax\"\n"
27652 +                    "1:\n"
27653 +                    _ASM_SUB "%1,%0\n"
27654 +                    "jmp 0b\n"
27655 +                    ".popsection\n"
27656 +                    _ASM_EXTABLE(0b, 1b)
27657 +#endif
27658 +
27659                      : "+m" (l->a.counter)
27660                      : "ir" (i));
27661  }
27662  
27663  static inline void local_sub(long i, local_t *l)
27664  {
27665 -       asm volatile(_ASM_SUB "%1,%0"
27666 +       asm volatile(_ASM_SUB "%1,%0\n"
27667 +
27668 +#ifdef CONFIG_PAX_REFCOUNT
27669 +#ifdef CONFIG_X86_32
27670 +                    "into\n0:\n"
27671 +#else
27672 +                    "jno 0f\n"
27673 +                    "int $4\n0:\n"
27674 +#endif
27675 +                    ".pushsection .fixup,\"ax\"\n"
27676 +                    "1:\n"
27677 +                    _ASM_ADD "%1,%0\n"
27678 +                    "jmp 0b\n"
27679 +                    ".popsection\n"
27680 +                    _ASM_EXTABLE(0b, 1b)
27681 +#endif
27682 +
27683                      : "+m" (l->a.counter)
27684                      : "ir" (i));
27685  }
27686 @@ -55,7 +119,24 @@ static inline int local_sub_and_test(lon
27687  {
27688         unsigned char c;
27689  
27690 -       asm volatile(_ASM_SUB "%2,%0; sete %1"
27691 +       asm volatile(_ASM_SUB "%2,%0\n"
27692 +
27693 +#ifdef CONFIG_PAX_REFCOUNT
27694 +#ifdef CONFIG_X86_32
27695 +                    "into\n0:\n"
27696 +#else
27697 +                    "jno 0f\n"
27698 +                    "int $4\n0:\n"
27699 +#endif
27700 +                    ".pushsection .fixup,\"ax\"\n"
27701 +                    "1:\n"
27702 +                    _ASM_ADD "%2,%0\n"
27703 +                    "jmp 0b\n"
27704 +                    ".popsection\n"
27705 +                    _ASM_EXTABLE(0b, 1b)
27706 +#endif
27707 +
27708 +                    "sete %1\n"
27709                      : "+m" (l->a.counter), "=qm" (c)
27710                      : "ir" (i) : "memory");
27711         return c;
27712 @@ -73,7 +154,24 @@ static inline int local_dec_and_test(loc
27713  {
27714         unsigned char c;
27715  
27716 -       asm volatile(_ASM_DEC "%0; sete %1"
27717 +       asm volatile(_ASM_DEC "%0\n"
27718 +
27719 +#ifdef CONFIG_PAX_REFCOUNT
27720 +#ifdef CONFIG_X86_32
27721 +                    "into\n0:\n"
27722 +#else
27723 +                    "jno 0f\n"
27724 +                    "int $4\n0:\n"
27725 +#endif
27726 +                    ".pushsection .fixup,\"ax\"\n"
27727 +                    "1:\n"
27728 +                    _ASM_INC "%0\n"
27729 +                    "jmp 0b\n"
27730 +                    ".popsection\n"
27731 +                    _ASM_EXTABLE(0b, 1b)
27732 +#endif
27733 +
27734 +                    "sete %1\n"
27735                      : "+m" (l->a.counter), "=qm" (c)
27736                      : : "memory");
27737         return c != 0;
27738 @@ -91,7 +189,24 @@ static inline int local_inc_and_test(loc
27739  {
27740         unsigned char c;
27741  
27742 -       asm volatile(_ASM_INC "%0; sete %1"
27743 +       asm volatile(_ASM_INC "%0\n"
27744 +
27745 +#ifdef CONFIG_PAX_REFCOUNT
27746 +#ifdef CONFIG_X86_32
27747 +                    "into\n0:\n"
27748 +#else
27749 +                    "jno 0f\n"
27750 +                    "int $4\n0:\n"
27751 +#endif
27752 +                    ".pushsection .fixup,\"ax\"\n"
27753 +                    "1:\n"
27754 +                    _ASM_DEC "%0\n"
27755 +                    "jmp 0b\n"
27756 +                    ".popsection\n"
27757 +                    _ASM_EXTABLE(0b, 1b)
27758 +#endif
27759 +
27760 +                    "sete %1\n"
27761                      : "+m" (l->a.counter), "=qm" (c)
27762                      : : "memory");
27763         return c != 0;
27764 @@ -110,7 +225,24 @@ static inline int local_add_negative(lon
27765  {
27766         unsigned char c;
27767  
27768 -       asm volatile(_ASM_ADD "%2,%0; sets %1"
27769 +       asm volatile(_ASM_ADD "%2,%0\n"
27770 +
27771 +#ifdef CONFIG_PAX_REFCOUNT
27772 +#ifdef CONFIG_X86_32
27773 +                    "into\n0:\n"
27774 +#else
27775 +                    "jno 0f\n"
27776 +                    "int $4\n0:\n"
27777 +#endif
27778 +                    ".pushsection .fixup,\"ax\"\n"
27779 +                    "1:\n"
27780 +                    _ASM_SUB "%2,%0\n"
27781 +                    "jmp 0b\n"
27782 +                    ".popsection\n"
27783 +                    _ASM_EXTABLE(0b, 1b)
27784 +#endif
27785 +
27786 +                    "sets %1\n"
27787                      : "+m" (l->a.counter), "=qm" (c)
27788                      : "ir" (i) : "memory");
27789         return c;
27790 @@ -133,7 +265,23 @@ static inline long local_add_return(long
27791  #endif
27792         /* Modern 486+ processor */
27793         __i = i;
27794 -       asm volatile(_ASM_XADD "%0, %1;"
27795 +       asm volatile(_ASM_XADD "%0, %1\n"
27796 +
27797 +#ifdef CONFIG_PAX_REFCOUNT
27798 +#ifdef CONFIG_X86_32
27799 +                    "into\n0:\n"
27800 +#else
27801 +                    "jno 0f\n"
27802 +                    "int $4\n0:\n"
27803 +#endif
27804 +                    ".pushsection .fixup,\"ax\"\n"
27805 +                    "1:\n"
27806 +                    _ASM_MOV_UL "%0,%1\n"
27807 +                    "jmp 0b\n"
27808 +                    ".popsection\n"
27809 +                    _ASM_EXTABLE(0b, 1b)
27810 +#endif
27811 +
27812                      : "+r" (i), "+m" (l->a.counter)
27813                      : : "memory");
27814         return i + __i;
27815 diff -urNp linux-2.6.27.10/include/asm-x86/mach-default/apm.h linux-2.6.27.10/include/asm-x86/mach-default/apm.h
27816 --- linux-2.6.27.10/include/asm-x86/mach-default/apm.h  2008-11-07 12:55:34.000000000 -0500
27817 +++ linux-2.6.27.10/include/asm-x86/mach-default/apm.h  2008-11-18 03:38:45.000000000 -0500
27818 @@ -34,7 +34,7 @@ static inline void apm_bios_call_asm(u32
27819         __asm__ __volatile__(APM_DO_ZERO_SEGS
27820                 "pushl %%edi\n\t"
27821                 "pushl %%ebp\n\t"
27822 -               "lcall *%%cs:apm_bios_entry\n\t"
27823 +               "lcall *%%ss:apm_bios_entry\n\t"
27824                 "setc %%al\n\t"
27825                 "popl %%ebp\n\t"
27826                 "popl %%edi\n\t"
27827 @@ -58,7 +58,7 @@ static inline u8 apm_bios_call_simple_as
27828         __asm__ __volatile__(APM_DO_ZERO_SEGS
27829                 "pushl %%edi\n\t"
27830                 "pushl %%ebp\n\t"
27831 -               "lcall *%%cs:apm_bios_entry\n\t"
27832 +               "lcall *%%ss:apm_bios_entry\n\t"
27833                 "setc %%bl\n\t"
27834                 "popl %%ebp\n\t"
27835                 "popl %%edi\n\t"
27836 diff -urNp linux-2.6.27.10/include/asm-x86/mman.h linux-2.6.27.10/include/asm-x86/mman.h
27837 --- linux-2.6.27.10/include/asm-x86/mman.h      2008-11-07 12:55:34.000000000 -0500
27838 +++ linux-2.6.27.10/include/asm-x86/mman.h      2008-11-18 03:38:45.000000000 -0500
27839 @@ -17,4 +17,14 @@
27840  #define MCL_CURRENT    1               /* lock all current mappings */
27841  #define MCL_FUTURE     2               /* lock all future mappings */
27842  
27843 +#ifdef __KERNEL__
27844 +#ifndef __ASSEMBLY__
27845 +#ifdef CONFIG_X86_32
27846 +#define arch_mmap_check        i386_mmap_check
27847 +int i386_mmap_check(unsigned long addr, unsigned long len,
27848 +               unsigned long flags);
27849 +#endif
27850 +#endif
27851 +#endif
27852 +
27853  #endif /* _ASM_X86_MMAN_H */
27854 diff -urNp linux-2.6.27.10/include/asm-x86/mmu_context_32.h linux-2.6.27.10/include/asm-x86/mmu_context_32.h
27855 --- linux-2.6.27.10/include/asm-x86/mmu_context_32.h    2008-11-07 12:55:34.000000000 -0500
27856 +++ linux-2.6.27.10/include/asm-x86/mmu_context_32.h    2008-11-18 03:38:45.000000000 -0500
27857 @@ -33,6 +33,22 @@ static inline void switch_mm(struct mm_s
27858                  */
27859                 if (unlikely(prev->context.ldt != next->context.ldt))
27860                         load_LDT_nolock(&next->context);
27861 +
27862 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27863 +               if (!nx_enabled) {
27864 +                       smp_mb__before_clear_bit();
27865 +                       cpu_clear(cpu, prev->context.cpu_user_cs_mask);
27866 +                       smp_mb__after_clear_bit();
27867 +                       cpu_set(cpu, next->context.cpu_user_cs_mask);
27868 +               }
27869 +#endif
27870 +
27871 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27872 +               if (unlikely(prev->context.user_cs_base != next->context.user_cs_base ||
27873 +                            prev->context.user_cs_limit != next->context.user_cs_limit))
27874 +                       set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27875 +#endif
27876 +
27877         }
27878  #ifdef CONFIG_SMP
27879         else {
27880 @@ -45,6 +61,19 @@ static inline void switch_mm(struct mm_s
27881                          */
27882                         load_cr3(next->pgd);
27883                         load_LDT_nolock(&next->context);
27884 +
27885 +#ifdef CONFIG_PAX_PAGEEXEC
27886 +                       if (!nx_enabled)
27887 +                               cpu_set(cpu, next->context.cpu_user_cs_mask);
27888 +#endif
27889 +
27890 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27891 +#ifdef CONFIG_PAX_PAGEEXEC
27892 +                       if (!((next->pax_flags & MF_PAX_PAGEEXEC) && nx_enabled))
27893 +#endif
27894 +                               set_user_cs(next->context.user_cs_base, next->context.user_cs_limit, cpu);
27895 +#endif
27896 +
27897                 }
27898         }
27899  #endif
27900 diff -urNp linux-2.6.27.10/include/asm-x86/mmu.h linux-2.6.27.10/include/asm-x86/mmu.h
27901 --- linux-2.6.27.10/include/asm-x86/mmu.h       2008-11-07 12:55:34.000000000 -0500
27902 +++ linux-2.6.27.10/include/asm-x86/mmu.h       2008-11-18 03:38:45.000000000 -0500
27903 @@ -11,13 +11,26 @@
27904   * cpu_vm_mask is used to optimize ldt flushing.
27905   */
27906  typedef struct {
27907 -       void *ldt;
27908 +       struct desc_struct *ldt;
27909  #ifdef CONFIG_X86_64
27910         rwlock_t ldtlock;
27911  #endif
27912         int size;
27913         struct mutex lock;
27914 -       void *vdso;
27915 +       unsigned long vdso;
27916 +
27917 +#ifdef CONFIG_X86_32
27918 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
27919 +       unsigned long user_cs_base;
27920 +       unsigned long user_cs_limit;
27921 +
27922 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_SMP)
27923 +       cpumask_t cpu_user_cs_mask;
27924 +#endif
27925 +
27926 +#endif
27927 +#endif
27928 +
27929  } mm_context_t;
27930  
27931  #ifdef CONFIG_SMP
27932 diff -urNp linux-2.6.27.10/include/asm-x86/module.h linux-2.6.27.10/include/asm-x86/module.h
27933 --- linux-2.6.27.10/include/asm-x86/module.h    2008-11-07 12:55:34.000000000 -0500
27934 +++ linux-2.6.27.10/include/asm-x86/module.h    2008-11-18 03:38:45.000000000 -0500
27935 @@ -76,7 +76,12 @@ struct mod_arch_specific {};
27936  # else
27937  #  define MODULE_STACKSIZE ""
27938  # endif
27939 -# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE
27940 +# ifdef CONFIG_GRKERNSEC
27941 +#  define MODULE_GRSEC "GRSECURITY "
27942 +# else
27943 +#  define MODULE_GRSEC ""
27944 +# endif
27945 +# define MODULE_ARCH_VERMAGIC MODULE_PROC_FAMILY MODULE_STACKSIZE MODULE_GRSEC
27946  #endif
27947  
27948  #endif /* _ASM_MODULE_H */
27949 diff -urNp linux-2.6.27.10/include/asm-x86/page_32.h linux-2.6.27.10/include/asm-x86/page_32.h
27950 --- linux-2.6.27.10/include/asm-x86/page_32.h   2008-11-07 12:55:34.000000000 -0500
27951 +++ linux-2.6.27.10/include/asm-x86/page_32.h   2008-11-18 03:38:45.000000000 -0500
27952 @@ -13,6 +13,23 @@
27953   */
27954  #define __PAGE_OFFSET          _AC(CONFIG_PAGE_OFFSET, UL)
27955  
27956 +#ifdef CONFIG_PAX_KERNEXEC
27957 +#ifndef __ASSEMBLY__
27958 +extern unsigned char MODULES_VADDR[];
27959 +extern unsigned char MODULES_END[];
27960 +extern unsigned char KERNEL_TEXT_OFFSET[];
27961 +#define ktla_ktva(addr)                (addr + (unsigned long)KERNEL_TEXT_OFFSET)
27962 +#define ktva_ktla(addr)                (addr - (unsigned long)KERNEL_TEXT_OFFSET)
27963 +#endif
27964 +#else
27965 +#define ktla_ktva(addr)                (addr)
27966 +#define ktva_ktla(addr)                (addr)
27967 +#endif
27968 +
27969 +#ifdef CONFIG_PAX_PAGEEXEC
27970 +#define CONFIG_ARCH_TRACK_EXEC_LIMIT 1
27971 +#endif
27972 +
27973  #ifdef CONFIG_4KSTACKS
27974  #define THREAD_ORDER   0
27975  #else
27976 diff -urNp linux-2.6.27.10/include/asm-x86/page_64.h linux-2.6.27.10/include/asm-x86/page_64.h
27977 --- linux-2.6.27.10/include/asm-x86/page_64.h   2008-11-07 12:55:34.000000000 -0500
27978 +++ linux-2.6.27.10/include/asm-x86/page_64.h   2008-11-18 03:38:45.000000000 -0500
27979 @@ -49,6 +49,9 @@
27980  #define __START_KERNEL         (__START_KERNEL_map + __PHYSICAL_START)
27981  #define __START_KERNEL_map     _AC(0xffffffff80000000, UL)
27982  
27983 +#define ktla_ktva(addr)                (addr)
27984 +#define ktva_ktla(addr)                (addr)
27985 +
27986  /* See Documentation/x86_64/mm.txt for a description of the memory map. */
27987  #define __PHYSICAL_MASK_SHIFT  46
27988  #define __VIRTUAL_MASK_SHIFT   48
27989 @@ -101,5 +104,6 @@ extern void init_extra_mapping_wb(unsign
27990  #define pfn_valid(pfn)          ((pfn) < max_pfn)
27991  #endif
27992  
27993 +#define nx_enabled (1)
27994  
27995  #endif /* _X86_64_PAGE_H */
27996 diff -urNp linux-2.6.27.10/include/asm-x86/paravirt.h linux-2.6.27.10/include/asm-x86/paravirt.h
27997 --- linux-2.6.27.10/include/asm-x86/paravirt.h  2008-11-07 12:55:34.000000000 -0500
27998 +++ linux-2.6.27.10/include/asm-x86/paravirt.h  2008-11-18 03:38:45.000000000 -0500
27999 @@ -1557,7 +1557,7 @@ static inline unsigned long __raw_local_
28000  #define PV_RESTORE_REGS popl %edx; popl %ecx; popl %edi; popl %eax
28001  #define PARA_PATCH(struct, off)        ((PARAVIRT_PATCH_##struct + (off)) / 4)
28002  #define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .long, 4)
28003 -#define PARA_INDIRECT(addr)    *%cs:addr
28004 +#define PARA_INDIRECT(addr)    *%ss:addr
28005  #endif
28006  
28007  #define INTERRUPT_RETURN                                               \
28008 diff -urNp linux-2.6.27.10/include/asm-x86/pda.h linux-2.6.27.10/include/asm-x86/pda.h
28009 --- linux-2.6.27.10/include/asm-x86/pda.h       2008-11-07 12:55:34.000000000 -0500
28010 +++ linux-2.6.27.10/include/asm-x86/pda.h       2008-11-18 03:38:45.000000000 -0500
28011 @@ -16,11 +16,9 @@ struct x8664_pda {
28012         unsigned long oldrsp;           /* 24 user rsp for system call */
28013         int irqcount;                   /* 32 Irq nesting counter. Starts -1 */
28014         unsigned int cpunumber;         /* 36 Logical CPU number */
28015 -#ifdef CONFIG_CC_STACKPROTECTOR
28016         unsigned long stack_canary;     /* 40 stack canary value */
28017                                         /* gcc-ABI: this canary MUST be at
28018                                            offset 40!!! */
28019 -#endif
28020         char *irqstackptr;
28021         short nodenumber;               /* number of current node (32k max) */
28022         short in_bootmem;               /* pda lives in bootmem */
28023 diff -urNp linux-2.6.27.10/include/asm-x86/percpu.h linux-2.6.27.10/include/asm-x86/percpu.h
28024 --- linux-2.6.27.10/include/asm-x86/percpu.h    2008-11-07 12:55:34.000000000 -0500
28025 +++ linux-2.6.27.10/include/asm-x86/percpu.h    2008-11-18 03:38:45.000000000 -0500
28026 @@ -93,6 +93,12 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
28027  
28028  #define __my_cpu_offset x86_read_percpu(this_cpu_off)
28029  
28030 +#include <asm-generic/sections.h>
28031 +#include <linux/threads.h>
28032 +#define __per_cpu_offset __per_cpu_offset
28033 +extern unsigned long __per_cpu_offset[NR_CPUS];
28034 +#define per_cpu_offset(x) (__per_cpu_offset[x] + (unsigned long)__per_cpu_start)
28035 +
28036  /* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
28037  #define __percpu_seg "%%fs:"
28038  
28039 diff -urNp linux-2.6.27.10/include/asm-x86/pgalloc.h linux-2.6.27.10/include/asm-x86/pgalloc.h
28040 --- linux-2.6.27.10/include/asm-x86/pgalloc.h   2008-11-07 12:55:34.000000000 -0500
28041 +++ linux-2.6.27.10/include/asm-x86/pgalloc.h   2008-11-18 03:38:45.000000000 -0500
28042 @@ -51,7 +51,7 @@ static inline void pmd_populate_kernel(s
28043                                        pmd_t *pmd, pte_t *pte)
28044  {
28045         paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
28046 -       set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
28047 +       set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
28048  }
28049  
28050  static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
28051 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable-2level.h linux-2.6.27.10/include/asm-x86/pgtable-2level.h
28052 --- linux-2.6.27.10/include/asm-x86/pgtable-2level.h    2008-11-07 12:55:34.000000000 -0500
28053 +++ linux-2.6.27.10/include/asm-x86/pgtable-2level.h    2008-11-18 03:38:45.000000000 -0500
28054 @@ -18,7 +18,19 @@ static inline void native_set_pte(pte_t 
28055  
28056  static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28057  {
28058 +
28059 +#ifdef CONFIG_PAX_KERNEXEC
28060 +       unsigned long cr0;
28061 +
28062 +       pax_open_kernel(cr0);
28063 +#endif
28064 +
28065         *pmdp = pmd;
28066 +
28067 +#ifdef CONFIG_PAX_KERNEXEC
28068 +       pax_close_kernel(cr0);
28069 +#endif
28070 +
28071  }
28072  
28073  static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
28074 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable_32.h linux-2.6.27.10/include/asm-x86/pgtable_32.h
28075 --- linux-2.6.27.10/include/asm-x86/pgtable_32.h        2008-11-07 12:55:34.000000000 -0500
28076 +++ linux-2.6.27.10/include/asm-x86/pgtable_32.h        2008-11-18 03:38:45.000000000 -0500
28077 @@ -25,8 +25,6 @@
28078  struct mm_struct;
28079  struct vm_area_struct;
28080  
28081 -extern pgd_t swapper_pg_dir[1024];
28082 -
28083  static inline void pgtable_cache_init(void) { }
28084  static inline void check_pgt_cache(void) { }
28085  void paging_init(void);
28086 @@ -45,6 +43,11 @@ void paging_init(void);
28087  # include <asm/pgtable-2level-defs.h>
28088  #endif
28089  
28090 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
28091 +#ifdef CONFIG_X86_PAE
28092 +extern pmd_t swapper_pm_dir[PTRS_PER_PGD][PTRS_PER_PMD];
28093 +#endif
28094 +
28095  #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
28096  #define PGDIR_MASK     (~(PGDIR_SIZE - 1))
28097  
28098 @@ -81,7 +84,7 @@ void paging_init(void);
28099  #undef TEST_ACCESS_OK
28100  
28101  /* The boot page tables (all created as a single array) */
28102 -extern unsigned long pg0[];
28103 +extern pte_t pg0[];
28104  
28105  #define pte_present(x) ((x).pte_low & (_PAGE_PRESENT | _PAGE_PROTNONE))
28106  
28107 @@ -173,6 +176,9 @@ do {                                                \
28108  
28109  #endif /* !__ASSEMBLY__ */
28110  
28111 +#define HAVE_ARCH_UNMAPPED_AREA
28112 +#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
28113 +
28114  /*
28115   * kern_addr_valid() is (1) for FLATMEM and (0) for
28116   * SPARSEMEM and DISCONTIGMEM
28117 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable-3level.h linux-2.6.27.10/include/asm-x86/pgtable-3level.h
28118 --- linux-2.6.27.10/include/asm-x86/pgtable-3level.h    2008-11-07 12:55:34.000000000 -0500
28119 +++ linux-2.6.27.10/include/asm-x86/pgtable-3level.h    2008-11-18 03:38:45.000000000 -0500
28120 @@ -70,12 +70,36 @@ static inline void native_set_pte_atomic
28121  
28122  static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28123  {
28124 +
28125 +#ifdef CONFIG_PAX_KERNEXEC
28126 +       unsigned long cr0;
28127 +
28128 +       pax_open_kernel(cr0);
28129 +#endif
28130 +
28131         set_64bit((unsigned long long *)(pmdp), native_pmd_val(pmd));
28132 +
28133 +#ifdef CONFIG_PAX_KERNEXEC
28134 +       pax_close_kernel(cr0);
28135 +#endif
28136 +
28137  }
28138  
28139  static inline void native_set_pud(pud_t *pudp, pud_t pud)
28140  {
28141 +
28142 +#ifdef CONFIG_PAX_KERNEXEC
28143 +       unsigned long cr0;
28144 +
28145 +       pax_open_kernel(cr0);
28146 +#endif
28147 +
28148         set_64bit((unsigned long long *)(pudp), native_pud_val(pud));
28149 +
28150 +#ifdef CONFIG_PAX_KERNEXEC
28151 +       pax_close_kernel(cr0);
28152 +#endif
28153 +
28154  }
28155  
28156  /*
28157 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable_64.h linux-2.6.27.10/include/asm-x86/pgtable_64.h
28158 --- linux-2.6.27.10/include/asm-x86/pgtable_64.h        2008-11-07 12:55:34.000000000 -0500
28159 +++ linux-2.6.27.10/include/asm-x86/pgtable_64.h        2008-11-18 03:38:45.000000000 -0500
28160 @@ -15,9 +15,12 @@
28161  
28162  extern pud_t level3_kernel_pgt[512];
28163  extern pud_t level3_ident_pgt[512];
28164 +extern pud_t level3_vmalloc_pgt[512];
28165 +extern pud_t level3_vmemmap_pgt[512];
28166  extern pmd_t level2_kernel_pgt[512];
28167  extern pmd_t level2_fixmap_pgt[512];
28168  extern pmd_t level2_ident_pgt[512];
28169 +extern pte_t level1_fixmap_pgt[512];
28170  extern pgd_t init_level4_pgt[];
28171  
28172  #define swapper_pg_dir init_level4_pgt
28173 @@ -106,7 +109,19 @@ static inline pte_t native_ptep_get_and_
28174  
28175  static inline void native_set_pmd(pmd_t *pmdp, pmd_t pmd)
28176  {
28177 +
28178 +#ifdef CONFIG_PAX_KERNEXEC
28179 +       unsigned long cr0;
28180 +
28181 +       pax_open_kernel(cr0);
28182 +#endif
28183 +
28184         *pmdp = pmd;
28185 +
28186 +#ifdef CONFIG_PAX_KERNEXEC
28187 +       pax_close_kernel(cr0);
28188 +#endif
28189 +
28190  }
28191  
28192  static inline void native_pmd_clear(pmd_t *pmd)
28193 @@ -158,17 +173,17 @@ static inline void native_pgd_clear(pgd_
28194  
28195  static inline int pgd_bad(pgd_t pgd)
28196  {
28197 -       return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28198 +       return (pgd_val(pgd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28199  }
28200  
28201  static inline int pud_bad(pud_t pud)
28202  {
28203 -       return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28204 +       return (pud_val(pud) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28205  }
28206  
28207  static inline int pmd_bad(pmd_t pmd)
28208  {
28209 -       return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER)) != _KERNPG_TABLE;
28210 +       return (pmd_val(pmd) & ~(PTE_PFN_MASK | _PAGE_USER | _PAGE_NX)) != _KERNPG_TABLE;
28211  }
28212  
28213  #define pte_none(x)    (!pte_val((x)))
28214 diff -urNp linux-2.6.27.10/include/asm-x86/pgtable.h linux-2.6.27.10/include/asm-x86/pgtable.h
28215 --- linux-2.6.27.10/include/asm-x86/pgtable.h   2008-11-07 12:55:34.000000000 -0500
28216 +++ linux-2.6.27.10/include/asm-x86/pgtable.h   2008-11-18 03:38:45.000000000 -0500
28217 @@ -41,7 +41,7 @@
28218  #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
28219  #define _PAGE_NX       (_AT(pteval_t, 1) << _PAGE_BIT_NX)
28220  #else
28221 -#define _PAGE_NX       (_AT(pteval_t, 0))
28222 +#define _PAGE_NX       (_AT(pteval_t, 1) << _PAGE_BIT_UNUSED3)
28223  #endif
28224  
28225  /* If _PAGE_PRESENT is clear, we use these: */
28226 @@ -81,6 +81,9 @@
28227  #define PAGE_READONLY_EXEC     __pgprot(_PAGE_PRESENT | _PAGE_USER |   \
28228                                          _PAGE_ACCESSED)
28229  
28230 +#define PAGE_READONLY_NOEXEC PAGE_READONLY
28231 +#define PAGE_SHARED_NOEXEC PAGE_SHARED
28232 +
28233  #define __PAGE_KERNEL_EXEC                                             \
28234         (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_GLOBAL)
28235  #define __PAGE_KERNEL          (__PAGE_KERNEL_EXEC | _PAGE_NX)
28236 @@ -92,7 +95,7 @@
28237  #define __PAGE_KERNEL_NOCACHE          (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
28238  #define __PAGE_KERNEL_UC_MINUS         (__PAGE_KERNEL | _PAGE_PCD)
28239  #define __PAGE_KERNEL_VSYSCALL         (__PAGE_KERNEL_RX | _PAGE_USER)
28240 -#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
28241 +#define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_RO | _PAGE_PCD | _PAGE_PWT | _PAGE_USER)
28242  #define __PAGE_KERNEL_LARGE            (__PAGE_KERNEL | _PAGE_PSE)
28243  #define __PAGE_KERNEL_LARGE_NOCACHE    (__PAGE_KERNEL | _PAGE_CACHE_UC | _PAGE_PSE)
28244  #define __PAGE_KERNEL_LARGE_EXEC       (__PAGE_KERNEL_EXEC | _PAGE_PSE)
28245 @@ -142,10 +145,17 @@ extern unsigned long empty_zero_page[PAG
28246  extern spinlock_t pgd_lock;
28247  extern struct list_head pgd_list;
28248  
28249 +extern pteval_t __supported_pte_mask;
28250 +
28251  /*
28252   * The following only work if pte_present() is true.
28253   * Undefined behaviour if not..
28254   */
28255 +static inline int pte_user(pte_t pte)
28256 +{
28257 +       return pte_val(pte) & _PAGE_USER;
28258 +}
28259 +
28260  static inline int pte_dirty(pte_t pte)
28261  {
28262         return pte_flags(pte) & _PAGE_DIRTY;
28263 @@ -207,9 +217,29 @@ static inline pte_t pte_wrprotect(pte_t 
28264         return __pte(pte_val(pte) & ~_PAGE_RW);
28265  }
28266  
28267 +static inline pte_t pte_mkread(pte_t pte)
28268 +{
28269 +       return __pte(pte_val(pte) | _PAGE_USER);
28270 +}
28271 +
28272  static inline pte_t pte_mkexec(pte_t pte)
28273  {
28274 -       return __pte(pte_val(pte) & ~_PAGE_NX);
28275 +#ifdef CONFIG_X86_PAE
28276 +       if (__supported_pte_mask & _PAGE_NX)
28277 +               return __pte(pte_val(pte) & ~(pteval_t)_PAGE_NX);
28278 +       else
28279 +#endif
28280 +               return __pte(pte_val(pte) | _PAGE_USER);
28281 +}
28282 +
28283 +static inline pte_t pte_exprotect(pte_t pte)
28284 +{
28285 +#ifdef CONFIG_X86_PAE
28286 +       if (__supported_pte_mask & _PAGE_NX)
28287 +               return __pte(pte_val(pte) | _PAGE_NX);
28288 +       else
28289 +#endif
28290 +               return __pte(pte_val(pte) & ~_PAGE_USER);
28291  }
28292  
28293  static inline pte_t pte_mkdirty(pte_t pte)
28294 @@ -252,8 +282,6 @@ static inline pte_t pte_mkspecial(pte_t 
28295         return __pte(pte_val(pte) | _PAGE_SPECIAL);
28296  }
28297  
28298 -extern pteval_t __supported_pte_mask;
28299 -
28300  static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
28301  {
28302         return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) |
28303 @@ -514,7 +542,19 @@ static inline void ptep_set_wrprotect(st
28304   */
28305  static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
28306  {
28307 -       memcpy(dst, src, count * sizeof(pgd_t));
28308 +
28309 +#ifdef CONFIG_PAX_KERNEXEC
28310 +       unsigned long cr0;
28311 +
28312 +       pax_open_kernel(cr0);
28313 +#endif
28314 +
28315 +       memcpy(dst, src, count * sizeof(pgd_t));
28316 +
28317 +#ifdef CONFIG_PAX_KERNEXEC
28318 +       pax_close_kernel(cr0);
28319 +#endif
28320 +
28321  }
28322  
28323  
28324 diff -urNp linux-2.6.27.10/include/asm-x86/processor.h linux-2.6.27.10/include/asm-x86/processor.h
28325 --- linux-2.6.27.10/include/asm-x86/processor.h 2008-11-07 12:55:34.000000000 -0500
28326 +++ linux-2.6.27.10/include/asm-x86/processor.h 2008-11-18 03:38:45.000000000 -0500
28327 @@ -269,7 +269,7 @@ struct tss_struct {
28328  
28329  } ____cacheline_aligned;
28330  
28331 -DECLARE_PER_CPU(struct tss_struct, init_tss);
28332 +extern struct tss_struct init_tss[NR_CPUS];
28333  
28334  /*
28335   * Save the original ist values for checking stack pointers during debugging
28336 @@ -832,11 +832,20 @@ static inline void spin_lock_prefetch(co
28337   * User space process size: 3GB (default).
28338   */
28339  #define TASK_SIZE              PAGE_OFFSET
28340 +
28341 +#ifdef CONFIG_PAX_SEGMEXEC
28342 +#define SEGMEXEC_TASK_SIZE     (TASK_SIZE / 2)
28343 +#endif
28344 +
28345 +#ifdef CONFIG_PAX_SEGMEXEC
28346 +#define STACK_TOP              ((current->mm->pax_flags & MF_PAX_SEGMEXEC)?SEGMEXEC_TASK_SIZE:TASK_SIZE)
28347 +#else
28348  #define STACK_TOP              TASK_SIZE
28349 -#define STACK_TOP_MAX          STACK_TOP
28350 +#endif
28351 +#define STACK_TOP_MAX          TASK_SIZE
28352  
28353  #define INIT_THREAD  {                                                   \
28354 -       .sp0                    = sizeof(init_stack) + (long)&init_stack, \
28355 +       .sp0                    = sizeof(init_stack) + (long)&init_stack - 8, \
28356         .vm86_info              = NULL,                                   \
28357         .sysenter_cs            = __KERNEL_CS,                            \
28358         .io_bitmap_ptr          = NULL,                                   \
28359 @@ -851,7 +860,7 @@ static inline void spin_lock_prefetch(co
28360   */
28361  #define INIT_TSS  {                                                      \
28362         .x86_tss = {                                                      \
28363 -               .sp0            = sizeof(init_stack) + (long)&init_stack, \
28364 +               .sp0            = sizeof(init_stack) + (long)&init_stack - 8, \
28365                 .ss0            = __KERNEL_DS,                            \
28366                 .ss1            = __KERNEL_CS,                            \
28367                 .io_bitmap_base = INVALID_IO_BITMAP_OFFSET,               \
28368 @@ -862,11 +871,7 @@ static inline void spin_lock_prefetch(co
28369  extern unsigned long thread_saved_pc(struct task_struct *tsk);
28370  
28371  #define THREAD_SIZE_LONGS      (THREAD_SIZE/sizeof(unsigned long))
28372 -#define KSTK_TOP(info)                                                 \
28373 -({                                                                     \
28374 -       unsigned long *__ptr = (unsigned long *)(info);                 \
28375 -       (unsigned long)(&__ptr[THREAD_SIZE_LONGS]);                     \
28376 -})
28377 +#define KSTK_TOP(info)         ((info)->task.thread.sp0)
28378  
28379  /*
28380   * The below -8 is to reserve 8 bytes on top of the ring0 stack.
28381 @@ -881,7 +886,7 @@ extern unsigned long thread_saved_pc(str
28382  #define task_pt_regs(task)                                             \
28383  ({                                                                     \
28384         struct pt_regs *__regs__;                                       \
28385 -       __regs__ = (struct pt_regs *)(KSTK_TOP(task_stack_page(task))-8); \
28386 +       __regs__ = (struct pt_regs *)((task)->thread.sp0);              \
28387         __regs__ - 1;                                                   \
28388  })
28389  
28390 @@ -897,7 +902,7 @@ extern unsigned long thread_saved_pc(str
28391   * space during mmap's.
28392   */
28393  #define IA32_PAGE_OFFSET       ((current->personality & ADDR_LIMIT_3GB) ? \
28394 -                                       0xc0000000 : 0xFFFFe000)
28395 +                                       0xc0000000 : 0xFFFFf000)
28396  
28397  #define TASK_SIZE              (test_thread_flag(TIF_IA32) ? \
28398                                         IA32_PAGE_OFFSET : TASK_SIZE64)
28399 @@ -934,6 +939,10 @@ extern void start_thread(struct pt_regs 
28400   */
28401  #define TASK_UNMAPPED_BASE     (PAGE_ALIGN(TASK_SIZE / 3))
28402  
28403 +#ifdef CONFIG_PAX_SEGMEXEC
28404 +#define SEGMEXEC_TASK_UNMAPPED_BASE    (PAGE_ALIGN(SEGMEXEC_TASK_SIZE / 3))
28405 +#endif
28406 +
28407  #define KSTK_EIP(task)         (task_pt_regs(task)->ip)
28408  
28409  /* Get/set a process' ability to use the timestamp counter instruction */
28410 diff -urNp linux-2.6.27.10/include/asm-x86/ptrace.h linux-2.6.27.10/include/asm-x86/ptrace.h
28411 --- linux-2.6.27.10/include/asm-x86/ptrace.h    2008-11-07 12:55:34.000000000 -0500
28412 +++ linux-2.6.27.10/include/asm-x86/ptrace.h    2008-11-18 03:38:45.000000000 -0500
28413 @@ -131,6 +131,7 @@ struct pt_regs {
28414  
28415  /* the DS BTS struct is used for ptrace as well */
28416  #include <asm/ds.h>
28417 +#include <asm/segment.h>
28418  
28419  struct task_struct;
28420  
28421 @@ -154,28 +155,29 @@ static inline unsigned long regs_return_
28422  }
28423  
28424  /*
28425 - * user_mode_vm(regs) determines whether a register set came from user mode.
28426 + * user_mode(regs) determines whether a register set came from user mode.
28427   * This is true if V8086 mode was enabled OR if the register set was from
28428   * protected mode with RPL-3 CS value.  This tricky test checks that with
28429   * one comparison.  Many places in the kernel can bypass this full check
28430 - * if they have already ruled out V8086 mode, so user_mode(regs) can be used.
28431 + * if they have already ruled out V8086 mode, so user_mode_novm(regs) can
28432 + * be used.
28433   */
28434 -static inline int user_mode(struct pt_regs *regs)
28435 +static inline int user_mode_novm(struct pt_regs *regs)
28436  {
28437  #ifdef CONFIG_X86_32
28438         return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
28439  #else
28440 -       return !!(regs->cs & 3);
28441 +       return !!(regs->cs & SEGMENT_RPL_MASK);
28442  #endif
28443  }
28444  
28445 -static inline int user_mode_vm(struct pt_regs *regs)
28446 +static inline int user_mode(struct pt_regs *regs)
28447  {
28448  #ifdef CONFIG_X86_32
28449         return ((regs->cs & SEGMENT_RPL_MASK) | (regs->flags & X86_VM_MASK)) >=
28450                 USER_RPL;
28451  #else
28452 -       return user_mode(regs);
28453 +       return user_mode_novm(regs);
28454  #endif
28455  }
28456  
28457 diff -urNp linux-2.6.27.10/include/asm-x86/reboot.h linux-2.6.27.10/include/asm-x86/reboot.h
28458 --- linux-2.6.27.10/include/asm-x86/reboot.h    2008-11-07 12:55:34.000000000 -0500
28459 +++ linux-2.6.27.10/include/asm-x86/reboot.h    2008-11-18 03:38:45.000000000 -0500
28460 @@ -16,6 +16,6 @@ extern struct machine_ops machine_ops;
28461  
28462  void native_machine_crash_shutdown(struct pt_regs *regs);
28463  void native_machine_shutdown(void);
28464 -void machine_real_restart(const unsigned char *code, int length);
28465 +void machine_real_restart(const unsigned char *code, unsigned int length);
28466  
28467  #endif /* _ASM_REBOOT_H */
28468 diff -urNp linux-2.6.27.10/include/asm-x86/rwsem.h linux-2.6.27.10/include/asm-x86/rwsem.h
28469 --- linux-2.6.27.10/include/asm-x86/rwsem.h     2008-11-07 12:55:34.000000000 -0500
28470 +++ linux-2.6.27.10/include/asm-x86/rwsem.h     2008-11-18 03:38:45.000000000 -0500
28471 @@ -106,10 +106,26 @@ static inline void __down_read(struct rw
28472  {
28473         asm volatile("# beginning down_read\n\t"
28474                      LOCK_PREFIX "  incl      (%%eax)\n\t"
28475 +
28476 +#ifdef CONFIG_PAX_REFCOUNT
28477 +#ifdef CONFIG_X86_32
28478 +                    "into\n0:\n"
28479 +#else
28480 +                    "jno 0f\n"
28481 +                    "int $4\n0:\n"
28482 +#endif
28483 +                    ".pushsection .fixup,\"ax\"\n"
28484 +                    "1:\n"
28485 +                    LOCK_PREFIX "decl (%%eax)\n"
28486 +                    "jmp 0b\n"
28487 +                    ".popsection\n"
28488 +                    _ASM_EXTABLE(0b, 1b)
28489 +#endif
28490 +
28491                      /* adds 0x00000001, returns the old value */
28492 -                    "  jns        1f\n"
28493 +                    "  jns        2f\n"
28494                      "  call call_rwsem_down_read_failed\n"
28495 -                    "1:\n\t"
28496 +                    "2:\n\t"
28497                      "# ending down_read\n\t"
28498                      : "+m" (sem->count)
28499                      : "a" (sem)
28500 @@ -124,13 +140,29 @@ static inline int __down_read_trylock(st
28501         __s32 result, tmp;
28502         asm volatile("# beginning __down_read_trylock\n\t"
28503                      "  movl      %0,%1\n\t"
28504 -                    "1:\n\t"
28505 +                    "2:\n\t"
28506                      "  movl         %1,%2\n\t"
28507                      "  addl      %3,%2\n\t"
28508 -                    "  jle          2f\n\t"
28509 +
28510 +#ifdef CONFIG_PAX_REFCOUNT
28511 +#ifdef CONFIG_X86_32
28512 +                    "into\n0:\n"
28513 +#else
28514 +                    "jno 0f\n"
28515 +                    "int $4\n0:\n"
28516 +#endif
28517 +                    ".pushsection .fixup,\"ax\"\n"
28518 +                    "1:\n"
28519 +                    "subl %3,%2\n"
28520 +                    "jmp 0b\n"
28521 +                    ".popsection\n"
28522 +                    _ASM_EXTABLE(0b, 1b)
28523 +#endif
28524 +
28525 +                    "  jle          3f\n\t"
28526                      LOCK_PREFIX "  cmpxchgl  %2,%0\n\t"
28527 -                    "  jnz          1b\n\t"
28528 -                    "2:\n\t"
28529 +                    "  jnz          2b\n\t"
28530 +                    "3:\n\t"
28531                      "# ending __down_read_trylock\n\t"
28532                      : "+m" (sem->count), "=&a" (result), "=&r" (tmp)
28533                      : "i" (RWSEM_ACTIVE_READ_BIAS)
28534 @@ -148,12 +180,28 @@ static inline void __down_write_nested(s
28535         tmp = RWSEM_ACTIVE_WRITE_BIAS;
28536         asm volatile("# beginning down_write\n\t"
28537                      LOCK_PREFIX "  xadd      %%edx,(%%eax)\n\t"
28538 +
28539 +#ifdef CONFIG_PAX_REFCOUNT
28540 +#ifdef CONFIG_X86_32
28541 +                    "into\n0:\n"
28542 +#else
28543 +                    "jno 0f\n"
28544 +                    "int $4\n0:\n"
28545 +#endif
28546 +                    ".pushsection .fixup,\"ax\"\n"
28547 +                    "1:\n"
28548 +                    "movl %%edx,(%%eax)\n"
28549 +                    "jmp 0b\n"
28550 +                    ".popsection\n"
28551 +                    _ASM_EXTABLE(0b, 1b)
28552 +#endif
28553 +
28554                      /* subtract 0x0000ffff, returns the old value */
28555                      "  testl     %%edx,%%edx\n\t"
28556                      /* was the count 0 before? */
28557 -                    "  jz        1f\n"
28558 +                    "  jz        2f\n"
28559                      "  call call_rwsem_down_write_failed\n"
28560 -                    "1:\n"
28561 +                    "2:\n"
28562                      "# ending down_write"
28563                      : "+m" (sem->count), "=d" (tmp)
28564                      : "a" (sem), "1" (tmp)
28565 @@ -186,10 +234,26 @@ static inline void __up_read(struct rw_s
28566         __s32 tmp = -RWSEM_ACTIVE_READ_BIAS;
28567         asm volatile("# beginning __up_read\n\t"
28568                      LOCK_PREFIX "  xadd      %%edx,(%%eax)\n\t"
28569 +
28570 +#ifdef CONFIG_PAX_REFCOUNT
28571 +#ifdef CONFIG_X86_32
28572 +                    "into\n0:\n"
28573 +#else
28574 +                    "jno 0f\n"
28575 +                    "int $4\n0:\n"
28576 +#endif
28577 +                    ".pushsection .fixup,\"ax\"\n"
28578 +                    "1:\n"
28579 +                    "movl %%edx,(%%eax)\n"
28580 +                    "jmp 0b\n"
28581 +                    ".popsection\n"
28582 +                    _ASM_EXTABLE(0b, 1b)
28583 +#endif
28584 +
28585                      /* subtracts 1, returns the old value */
28586 -                    "  jns        1f\n\t"
28587 +                    "  jns        2f\n\t"
28588                      "  call call_rwsem_wake\n"
28589 -                    "1:\n"
28590 +                    "2:\n"
28591                      "# ending __up_read\n"
28592                      : "+m" (sem->count), "=d" (tmp)
28593                      : "a" (sem), "1" (tmp)
28594 @@ -204,11 +268,27 @@ static inline void __up_write(struct rw_
28595         asm volatile("# beginning __up_write\n\t"
28596                      "  movl      %2,%%edx\n\t"
28597                      LOCK_PREFIX "  xaddl     %%edx,(%%eax)\n\t"
28598 +
28599 +#ifdef CONFIG_PAX_REFCOUNT
28600 +#ifdef CONFIG_X86_32
28601 +                    "into\n0:\n"
28602 +#else
28603 +                    "jno 0f\n"
28604 +                    "int $4\n0:\n"
28605 +#endif
28606 +                    ".pushsection .fixup,\"ax\"\n"
28607 +                    "1:\n"
28608 +                    "movl %%edx,(%%eax)\n"
28609 +                    "jmp 0b\n"
28610 +                    ".popsection\n"
28611 +                    _ASM_EXTABLE(0b, 1b)
28612 +#endif
28613 +
28614                      /* tries to transition
28615                         0xffff0001 -> 0x00000000 */
28616 -                    "  jz       1f\n"
28617 +                    "  jz       2f\n"
28618                      "  call call_rwsem_wake\n"
28619 -                    "1:\n\t"
28620 +                    "2:\n\t"
28621                      "# ending __up_write\n"
28622                      : "+m" (sem->count)
28623                      : "a" (sem), "i" (-RWSEM_ACTIVE_WRITE_BIAS)
28624 @@ -222,10 +302,26 @@ static inline void __downgrade_write(str
28625  {
28626         asm volatile("# beginning __downgrade_write\n\t"
28627                      LOCK_PREFIX "  addl      %2,(%%eax)\n\t"
28628 +
28629 +#ifdef CONFIG_PAX_REFCOUNT
28630 +#ifdef CONFIG_X86_32
28631 +                    "into\n0:\n"
28632 +#else
28633 +                    "jno 0f\n"
28634 +                    "int $4\n0:\n"
28635 +#endif
28636 +                    ".pushsection .fixup,\"ax\"\n"
28637 +                    "1:\n"
28638 +                    LOCK_PREFIX "subl %2,(%%eax)\n"
28639 +                    "jmp 0b\n"
28640 +                    ".popsection\n"
28641 +                    _ASM_EXTABLE(0b, 1b)
28642 +#endif
28643 +
28644                      /* transitions 0xZZZZ0001 -> 0xYYYY0001 */
28645 -                    "  jns       1f\n\t"
28646 +                    "  jns       2f\n\t"
28647                      "  call call_rwsem_downgrade_wake\n"
28648 -                    "1:\n\t"
28649 +                    "2:\n\t"
28650                      "# ending __downgrade_write\n"
28651                      : "+m" (sem->count)
28652                      : "a" (sem), "i" (-RWSEM_WAITING_BIAS)
28653 @@ -237,7 +333,23 @@ static inline void __downgrade_write(str
28654   */
28655  static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
28656  {
28657 -       asm volatile(LOCK_PREFIX "addl %1,%0"
28658 +       asm volatile(LOCK_PREFIX "addl %1,%0\n"
28659 +
28660 +#ifdef CONFIG_PAX_REFCOUNT
28661 +#ifdef CONFIG_X86_32
28662 +                    "into\n0:\n"
28663 +#else
28664 +                    "jno 0f\n"
28665 +                    "int $4\n0:\n"
28666 +#endif
28667 +                    ".pushsection .fixup,\"ax\"\n"
28668 +                    "1:\n"
28669 +                    LOCK_PREFIX "subl %1,%0\n"
28670 +                    "jmp 0b\n"
28671 +                    ".popsection\n"
28672 +                    _ASM_EXTABLE(0b, 1b)
28673 +#endif
28674 +
28675                      : "+m" (sem->count)
28676                      : "ir" (delta));
28677  }
28678 @@ -249,7 +361,23 @@ static inline int rwsem_atomic_update(in
28679  {
28680         int tmp = delta;
28681  
28682 -       asm volatile(LOCK_PREFIX "xadd %0,%1"
28683 +       asm volatile(LOCK_PREFIX "xadd %0,%1\n"
28684 +
28685 +#ifdef CONFIG_PAX_REFCOUNT
28686 +#ifdef CONFIG_X86_32
28687 +                    "into\n0:\n"
28688 +#else
28689 +                    "jno 0f\n"
28690 +                    "int $4\n0:\n"
28691 +#endif
28692 +                    ".pushsection .fixup,\"ax\"\n"
28693 +                    "1:\n"
28694 +                    "movl %0,%1\n"
28695 +                    "jmp 0b\n"
28696 +                    ".popsection\n"
28697 +                    _ASM_EXTABLE(0b, 1b)
28698 +#endif
28699 +
28700                      : "+r" (tmp), "+m" (sem->count)
28701                      : : "memory");
28702  
28703 diff -urNp linux-2.6.27.10/include/asm-x86/segment.h linux-2.6.27.10/include/asm-x86/segment.h
28704 --- linux-2.6.27.10/include/asm-x86/segment.h   2008-11-07 12:55:34.000000000 -0500
28705 +++ linux-2.6.27.10/include/asm-x86/segment.h   2008-11-18 03:38:45.000000000 -0500
28706 @@ -88,13 +88,19 @@
28707  #define GDT_ENTRY_ESPFIX_SS            (GDT_ENTRY_KERNEL_BASE + 14)
28708  #define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
28709  
28710 -#define GDT_ENTRY_PERCPU                       (GDT_ENTRY_KERNEL_BASE + 15)
28711 +#define GDT_ENTRY_PERCPU               (GDT_ENTRY_KERNEL_BASE + 15)
28712  #ifdef CONFIG_SMP
28713  #define __KERNEL_PERCPU (GDT_ENTRY_PERCPU * 8)
28714  #else
28715  #define __KERNEL_PERCPU 0
28716  #endif
28717  
28718 +#define GDT_ENTRY_PCIBIOS_CS           (GDT_ENTRY_KERNEL_BASE + 16)
28719 +#define __PCIBIOS_CS (GDT_ENTRY_PCIBIOS_CS * 8)
28720 +
28721 +#define GDT_ENTRY_PCIBIOS_DS           (GDT_ENTRY_KERNEL_BASE + 17)
28722 +#define __PCIBIOS_DS (GDT_ENTRY_PCIBIOS_DS * 8)
28723 +
28724  #define GDT_ENTRY_DOUBLEFAULT_TSS      31
28725  
28726  /*
28727 @@ -135,10 +141,10 @@
28728  #define SEGMENT_IS_KERNEL_CODE(x) (((x) & 0xfc) == GDT_ENTRY_KERNEL_CS * 8)
28729  
28730  /* Matches __KERNEL_CS and __USER_CS (they must be 2 entries apart) */
28731 -#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xec) == GDT_ENTRY_KERNEL_CS * 8)
28732 +#define SEGMENT_IS_FLAT_CODE(x)  (((x) & 0xFFFCU) == __KERNEL_CS || ((x) & 0xFFFCU) == __USER_CS)
28733  
28734  /* Matches PNP_CS32 and PNP_CS16 (they must be consecutive) */
28735 -#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xf4) == GDT_ENTRY_PNPBIOS_BASE * 8)
28736 +#define SEGMENT_IS_PNP_CODE(x)   (((x) & 0xFFFCU) == PNP_CS32 || ((x) & 0xFFFCU) == PNP_CS16)
28737  
28738  
28739  #else
28740 diff -urNp linux-2.6.27.10/include/asm-x86/spinlock.h linux-2.6.27.10/include/asm-x86/spinlock.h
28741 --- linux-2.6.27.10/include/asm-x86/spinlock.h  2008-11-07 12:55:34.000000000 -0500
28742 +++ linux-2.6.27.10/include/asm-x86/spinlock.h  2008-11-18 03:38:45.000000000 -0500
28743 @@ -315,18 +315,50 @@ static inline int __raw_write_can_lock(r
28744  static inline void __raw_read_lock(raw_rwlock_t *rw)
28745  {
28746         asm volatile(LOCK_PREFIX " subl $1,(%0)\n\t"
28747 -                    "jns 1f\n"
28748 -                    "call __read_lock_failed\n\t"
28749 +
28750 +#ifdef CONFIG_PAX_REFCOUNT
28751 +#ifdef CONFIG_X86_32
28752 +                    "into\n0:\n"
28753 +#else
28754 +                    "jno 0f\n"
28755 +                    "int $4\n0:\n"
28756 +#endif
28757 +                    ".pushsection .fixup,\"ax\"\n"
28758                      "1:\n"
28759 +                    LOCK_PREFIX " addl $1,(%0)\n"
28760 +                    "jmp 0b\n"
28761 +                    ".popsection\n"
28762 +                    _ASM_EXTABLE(0b, 1b)
28763 +#endif
28764 +
28765 +                    "jns 2f\n"
28766 +                    "call __read_lock_failed\n\t"
28767 +                    "2:\n"
28768                      ::LOCK_PTR_REG (rw) : "memory");
28769  }
28770  
28771  static inline void __raw_write_lock(raw_rwlock_t *rw)
28772  {
28773         asm volatile(LOCK_PREFIX " subl %1,(%0)\n\t"
28774 -                    "jz 1f\n"
28775 -                    "call __write_lock_failed\n\t"
28776 +
28777 +#ifdef CONFIG_PAX_REFCOUNT
28778 +#ifdef CONFIG_X86_32
28779 +                    "into\n0:\n"
28780 +#else
28781 +                    "jno 0f\n"
28782 +                    "int $4\n0:\n"
28783 +#endif
28784 +                    ".pushsection .fixup,\"ax\"\n"
28785                      "1:\n"
28786 +                    LOCK_PREFIX " addl %1,(%0)\n"
28787 +                    "jmp 0b\n"
28788 +                    ".popsection\n"
28789 +                    _ASM_EXTABLE(0b, 1b)
28790 +#endif
28791 +
28792 +                    "jz 2f\n"
28793 +                    "call __write_lock_failed\n\t"
28794 +                    "2:\n"
28795                      ::LOCK_PTR_REG (rw), "i" (RW_LOCK_BIAS) : "memory");
28796  }
28797  
28798 @@ -353,12 +385,45 @@ static inline int __raw_write_trylock(ra
28799  
28800  static inline void __raw_read_unlock(raw_rwlock_t *rw)
28801  {
28802 -       asm volatile(LOCK_PREFIX "incl %0" :"+m" (rw->lock) : : "memory");
28803 +       asm volatile(LOCK_PREFIX "incl %0\n"
28804 +
28805 +#ifdef CONFIG_PAX_REFCOUNT
28806 +#ifdef CONFIG_X86_32
28807 +                    "into\n0:\n"
28808 +#else
28809 +                    "jno 0f\n"
28810 +                    "int $4\n0:\n"
28811 +#endif
28812 +                    ".pushsection .fixup,\"ax\"\n"
28813 +                    "1:\n"
28814 +                    LOCK_PREFIX "decl %0\n"
28815 +                    "jmp 0b\n"
28816 +                    ".popsection\n"
28817 +                    _ASM_EXTABLE(0b, 1b)
28818 +#endif
28819 +
28820 +                    :"+m" (rw->lock) : : "memory");
28821  }
28822  
28823  static inline void __raw_write_unlock(raw_rwlock_t *rw)
28824  {
28825 -       asm volatile(LOCK_PREFIX "addl %1, %0"
28826 +       asm volatile(LOCK_PREFIX "addl %1, %0\n"
28827 +
28828 +#ifdef CONFIG_PAX_REFCOUNT
28829 +#ifdef CONFIG_X86_32
28830 +                    "into\n0:\n"
28831 +#else
28832 +                    "jno 0f\n"
28833 +                    "int $4\n0:\n"
28834 +#endif
28835 +                    ".pushsection .fixup,\"ax\"\n"
28836 +                    "1:\n"
28837 +                    LOCK_PREFIX "subl %1,%0\n"
28838 +                    "jmp 0b\n"
28839 +                    ".popsection\n"
28840 +                    _ASM_EXTABLE(0b, 1b)
28841 +#endif
28842 +
28843                      : "+m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory");
28844  }
28845  
28846 diff -urNp linux-2.6.27.10/include/asm-x86/system.h linux-2.6.27.10/include/asm-x86/system.h
28847 --- linux-2.6.27.10/include/asm-x86/system.h    2008-11-07 12:55:34.000000000 -0500
28848 +++ linux-2.6.27.10/include/asm-x86/system.h    2008-11-18 03:38:45.000000000 -0500
28849 @@ -92,6 +92,8 @@ do {                                                                  \
28850              ".globl thread_return\n"                                     \
28851              "thread_return:\n\t"                                         \
28852              "movq %%gs:%P[pda_pcurrent],%%rsi\n\t"                       \
28853 +            "movq %P[task_canary](%%rsi),%%r8\n\t"                       \
28854 +            "movq %%r8,%%gs:%P[pda_canary]\n\t"                          \
28855              "movq %P[thread_info](%%rsi),%%r8\n\t"                       \
28856              LOCK_PREFIX "btr  %[tif_fork],%P[ti_flags](%%r8)\n\t"        \
28857              "movq %%rax,%%rdi\n\t"                                       \
28858 @@ -103,7 +105,9 @@ do {                                                                        \
28859                [ti_flags] "i" (offsetof(struct thread_info, flags)),      \
28860                [tif_fork] "i" (TIF_FORK),                                 \
28861                [thread_info] "i" (offsetof(struct task_struct, stack)),   \
28862 -              [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent))  \
28863 +              [task_canary] "i" (offsetof(struct task_struct, stack_canary)), \
28864 +              [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)), \
28865 +              [pda_canary] "i" (offsetof(struct x8664_pda, stack_canary))\
28866              : "memory", "cc" __EXTRA_CLOBBER)
28867  #endif
28868  
28869 @@ -166,7 +170,7 @@ static inline unsigned long get_limit(un
28870  {
28871         unsigned long __limit;
28872         asm("lsll %1,%0" : "=r" (__limit) : "r" (segment));
28873 -       return __limit + 1;
28874 +       return __limit;
28875  }
28876  
28877  static inline void native_clts(void)
28878 @@ -292,6 +296,21 @@ static inline void native_wbinvd(void)
28879  
28880  #define stts() write_cr0(read_cr0() | X86_CR0_TS)
28881  
28882 +#define pax_open_kernel(cr0)           \
28883 +do {                                   \
28884 +       typecheck(unsigned long, cr0);  \
28885 +       preempt_disable();              \
28886 +       cr0 = read_cr0();               \
28887 +       write_cr0(cr0 & ~X86_CR0_WP);   \
28888 +} while (0)
28889 +
28890 +#define pax_close_kernel(cr0)          \
28891 +do {                                   \
28892 +       typecheck(unsigned long, cr0);  \
28893 +       write_cr0(cr0);                 \
28894 +       preempt_enable_no_resched();    \
28895 +} while (0)
28896 +
28897  #endif /* __KERNEL__ */
28898  
28899  static inline void clflush(volatile void *__p)
28900 @@ -306,7 +325,7 @@ void enable_hlt(void);
28901  
28902  void cpu_idle_wait(void);
28903  
28904 -extern unsigned long arch_align_stack(unsigned long sp);
28905 +#define arch_align_stack(x) ((x) & ~0xfUL)
28906  extern void free_init_pages(char *what, unsigned long begin, unsigned long end);
28907  
28908  void default_idle(void);
28909 diff -urNp linux-2.6.27.10/include/asm-x86/uaccess_64.h linux-2.6.27.10/include/asm-x86/uaccess_64.h
28910 --- linux-2.6.27.10/include/asm-x86/uaccess_64.h        2008-11-07 12:55:34.000000000 -0500
28911 +++ linux-2.6.27.10/include/asm-x86/uaccess_64.h        2008-11-18 03:38:45.000000000 -0500
28912 @@ -10,6 +10,8 @@
28913  #include <linux/lockdep.h>
28914  #include <asm/page.h>
28915  
28916 +#define set_fs(x)      (current_thread_info()->addr_limit = (x))
28917 +
28918  /*
28919   * Copy To/From Userspace
28920   */
28921 diff -urNp linux-2.6.27.10/include/asm-x86/uaccess.h linux-2.6.27.10/include/asm-x86/uaccess.h
28922 --- linux-2.6.27.10/include/asm-x86/uaccess.h   2008-11-07 12:55:34.000000000 -0500
28923 +++ linux-2.6.27.10/include/asm-x86/uaccess.h   2008-11-18 03:38:45.000000000 -0500
28924 @@ -10,6 +10,7 @@
28925  #include <linux/string.h>
28926  #include <asm/asm.h>
28927  #include <asm/page.h>
28928 +#include <asm/segment.h>
28929  
28930  #define VERIFY_READ 0
28931  #define VERIFY_WRITE 1
28932 @@ -29,7 +30,12 @@
28933  
28934  #define get_ds()       (KERNEL_DS)
28935  #define get_fs()       (current_thread_info()->addr_limit)
28936 +#ifdef CONFIG_X86_32
28937 +void __set_fs(mm_segment_t x, int cpu);
28938 +void set_fs(mm_segment_t x);
28939 +#else
28940  #define set_fs(x)      (current_thread_info()->addr_limit = (x))
28941 +#endif
28942  
28943  #define segment_eq(a, b)       ((a).seg == (b).seg)
28944  
28945 @@ -97,6 +103,7 @@ struct exception_table_entry {
28946  };
28947  
28948  extern int fixup_exception(struct pt_regs *regs);
28949 +#define ARCH_HAS_SORT_EXTABLE
28950  
28951  /*
28952   * These are the main single-value transfer routines.  They automatically
28953 @@ -186,9 +193,12 @@ extern int __get_user_bad(void);
28954  
28955  #ifdef CONFIG_X86_32
28956  #define __put_user_u64(x, addr, err)                                   \
28957 -       asm volatile("1:        movl %%eax,0(%2)\n"                     \
28958 -                    "2:        movl %%edx,4(%2)\n"                     \
28959 +       asm volatile("          movw %w5,%%ds\n"                        \
28960 +                    "1:        movl %%eax,%%ds:0(%2)\n"                \
28961 +                    "2:        movl %%edx,%%ds:4(%2)\n"                \
28962                      "3:\n"                                             \
28963 +                    "          pushl %%ss\n"                           \
28964 +                    "          popl %%ds\n"                            \
28965                      ".section .fixup,\"ax\"\n"                         \
28966                      "4:        movl %3,%0\n"                           \
28967                      "  jmp 3b\n"                                       \
28968 @@ -196,7 +206,8 @@ extern int __get_user_bad(void);
28969                      _ASM_EXTABLE(1b, 4b)                               \
28970                      _ASM_EXTABLE(2b, 4b)                               \
28971                      : "=r" (err)                                       \
28972 -                    : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err))
28973 +                    : "A" (x), "r" (addr), "i" (-EFAULT), "0" (err),   \
28974 +                      "r"(__USER_DS))
28975  
28976  #define __put_user_x8(x, ptr, __ret_pu)                                \
28977         asm volatile("call __put_user_8" : "=a" (__ret_pu)      \
28978 @@ -336,6 +347,22 @@ do {                                                                       \
28979         }                                                               \
28980  } while (0)
28981  
28982 +#ifdef CONFIG_X86_32
28983 +#define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
28984 +       asm volatile("          movw %w5,%%ds\n"                        \
28985 +                    "1:        mov"itype" %%ds:%2,%"rtype"1\n"         \
28986 +                    "2:\n"                                             \
28987 +                    "          pushl %%ss\n"                           \
28988 +                    "          popl %%ds\n"                            \
28989 +                    ".section .fixup,\"ax\"\n"                         \
28990 +                    "3:        movl %3,%0\n"                           \
28991 +                    "  xor"itype" %"rtype"1,%"rtype"1\n"               \
28992 +                    "  jmp 2b\n"                                       \
28993 +                    ".previous\n"                                      \
28994 +                    _ASM_EXTABLE(1b, 3b)                               \
28995 +                    : "=r" (err), ltype (x)                            \
28996 +                    : "m" (__m(addr)), "i" (errret), "0" (err), "r"(__USER_DS))
28997 +#else
28998  #define __get_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
28999         asm volatile("1:        mov"itype" %2,%"rtype"1\n"              \
29000                      "2:\n"                                             \
29001 @@ -347,6 +374,7 @@ do {                                                                        \
29002                      _ASM_EXTABLE(1b, 3b)                               \
29003                      : "=r" (err), ltype(x)                             \
29004                      : "m" (__m(addr)), "i" (errret), "0" (err))
29005 +#endif
29006  
29007  #define __put_user_nocheck(x, ptr, size)                       \
29008  ({                                                             \
29009 @@ -373,6 +401,22 @@ struct __large_struct { unsigned long bu
29010   * we do not write to any memory gcc knows about, so there are no
29011   * aliasing issues.
29012   */
29013 +#ifdef CONFIG_X86_32
29014 +#define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
29015 +       asm volatile("          movw %w5,%%ds\n"                        \
29016 +                    "1:        mov"itype" %"rtype"1,%%ds:%2\n"         \
29017 +                    "2:\n"                                             \
29018 +                    "          pushl %%ss\n"                           \
29019 +                    "          popl %%ds\n"                            \
29020 +                    ".section .fixup,\"ax\"\n"                         \
29021 +                    "3:        movl %3,%0\n"                           \
29022 +                    "  jmp 2b\n"                                       \
29023 +                    ".previous\n"                                      \
29024 +                    _ASM_EXTABLE(1b, 3b)                               \
29025 +                    : "=r"(err)                                        \
29026 +                    : ltype (x), "m" (__m(addr)), "i" (errret), "0" (err),\
29027 +                      "r"(__USER_DS))
29028 +#else
29029  #define __put_user_asm(x, addr, err, itype, rtype, ltype, errret)      \
29030         asm volatile("1:        mov"itype" %"rtype"1,%2\n"              \
29031                      "2:\n"                                             \
29032 @@ -383,6 +427,7 @@ struct __large_struct { unsigned long bu
29033                      _ASM_EXTABLE(1b, 3b)                               \
29034                      : "=r"(err)                                        \
29035                      : ltype(x), "m" (__m(addr)), "i" (errret), "0" (err))
29036 +#endif
29037  /**
29038   * __get_user: - Get a simple variable from user space, with less checking.
29039   * @x:   Variable to store result.
29040 @@ -447,6 +492,7 @@ extern struct movsl_mask {
29041  # include "uaccess_32.h"
29042  #else
29043  # define ARCH_HAS_SEARCH_EXTABLE
29044 +# define ARCH_HAS_SORT_EXTABLE
29045  # include "uaccess_64.h"
29046  #endif
29047  
29048 diff -urNp linux-2.6.27.10/include/asm-xtensa/kmap_types.h linux-2.6.27.10/include/asm-xtensa/kmap_types.h
29049 --- linux-2.6.27.10/include/asm-xtensa/kmap_types.h     2008-11-07 12:55:34.000000000 -0500
29050 +++ linux-2.6.27.10/include/asm-xtensa/kmap_types.h     2008-11-18 03:38:45.000000000 -0500
29051 @@ -25,6 +25,7 @@ enum km_type {
29052    KM_IRQ1,
29053    KM_SOFTIRQ0,
29054    KM_SOFTIRQ1,
29055 +  KM_CLEARPAGE,
29056    KM_TYPE_NR
29057  };
29058  
29059 diff -urNp linux-2.6.27.10/include/drm/drm_pciids.h linux-2.6.27.10/include/drm/drm_pciids.h
29060 --- linux-2.6.27.10/include/drm/drm_pciids.h    2008-11-07 12:55:34.000000000 -0500
29061 +++ linux-2.6.27.10/include/drm/drm_pciids.h    2008-11-18 03:38:45.000000000 -0500
29062 @@ -237,7 +237,7 @@
29063         {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
29064         {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29065         {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
29066 -       {0, 0, 0}
29067 +       {0, 0, 0, 0, 0, 0}
29068  
29069  #define r128_PCI_IDS \
29070         {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29071 @@ -277,14 +277,14 @@
29072         {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29073         {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29074         {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29075 -       {0, 0, 0}
29076 +       {0, 0, 0, 0, 0, 0}
29077  
29078  #define mga_PCI_IDS \
29079         {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
29080         {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
29081         {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
29082         {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
29083 -       {0, 0, 0}
29084 +       {0, 0, 0, 0, 0, 0}
29085  
29086  #define mach64_PCI_IDS \
29087         {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29088 @@ -307,7 +307,7 @@
29089         {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29090         {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29091         {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29092 -       {0, 0, 0}
29093 +       {0, 0, 0, 0, 0, 0}
29094  
29095  #define sisdrv_PCI_IDS \
29096         {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29097 @@ -318,7 +318,7 @@
29098         {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29099         {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
29100         {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
29101 -       {0, 0, 0}
29102 +       {0, 0, 0, 0, 0, 0}
29103  
29104  #define tdfx_PCI_IDS \
29105         {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29106 @@ -327,7 +327,7 @@
29107         {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29108         {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29109         {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29110 -       {0, 0, 0}
29111 +       {0, 0, 0, 0, 0, 0}
29112  
29113  #define viadrv_PCI_IDS \
29114         {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29115 @@ -339,25 +339,25 @@
29116         {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29117         {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
29118         {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
29119 -       {0, 0, 0}
29120 +       {0, 0, 0, 0, 0, 0}
29121  
29122  #define i810_PCI_IDS \
29123         {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29124         {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29125         {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29126         {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29127 -       {0, 0, 0}
29128 +       {0, 0, 0, 0, 0, 0}
29129  
29130  #define i830_PCI_IDS \
29131         {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29132         {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29133         {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29134         {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29135 -       {0, 0, 0}
29136 +       {0, 0, 0, 0, 0, 0}
29137  
29138  #define gamma_PCI_IDS \
29139         {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29140 -       {0, 0, 0}
29141 +       {0, 0, 0, 0, 0, 0}
29142  
29143  #define savage_PCI_IDS \
29144         {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
29145 @@ -383,10 +383,10 @@
29146         {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
29147         {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
29148         {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
29149 -       {0, 0, 0}
29150 +       {0, 0, 0, 0, 0, 0}
29151  
29152  #define ffb_PCI_IDS \
29153 -       {0, 0, 0}
29154 +       {0, 0, 0, 0, 0, 0}
29155  
29156  #define i915_PCI_IDS \
29157         {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29158 @@ -412,4 +412,4 @@
29159         {0x8086, 0x2e02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29160         {0x8086, 0x2e12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29161         {0x8086, 0x2e22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
29162 -       {0, 0, 0}
29163 +       {0, 0, 0, 0, 0, 0}
29164 diff -urNp linux-2.6.27.10/include/linux/a.out.h linux-2.6.27.10/include/linux/a.out.h
29165 --- linux-2.6.27.10/include/linux/a.out.h       2008-11-07 12:55:34.000000000 -0500
29166 +++ linux-2.6.27.10/include/linux/a.out.h       2008-11-18 03:38:45.000000000 -0500
29167 @@ -39,6 +39,14 @@ enum machine_type {
29168    M_MIPS2 = 152                /* MIPS R6000/R4000 binary */
29169  };
29170  
29171 +/* Constants for the N_FLAGS field */
29172 +#define F_PAX_PAGEEXEC 1       /* Paging based non-executable pages */
29173 +#define F_PAX_EMUTRAMP 2       /* Emulate trampolines */
29174 +#define F_PAX_MPROTECT 4       /* Restrict mprotect() */
29175 +#define F_PAX_RANDMMAP 8       /* Randomize mmap() base */
29176 +/*#define F_PAX_RANDEXEC       16*/    /* Randomize ET_EXEC base */
29177 +#define F_PAX_SEGMEXEC 32      /* Segmentation based non-executable pages */
29178 +
29179  #if !defined (N_MAGIC)
29180  #define N_MAGIC(exec) ((exec).a_info & 0xffff)
29181  #endif
29182 diff -urNp linux-2.6.27.10/include/linux/binfmts.h linux-2.6.27.10/include/linux/binfmts.h
29183 --- linux-2.6.27.10/include/linux/binfmts.h     2008-12-21 01:16:52.000000000 -0500
29184 +++ linux-2.6.27.10/include/linux/binfmts.h     2008-12-21 01:13:46.000000000 -0500
29185 @@ -71,6 +71,7 @@ struct linux_binfmt {
29186         int (*load_binary)(struct linux_binprm *, struct  pt_regs * regs);
29187         int (*load_shlib)(struct file *);
29188         int (*core_dump)(long signr, struct pt_regs *regs, struct file *file, unsigned long limit);
29189 +       void (*handle_mprotect)(struct vm_area_struct *vma, unsigned long newflags);
29190         unsigned long min_coredump;     /* minimal dump size */
29191         int hasvdso;
29192  };
29193 diff -urNp linux-2.6.27.10/include/linux/cache.h linux-2.6.27.10/include/linux/cache.h
29194 --- linux-2.6.27.10/include/linux/cache.h       2008-11-07 12:55:34.000000000 -0500
29195 +++ linux-2.6.27.10/include/linux/cache.h       2008-11-18 03:38:45.000000000 -0500
29196 @@ -16,6 +16,10 @@
29197  #define __read_mostly
29198  #endif
29199  
29200 +#ifndef __read_only
29201 +#define __read_only __read_mostly
29202 +#endif
29203 +
29204  #ifndef ____cacheline_aligned
29205  #define ____cacheline_aligned __attribute__((__aligned__(SMP_CACHE_BYTES)))
29206  #endif
29207 diff -urNp linux-2.6.27.10/include/linux/capability.h linux-2.6.27.10/include/linux/capability.h
29208 --- linux-2.6.27.10/include/linux/capability.h  2008-11-07 12:55:34.000000000 -0500
29209 +++ linux-2.6.27.10/include/linux/capability.h  2008-11-18 03:38:45.000000000 -0500
29210 @@ -516,6 +516,7 @@ kernel_cap_t cap_set_effective(const ker
29211  #define has_capability(t, cap) (security_capable((t), (cap)) == 0)
29212  
29213  extern int capable(int cap);
29214 +int capable_nolog(int cap);
29215  
29216  #endif /* __KERNEL__ */
29217  
29218 diff -urNp linux-2.6.27.10/include/linux/cpumask.h linux-2.6.27.10/include/linux/cpumask.h
29219 --- linux-2.6.27.10/include/linux/cpumask.h     2008-11-07 12:55:34.000000000 -0500
29220 +++ linux-2.6.27.10/include/linux/cpumask.h     2008-11-18 03:38:45.000000000 -0500
29221 @@ -139,7 +139,6 @@
29222  #include <linux/bitmap.h>
29223  
29224  typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;
29225 -extern cpumask_t _unused_cpumask_arg_;
29226  
29227  #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst))
29228  static inline void __cpu_set(int cpu, volatile cpumask_t *dstp)
29229 diff -urNp linux-2.6.27.10/include/linux/elf.h linux-2.6.27.10/include/linux/elf.h
29230 --- linux-2.6.27.10/include/linux/elf.h 2008-11-07 12:55:34.000000000 -0500
29231 +++ linux-2.6.27.10/include/linux/elf.h 2008-12-21 00:44:29.000000000 -0500
29232 @@ -49,6 +49,17 @@ typedef __s64        Elf64_Sxword;
29233  #define PT_GNU_EH_FRAME                0x6474e550
29234  
29235  #define PT_GNU_STACK   (PT_LOOS + 0x474e551)
29236 +#define PT_GNU_RELRO   (PT_LOOS + 0x474e552)
29237 +
29238 +#define PT_PAX_FLAGS   (PT_LOOS + 0x5041580)
29239 +
29240 +/* Constants for the e_flags field */
29241 +#define EF_PAX_PAGEEXEC                1       /* Paging based non-executable pages */
29242 +#define EF_PAX_EMUTRAMP                2       /* Emulate trampolines */
29243 +#define EF_PAX_MPROTECT                4       /* Restrict mprotect() */
29244 +#define EF_PAX_RANDMMAP                8       /* Randomize mmap() base */
29245 +/*#define EF_PAX_RANDEXEC              16*/    /* Randomize ET_EXEC base */
29246 +#define EF_PAX_SEGMEXEC                32      /* Segmentation based non-executable pages */
29247  
29248  /* These constants define the different elf file types */
29249  #define ET_NONE   0
29250 @@ -84,6 +95,8 @@ typedef __s64 Elf64_Sxword;
29251  #define DT_DEBUG       21
29252  #define DT_TEXTREL     22
29253  #define DT_JMPREL      23
29254 +#define DT_FLAGS       30
29255 +  #define DF_TEXTREL  0x00000004
29256  #define DT_ENCODING    32
29257  #define OLD_DT_LOOS    0x60000000
29258  #define DT_LOOS                0x6000000d
29259 @@ -230,6 +243,19 @@ typedef struct elf64_hdr {
29260  #define PF_W           0x2
29261  #define PF_X           0x1
29262  
29263 +#define PF_PAGEEXEC    (1U << 4)       /* Enable  PAGEEXEC */
29264 +#define PF_NOPAGEEXEC  (1U << 5)       /* Disable PAGEEXEC */
29265 +#define PF_SEGMEXEC    (1U << 6)       /* Enable  SEGMEXEC */
29266 +#define PF_NOSEGMEXEC  (1U << 7)       /* Disable SEGMEXEC */
29267 +#define PF_MPROTECT    (1U << 8)       /* Enable  MPROTECT */
29268 +#define PF_NOMPROTECT  (1U << 9)       /* Disable MPROTECT */
29269 +/*#define PF_RANDEXEC  (1U << 10)*/    /* Enable  RANDEXEC */
29270 +/*#define PF_NORANDEXEC        (1U << 11)*/    /* Disable RANDEXEC */
29271 +#define PF_EMUTRAMP    (1U << 12)      /* Enable  EMUTRAMP */
29272 +#define PF_NOEMUTRAMP  (1U << 13)      /* Disable EMUTRAMP */
29273 +#define PF_RANDMMAP    (1U << 14)      /* Enable  RANDMMAP */
29274 +#define PF_NORANDMMAP  (1U << 15)      /* Disable RANDMMAP */
29275 +
29276  typedef struct elf32_phdr{
29277    Elf32_Word   p_type;
29278    Elf32_Off    p_offset;
29279 @@ -322,6 +348,8 @@ typedef struct elf64_shdr {
29280  #define        EI_OSABI        7
29281  #define        EI_PAD          8
29282  
29283 +#define        EI_PAX          14
29284 +
29285  #define        ELFMAG0         0x7f            /* EI_MAG */
29286  #define        ELFMAG1         'E'
29287  #define        ELFMAG2         'L'
29288 @@ -383,6 +411,7 @@ extern Elf32_Dyn _DYNAMIC [];
29289  #define elf_phdr       elf32_phdr
29290  #define elf_note       elf32_note
29291  #define elf_addr_t     Elf32_Off
29292 +#define elf_dyn                Elf32_Dyn
29293  
29294  #else
29295  
29296 @@ -391,6 +420,7 @@ extern Elf64_Dyn _DYNAMIC [];
29297  #define elf_phdr       elf64_phdr
29298  #define elf_note       elf64_note
29299  #define elf_addr_t     Elf64_Off
29300 +#define elf_dyn                Elf64_Dyn
29301  
29302  #endif
29303  
29304 diff -urNp linux-2.6.27.10/include/linux/gracl.h linux-2.6.27.10/include/linux/gracl.h
29305 --- linux-2.6.27.10/include/linux/gracl.h       1969-12-31 19:00:00.000000000 -0500
29306 +++ linux-2.6.27.10/include/linux/gracl.h       2008-11-18 03:38:45.000000000 -0500
29307 @@ -0,0 +1,318 @@
29308 +#ifndef GR_ACL_H
29309 +#define GR_ACL_H
29310 +
29311 +#include <linux/grdefs.h>
29312 +#include <linux/resource.h>
29313 +#include <linux/capability.h>
29314 +#include <linux/dcache.h>
29315 +#include <asm/resource.h>
29316 +
29317 +/* Major status information */
29318 +
29319 +#define GR_VERSION  "grsecurity 2.1.12"
29320 +#define GRSECURITY_VERSION 0x2112
29321 +
29322 +enum {
29323 +
29324 +       SHUTDOWN = 0,
29325 +       ENABLE = 1,
29326 +       SPROLE = 2,
29327 +       RELOAD = 3,
29328 +       SEGVMOD = 4,
29329 +       STATUS = 5,
29330 +       UNSPROLE = 6,
29331 +       PASSSET = 7,
29332 +       SPROLEPAM = 8
29333 +};
29334 +
29335 +/* Password setup definitions
29336 + * kernel/grhash.c */
29337 +enum {
29338 +       GR_PW_LEN = 128,
29339 +       GR_SALT_LEN = 16,
29340 +       GR_SHA_LEN = 32,
29341 +};
29342 +
29343 +enum {
29344 +       GR_SPROLE_LEN = 64,
29345 +};
29346 +
29347 +#define GR_NLIMITS (RLIMIT_LOCKS + 2)
29348 +
29349 +/* Begin Data Structures */
29350 +
29351 +struct sprole_pw {
29352 +       unsigned char *rolename;
29353 +       unsigned char salt[GR_SALT_LEN];
29354 +       unsigned char sum[GR_SHA_LEN];  /* 256-bit SHA hash of the password */
29355 +};
29356 +
29357 +struct name_entry {
29358 +       __u32 key;
29359 +       ino_t inode;
29360 +       dev_t device;
29361 +       char *name;
29362 +       __u16 len;
29363 +       __u8 deleted;
29364 +       struct name_entry *prev;
29365 +       struct name_entry *next;
29366 +};
29367 +
29368 +struct inodev_entry {
29369 +       struct name_entry *nentry;
29370 +       struct inodev_entry *prev;
29371 +       struct inodev_entry *next;
29372 +};
29373 +
29374 +struct acl_role_db {
29375 +       struct acl_role_label **r_hash;
29376 +       __u32 r_size;
29377 +};
29378 +
29379 +struct inodev_db {
29380 +       struct inodev_entry **i_hash;
29381 +       __u32 i_size;
29382 +};
29383 +
29384 +struct name_db {
29385 +       struct name_entry **n_hash;
29386 +       __u32 n_size;
29387 +};
29388 +
29389 +struct crash_uid {
29390 +       uid_t uid;
29391 +       unsigned long expires;
29392 +};
29393 +
29394 +struct gr_hash_struct {
29395 +       void **table;
29396 +       void **nametable;
29397 +       void *first;
29398 +       __u32 table_size;
29399 +       __u32 used_size;
29400 +       int type;
29401 +};
29402 +
29403 +/* Userspace Grsecurity ACL data structures */
29404 +
29405 +struct acl_subject_label {
29406 +       char *filename;
29407 +       ino_t inode;
29408 +       dev_t device;
29409 +       __u32 mode;
29410 +       kernel_cap_t cap_mask;
29411 +       kernel_cap_t cap_lower;
29412 +
29413 +       struct rlimit res[GR_NLIMITS];
29414 +       __u16 resmask;
29415 +
29416 +       __u8 user_trans_type;
29417 +       __u8 group_trans_type;
29418 +       uid_t *user_transitions;
29419 +       gid_t *group_transitions;
29420 +       __u16 user_trans_num;
29421 +       __u16 group_trans_num;
29422 +
29423 +       __u32 ip_proto[8];
29424 +       __u32 ip_type;
29425 +       struct acl_ip_label **ips;
29426 +       __u32 ip_num;
29427 +
29428 +       __u32 crashes;
29429 +       unsigned long expires;
29430 +
29431 +       struct acl_subject_label *parent_subject;
29432 +       struct gr_hash_struct *hash;
29433 +       struct acl_subject_label *prev;
29434 +       struct acl_subject_label *next;
29435 +
29436 +       struct acl_object_label **obj_hash;
29437 +       __u32 obj_hash_size;
29438 +       __u16 pax_flags;
29439 +};
29440 +
29441 +struct role_allowed_ip {
29442 +       __u32 addr;
29443 +       __u32 netmask;
29444 +
29445 +       struct role_allowed_ip *prev;
29446 +       struct role_allowed_ip *next;
29447 +};
29448 +
29449 +struct role_transition {
29450 +       char *rolename;
29451 +
29452 +       struct role_transition *prev;
29453 +       struct role_transition *next;
29454 +};
29455 +
29456 +struct acl_role_label {
29457 +       char *rolename;
29458 +       uid_t uidgid;
29459 +       __u16 roletype;
29460 +
29461 +       __u16 auth_attempts;
29462 +       unsigned long expires;
29463 +
29464 +       struct acl_subject_label *root_label;
29465 +       struct gr_hash_struct *hash;
29466 +
29467 +       struct acl_role_label *prev;
29468 +       struct acl_role_label *next;
29469 +
29470 +       struct role_transition *transitions;
29471 +       struct role_allowed_ip *allowed_ips;
29472 +       uid_t *domain_children;
29473 +       __u16 domain_child_num;
29474 +
29475 +       struct acl_subject_label **subj_hash;
29476 +       __u32 subj_hash_size;
29477 +};
29478 +
29479 +struct user_acl_role_db {
29480 +       struct acl_role_label **r_table;
29481 +       __u32 num_pointers;             /* Number of allocations to track */
29482 +       __u32 num_roles;                /* Number of roles */
29483 +       __u32 num_domain_children;      /* Number of domain children */
29484 +       __u32 num_subjects;             /* Number of subjects */
29485 +       __u32 num_objects;              /* Number of objects */
29486 +};
29487 +
29488 +struct acl_object_label {
29489 +       char *filename;
29490 +       ino_t inode;
29491 +       dev_t device;
29492 +       __u32 mode;
29493 +
29494 +       struct acl_subject_label *nested;
29495 +       struct acl_object_label *globbed;
29496 +
29497 +       /* next two structures not used */
29498 +
29499 +       struct acl_object_label *prev;
29500 +       struct acl_object_label *next;
29501 +};
29502 +
29503 +struct acl_ip_label {
29504 +       char *iface;
29505 +       __u32 addr;
29506 +       __u32 netmask;
29507 +       __u16 low, high;
29508 +       __u8 mode;
29509 +       __u32 type;
29510 +       __u32 proto[8];
29511 +
29512 +       /* next two structures not used */
29513 +
29514 +       struct acl_ip_label *prev;
29515 +       struct acl_ip_label *next;
29516 +};
29517 +
29518 +struct gr_arg {
29519 +       struct user_acl_role_db role_db;
29520 +       unsigned char pw[GR_PW_LEN];
29521 +       unsigned char salt[GR_SALT_LEN];
29522 +       unsigned char sum[GR_SHA_LEN];
29523 +       unsigned char sp_role[GR_SPROLE_LEN];
29524 +       struct sprole_pw *sprole_pws;
29525 +       dev_t segv_device;
29526 +       ino_t segv_inode;
29527 +       uid_t segv_uid;
29528 +       __u16 num_sprole_pws;
29529 +       __u16 mode;
29530 +};
29531 +
29532 +struct gr_arg_wrapper {
29533 +       struct gr_arg *arg;
29534 +       __u32 version;
29535 +       __u32 size;
29536 +};
29537 +
29538 +struct subject_map {
29539 +       struct acl_subject_label *user;
29540 +       struct acl_subject_label *kernel;
29541 +       struct subject_map *prev;
29542 +       struct subject_map *next;
29543 +};
29544 +
29545 +struct acl_subj_map_db {
29546 +       struct subject_map **s_hash;
29547 +       __u32 s_size;
29548 +};
29549 +
29550 +/* End Data Structures Section */
29551 +
29552 +/* Hash functions generated by empirical testing by Brad Spengler
29553 +   Makes good use of the low bits of the inode.  Generally 0-1 times
29554 +   in loop for successful match.  0-3 for unsuccessful match.
29555 +   Shift/add algorithm with modulus of table size and an XOR*/
29556 +
29557 +static __inline__ unsigned int
29558 +rhash(const uid_t uid, const __u16 type, const unsigned int sz)
29559 +{
29560 +       return (((uid << type) + (uid ^ type)) % sz);
29561 +}
29562 +
29563 + static __inline__ unsigned int
29564 +shash(const struct acl_subject_label *userp, const unsigned int sz)
29565 +{
29566 +       return ((const unsigned long)userp % sz);
29567 +}
29568 +
29569 +static __inline__ unsigned int
29570 +fhash(const ino_t ino, const dev_t dev, const unsigned int sz)
29571 +{
29572 +       return (((ino + dev) ^ ((ino << 13) + (ino << 23) + (dev << 9))) % sz);
29573 +}
29574 +
29575 +static __inline__ unsigned int
29576 +nhash(const char *name, const __u16 len, const unsigned int sz)
29577 +{
29578 +       return full_name_hash(name, len) % sz;
29579 +}
29580 +
29581 +#define FOR_EACH_ROLE_START(role,iter) \
29582 +       role = NULL; \
29583 +       iter = 0; \
29584 +       while (iter < acl_role_set.r_size) { \
29585 +               if (role == NULL) \
29586 +                       role = acl_role_set.r_hash[iter]; \
29587 +               if (role == NULL) { \
29588 +                       iter++; \
29589 +                       continue; \
29590 +               }
29591 +
29592 +#define FOR_EACH_ROLE_END(role,iter) \
29593 +               role = role->next; \
29594 +               if (role == NULL) \
29595 +                       iter++; \
29596 +       }
29597 +
29598 +#define FOR_EACH_SUBJECT_START(role,subj,iter) \
29599 +       subj = NULL; \
29600 +       iter = 0; \
29601 +       while (iter < role->subj_hash_size) { \
29602 +               if (subj == NULL) \
29603 +                       subj = role->subj_hash[iter]; \
29604 +               if (subj == NULL) { \
29605 +                       iter++; \
29606 +                       continue; \
29607 +               }
29608 +
29609 +#define FOR_EACH_SUBJECT_END(subj,iter) \
29610 +               subj = subj->next; \
29611 +               if (subj == NULL) \
29612 +                       iter++; \
29613 +       }
29614 +
29615 +
29616 +#define FOR_EACH_NESTED_SUBJECT_START(role,subj) \
29617 +       subj = role->hash->first; \
29618 +       while (subj != NULL) {
29619 +
29620 +#define FOR_EACH_NESTED_SUBJECT_END(subj) \
29621 +               subj = subj->next; \
29622 +       }
29623 +
29624 +#endif
29625 +
29626 diff -urNp linux-2.6.27.10/include/linux/gralloc.h linux-2.6.27.10/include/linux/gralloc.h
29627 --- linux-2.6.27.10/include/linux/gralloc.h     1969-12-31 19:00:00.000000000 -0500
29628 +++ linux-2.6.27.10/include/linux/gralloc.h     2008-11-18 03:38:45.000000000 -0500
29629 @@ -0,0 +1,8 @@
29630 +#ifndef __GRALLOC_H
29631 +#define __GRALLOC_H
29632 +
29633 +void acl_free_all(void);
29634 +int acl_alloc_stack_init(unsigned long size);
29635 +void *acl_alloc(unsigned long len);
29636 +
29637 +#endif
29638 diff -urNp linux-2.6.27.10/include/linux/grdefs.h linux-2.6.27.10/include/linux/grdefs.h
29639 --- linux-2.6.27.10/include/linux/grdefs.h      1969-12-31 19:00:00.000000000 -0500
29640 +++ linux-2.6.27.10/include/linux/grdefs.h      2008-11-18 03:38:45.000000000 -0500
29641 @@ -0,0 +1,131 @@
29642 +#ifndef GRDEFS_H
29643 +#define GRDEFS_H
29644 +
29645 +/* Begin grsecurity status declarations */
29646 +
29647 +enum {
29648 +       GR_READY = 0x01,
29649 +       GR_STATUS_INIT = 0x00   // disabled state
29650 +};
29651 +
29652 +/* Begin  ACL declarations */
29653 +
29654 +/* Role flags */
29655 +
29656 +enum {
29657 +       GR_ROLE_USER = 0x0001,
29658 +       GR_ROLE_GROUP = 0x0002,
29659 +       GR_ROLE_DEFAULT = 0x0004,
29660 +       GR_ROLE_SPECIAL = 0x0008,
29661 +       GR_ROLE_AUTH = 0x0010,
29662 +       GR_ROLE_NOPW = 0x0020,
29663 +       GR_ROLE_GOD = 0x0040,
29664 +       GR_ROLE_LEARN = 0x0080,
29665 +       GR_ROLE_TPE = 0x0100,
29666 +       GR_ROLE_DOMAIN = 0x0200,
29667 +       GR_ROLE_PAM = 0x0400
29668 +};
29669 +
29670 +/* ACL Subject and Object mode flags */
29671 +enum {
29672 +       GR_DELETED = 0x80000000
29673 +};
29674 +
29675 +/* ACL Object-only mode flags */
29676 +enum {
29677 +       GR_READ         = 0x00000001,
29678 +       GR_APPEND       = 0x00000002,
29679 +       GR_WRITE        = 0x00000004,
29680 +       GR_EXEC         = 0x00000008,
29681 +       GR_FIND         = 0x00000010,
29682 +       GR_INHERIT      = 0x00000020,
29683 +       GR_SETID        = 0x00000040,
29684 +       GR_CREATE       = 0x00000080,
29685 +       GR_DELETE       = 0x00000100,
29686 +       GR_LINK         = 0x00000200,
29687 +       GR_AUDIT_READ   = 0x00000400,
29688 +       GR_AUDIT_APPEND = 0x00000800,
29689 +       GR_AUDIT_WRITE  = 0x00001000,
29690 +       GR_AUDIT_EXEC   = 0x00002000,
29691 +       GR_AUDIT_FIND   = 0x00004000,
29692 +       GR_AUDIT_INHERIT= 0x00008000,
29693 +       GR_AUDIT_SETID  = 0x00010000,
29694 +       GR_AUDIT_CREATE = 0x00020000,
29695 +       GR_AUDIT_DELETE = 0x00040000,
29696 +       GR_AUDIT_LINK   = 0x00080000,
29697 +       GR_PTRACERD     = 0x00100000,
29698 +       GR_NOPTRACE     = 0x00200000,
29699 +       GR_SUPPRESS     = 0x00400000,
29700 +       GR_NOLEARN      = 0x00800000
29701 +};
29702 +
29703 +#define GR_AUDITS (GR_AUDIT_READ | GR_AUDIT_WRITE | GR_AUDIT_APPEND | GR_AUDIT_EXEC | \
29704 +                  GR_AUDIT_FIND | GR_AUDIT_INHERIT | GR_AUDIT_SETID | \
29705 +                  GR_AUDIT_CREATE | GR_AUDIT_DELETE | GR_AUDIT_LINK)
29706 +
29707 +/* ACL subject-only mode flags */
29708 +enum {
29709 +       GR_KILL         = 0x00000001,
29710 +       GR_VIEW         = 0x00000002,
29711 +       GR_PROTECTED    = 0x00000004,
29712 +       GR_LEARN        = 0x00000008,
29713 +       GR_OVERRIDE     = 0x00000010,
29714 +       /* just a placeholder, this mode is only used in userspace */
29715 +       GR_DUMMY        = 0x00000020,
29716 +       GR_PROTSHM      = 0x00000040,
29717 +       GR_KILLPROC     = 0x00000080,
29718 +       GR_KILLIPPROC   = 0x00000100,
29719 +       /* just a placeholder, this mode is only used in userspace */
29720 +       GR_NOTROJAN     = 0x00000200,
29721 +       GR_PROTPROCFD   = 0x00000400,
29722 +       GR_PROCACCT     = 0x00000800,
29723 +       GR_RELAXPTRACE  = 0x00001000,
29724 +       GR_NESTED       = 0x00002000,
29725 +       GR_INHERITLEARN = 0x00004000,
29726 +       GR_PROCFIND     = 0x00008000,
29727 +       GR_POVERRIDE    = 0x00010000,
29728 +       GR_KERNELAUTH   = 0x00020000,
29729 +};
29730 +
29731 +enum {
29732 +       GR_PAX_ENABLE_SEGMEXEC  = 0x0001,
29733 +       GR_PAX_ENABLE_PAGEEXEC  = 0x0002,
29734 +       GR_PAX_ENABLE_MPROTECT  = 0x0004,
29735 +       GR_PAX_ENABLE_RANDMMAP  = 0x0008,
29736 +       GR_PAX_ENABLE_EMUTRAMP  = 0x0010,
29737 +       GR_PAX_DISABLE_SEGMEXEC = 0x0100,
29738 +       GR_PAX_DISABLE_PAGEEXEC = 0x0200,
29739 +       GR_PAX_DISABLE_MPROTECT = 0x0400,
29740 +       GR_PAX_DISABLE_RANDMMAP = 0x0800,
29741 +       GR_PAX_DISABLE_EMUTRAMP = 0x1000,
29742 +};
29743 +
29744 +enum {
29745 +       GR_ID_USER      = 0x01,
29746 +       GR_ID_GROUP     = 0x02,
29747 +};
29748 +
29749 +enum {
29750 +       GR_ID_ALLOW     = 0x01,
29751 +       GR_ID_DENY      = 0x02,
29752 +};
29753 +
29754 +#define GR_CRASH_RES   11
29755 +#define GR_UIDTABLE_MAX 500
29756 +
29757 +/* begin resource learning section */
29758 +enum {
29759 +       GR_RLIM_CPU_BUMP = 60,
29760 +       GR_RLIM_FSIZE_BUMP = 50000,
29761 +       GR_RLIM_DATA_BUMP = 10000,
29762 +       GR_RLIM_STACK_BUMP = 1000,
29763 +       GR_RLIM_CORE_BUMP = 10000,
29764 +       GR_RLIM_RSS_BUMP = 500000,
29765 +       GR_RLIM_NPROC_BUMP = 1,
29766 +       GR_RLIM_NOFILE_BUMP = 5,
29767 +       GR_RLIM_MEMLOCK_BUMP = 50000,
29768 +       GR_RLIM_AS_BUMP = 500000,
29769 +       GR_RLIM_LOCKS_BUMP = 2
29770 +};
29771 +
29772 +#endif
29773 diff -urNp linux-2.6.27.10/include/linux/grinternal.h linux-2.6.27.10/include/linux/grinternal.h
29774 --- linux-2.6.27.10/include/linux/grinternal.h  1969-12-31 19:00:00.000000000 -0500
29775 +++ linux-2.6.27.10/include/linux/grinternal.h  2008-11-18 03:38:45.000000000 -0500
29776 @@ -0,0 +1,210 @@
29777 +#ifndef __GRINTERNAL_H
29778 +#define __GRINTERNAL_H
29779 +
29780 +#ifdef CONFIG_GRKERNSEC
29781 +
29782 +#include <linux/fs.h>
29783 +#include <linux/gracl.h>
29784 +#include <linux/grdefs.h>
29785 +#include <linux/grmsg.h>
29786 +
29787 +void gr_add_learn_entry(const char *fmt, ...);
29788 +__u32 gr_search_file(const struct dentry *dentry, const __u32 mode,
29789 +                           const struct vfsmount *mnt);
29790 +__u32 gr_check_create(const struct dentry *new_dentry,
29791 +                            const struct dentry *parent,
29792 +                            const struct vfsmount *mnt, const __u32 mode);
29793 +int gr_check_protected_task(const struct task_struct *task);
29794 +__u32 to_gr_audit(const __u32 reqmode);
29795 +int gr_set_acls(const int type);
29796 +
29797 +int gr_acl_is_enabled(void);
29798 +char gr_roletype_to_char(void);
29799 +
29800 +void gr_handle_alertkill(struct task_struct *task);
29801 +char *gr_to_filename(const struct dentry *dentry,
29802 +                           const struct vfsmount *mnt);
29803 +char *gr_to_filename1(const struct dentry *dentry,
29804 +                           const struct vfsmount *mnt);
29805 +char *gr_to_filename2(const struct dentry *dentry,
29806 +                           const struct vfsmount *mnt);
29807 +char *gr_to_filename3(const struct dentry *dentry,
29808 +                           const struct vfsmount *mnt);
29809 +
29810 +extern int grsec_enable_link;
29811 +extern int grsec_enable_fifo;
29812 +extern int grsec_enable_execve;
29813 +extern int grsec_enable_shm;
29814 +extern int grsec_enable_execlog;
29815 +extern int grsec_enable_signal;
29816 +extern int grsec_enable_forkfail;
29817 +extern int grsec_enable_time;
29818 +extern int grsec_enable_chroot_shmat;
29819 +extern int grsec_enable_chroot_findtask;
29820 +extern int grsec_enable_chroot_mount;
29821 +extern int grsec_enable_chroot_double;
29822 +extern int grsec_enable_chroot_pivot;
29823 +extern int grsec_enable_chroot_chdir;
29824 +extern int grsec_enable_chroot_chmod;
29825 +extern int grsec_enable_chroot_mknod;
29826 +extern int grsec_enable_chroot_fchdir;
29827 +extern int grsec_enable_chroot_nice;
29828 +extern int grsec_enable_chroot_execlog;
29829 +extern int grsec_enable_chroot_caps;
29830 +extern int grsec_enable_chroot_sysctl;
29831 +extern int grsec_enable_chroot_unix;
29832 +extern int grsec_enable_tpe;
29833 +extern int grsec_tpe_gid;
29834 +extern int grsec_enable_tpe_all;
29835 +extern int grsec_enable_sidcaps;
29836 +extern int grsec_enable_socket_all;
29837 +extern int grsec_socket_all_gid;
29838 +extern int grsec_enable_socket_client;
29839 +extern int grsec_socket_client_gid;
29840 +extern int grsec_enable_socket_server;
29841 +extern int grsec_socket_server_gid;
29842 +extern int grsec_audit_gid;
29843 +extern int grsec_enable_group;
29844 +extern int grsec_enable_audit_ipc;
29845 +extern int grsec_enable_audit_textrel;
29846 +extern int grsec_enable_mount;
29847 +extern int grsec_enable_chdir;
29848 +extern int grsec_resource_logging;
29849 +extern int grsec_lock;
29850 +
29851 +extern spinlock_t grsec_alert_lock;
29852 +extern unsigned long grsec_alert_wtime;
29853 +extern unsigned long grsec_alert_fyet;
29854 +
29855 +extern spinlock_t grsec_audit_lock;
29856 +
29857 +extern rwlock_t grsec_exec_file_lock;
29858 +
29859 +#define gr_task_fullpath(tsk) (tsk->exec_file ? \
29860 +                       gr_to_filename2(tsk->exec_file->f_path.dentry, \
29861 +                       tsk->exec_file->f_vfsmnt) : "/")
29862 +
29863 +#define gr_parent_task_fullpath(tsk) (tsk->parent->exec_file ? \
29864 +                       gr_to_filename3(tsk->parent->exec_file->f_path.dentry, \
29865 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
29866 +
29867 +#define gr_task_fullpath0(tsk) (tsk->exec_file ? \
29868 +                       gr_to_filename(tsk->exec_file->f_path.dentry, \
29869 +                       tsk->exec_file->f_vfsmnt) : "/")
29870 +
29871 +#define gr_parent_task_fullpath0(tsk) (tsk->parent->exec_file ? \
29872 +                       gr_to_filename1(tsk->parent->exec_file->f_path.dentry, \
29873 +                       tsk->parent->exec_file->f_vfsmnt) : "/")
29874 +
29875 +#define proc_is_chrooted(tsk_a)  ((tsk_a->pid > 1) && (tsk_a->fs != NULL) && \
29876 +                         ((tsk_a->fs->root.dentry->d_inode->i_sb->s_dev != \
29877 +                         tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_sb->s_dev) || \
29878 +                         (tsk_a->fs->root.dentry->d_inode->i_ino != \
29879 +                         tsk_a->nsproxy->pid_ns->child_reaper->fs->root.dentry->d_inode->i_ino)))
29880 +
29881 +#define have_same_root(tsk_a,tsk_b) ((tsk_a->fs != NULL) && (tsk_b->fs != NULL) && \
29882 +                         (tsk_a->fs->root.dentry->d_inode->i_sb->s_dev == \
29883 +                         tsk_b->fs->root.dentry->d_inode->i_sb->s_dev) && \
29884 +                         (tsk_a->fs->root.dentry->d_inode->i_ino == \
29885 +                         tsk_b->fs->root.dentry->d_inode->i_ino))
29886 +
29887 +#define DEFAULTSECARGS(task) gr_task_fullpath(task), task->comm, \
29888 +                      task->pid, task->uid, \
29889 +                      task->euid, task->gid, task->egid, \
29890 +                      gr_parent_task_fullpath(task), \
29891 +                      task->parent->comm, task->parent->pid, \
29892 +                      task->parent->uid, task->parent->euid, \
29893 +                      task->parent->gid, task->parent->egid
29894 +
29895 +#define GR_CHROOT_CAPS {{ \
29896 +       CAP_TO_MASK(CAP_LINUX_IMMUTABLE) | CAP_TO_MASK(CAP_NET_ADMIN) | \
29897 +       CAP_TO_MASK(CAP_SYS_MODULE) | CAP_TO_MASK(CAP_SYS_RAWIO) | \
29898 +       CAP_TO_MASK(CAP_SYS_PACCT) | CAP_TO_MASK(CAP_SYS_ADMIN) | \
29899 +       CAP_TO_MASK(CAP_SYS_BOOT) | CAP_TO_MASK(CAP_SYS_TIME) | \
29900 +       CAP_TO_MASK(CAP_NET_RAW) | CAP_TO_MASK(CAP_SYS_TTY_CONFIG) | \
29901 +       CAP_TO_MASK(CAP_IPC_OWNER) , 0 }}
29902 +
29903 +#define security_learn(normal_msg,args...) \
29904 +({ \
29905 +       read_lock(&grsec_exec_file_lock); \
29906 +       gr_add_learn_entry(normal_msg "\n", ## args); \
29907 +       read_unlock(&grsec_exec_file_lock); \
29908 +})
29909 +
29910 +enum {
29911 +       GR_DO_AUDIT,
29912 +       GR_DONT_AUDIT,
29913 +       GR_DONT_AUDIT_GOOD
29914 +};
29915 +
29916 +enum {
29917 +       GR_TTYSNIFF,
29918 +       GR_RBAC,
29919 +       GR_RBAC_STR,
29920 +       GR_STR_RBAC,
29921 +       GR_RBAC_MODE2,
29922 +       GR_RBAC_MODE3,
29923 +       GR_FILENAME,
29924 +       GR_SYSCTL_HIDDEN,
29925 +       GR_NOARGS,
29926 +       GR_ONE_INT,
29927 +       GR_ONE_INT_TWO_STR,
29928 +       GR_ONE_STR,
29929 +       GR_STR_INT,
29930 +       GR_TWO_INT,
29931 +       GR_THREE_INT,
29932 +       GR_FIVE_INT_TWO_STR,
29933 +       GR_TWO_STR,
29934 +       GR_THREE_STR,
29935 +       GR_FOUR_STR,
29936 +       GR_STR_FILENAME,
29937 +       GR_FILENAME_STR,
29938 +       GR_FILENAME_TWO_INT,
29939 +       GR_FILENAME_TWO_INT_STR,
29940 +       GR_TEXTREL,
29941 +       GR_PTRACE,
29942 +       GR_RESOURCE,
29943 +       GR_CAP,
29944 +       GR_SIG,
29945 +       GR_CRASH1,
29946 +       GR_CRASH2,
29947 +       GR_PSACCT
29948 +};
29949 +
29950 +#define gr_log_hidden_sysctl(audit, msg, str) gr_log_varargs(audit, msg, GR_SYSCTL_HIDDEN, str)
29951 +#define gr_log_ttysniff(audit, msg, task) gr_log_varargs(audit, msg, GR_TTYSNIFF, task)
29952 +#define gr_log_fs_rbac_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_RBAC, dentry, mnt)
29953 +#define gr_log_fs_rbac_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_RBAC_STR, dentry, mnt, str)
29954 +#define gr_log_fs_str_rbac(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_RBAC, str, dentry, mnt)
29955 +#define gr_log_fs_rbac_mode2(audit, msg, dentry, mnt, str1, str2) gr_log_varargs(audit, msg, GR_RBAC_MODE2, dentry, mnt, str1, str2)
29956 +#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)
29957 +#define gr_log_fs_generic(audit, msg, dentry, mnt) gr_log_varargs(audit, msg, GR_FILENAME, dentry, mnt)
29958 +#define gr_log_noargs(audit, msg) gr_log_varargs(audit, msg, GR_NOARGS)
29959 +#define gr_log_int(audit, msg, num) gr_log_varargs(audit, msg, GR_ONE_INT, num)
29960 +#define gr_log_int_str2(audit, msg, num, str1, str2) gr_log_varargs(audit, msg, GR_ONE_INT_TWO_STR, num, str1, str2)
29961 +#define gr_log_str(audit, msg, str) gr_log_varargs(audit, msg, GR_ONE_STR, str)
29962 +#define gr_log_str_int(audit, msg, str, num) gr_log_varargs(audit, msg, GR_STR_INT, str, num)
29963 +#define gr_log_int_int(audit, msg, num1, num2) gr_log_varargs(audit, msg, GR_TWO_INT, num1, num2)
29964 +#define gr_log_int3(audit, msg, num1, num2, num3) gr_log_varargs(audit, msg, GR_THREE_INT, num1, num2, num3)
29965 +#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)
29966 +#define gr_log_str_str(audit, msg, str1, str2) gr_log_varargs(audit, msg, GR_TWO_STR, str1, str2)
29967 +#define gr_log_str3(audit, msg, str1, str2, str3) gr_log_varargs(audit, msg, GR_THREE_STR, str1, str2, str3)
29968 +#define gr_log_str4(audit, msg, str1, str2, str3, str4) gr_log_varargs(audit, msg, GR_FOUR_STR, str1, str2, str3, str4)
29969 +#define gr_log_str_fs(audit, msg, str, dentry, mnt) gr_log_varargs(audit, msg, GR_STR_FILENAME, str, dentry, mnt)
29970 +#define gr_log_fs_str(audit, msg, dentry, mnt, str) gr_log_varargs(audit, msg, GR_FILENAME_STR, dentry, mnt, str)
29971 +#define gr_log_fs_int2(audit, msg, dentry, mnt, num1, num2) gr_log_varargs(audit, msg, GR_FILENAME_TWO_INT, dentry, mnt, num1, num2)
29972 +#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)
29973 +#define gr_log_textrel_ulong_ulong(audit, msg, file, ulong1, ulong2) gr_log_varargs(audit, msg, GR_TEXTREL, file, ulong1, ulong2)
29974 +#define gr_log_ptrace(audit, msg, task) gr_log_varargs(audit, msg, GR_PTRACE, task)
29975 +#define gr_log_res_ulong2_str(audit, msg, task, ulong1, str, ulong2) gr_log_varargs(audit, msg, GR_RESOURCE, task, ulong1, str, ulong2)
29976 +#define gr_log_cap(audit, msg, task, str) gr_log_varargs(audit, msg, GR_CAP, task, str)
29977 +#define gr_log_sig(audit, msg, task, num) gr_log_varargs(audit, msg, GR_SIG, task, num)
29978 +#define gr_log_crash1(audit, msg, task, ulong) gr_log_varargs(audit, msg, GR_CRASH1, task, ulong)
29979 +#define gr_log_crash2(audit, msg, task, ulong1) gr_log_varargs(audit, msg, GR_CRASH2, task, ulong1)
29980 +#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)
29981 +
29982 +void gr_log_varargs(int audit, const char *msg, int argtypes, ...);
29983 +
29984 +#endif
29985 +
29986 +#endif
29987 diff -urNp linux-2.6.27.10/include/linux/grmsg.h linux-2.6.27.10/include/linux/grmsg.h
29988 --- linux-2.6.27.10/include/linux/grmsg.h       1969-12-31 19:00:00.000000000 -0500
29989 +++ linux-2.6.27.10/include/linux/grmsg.h       2008-11-18 03:38:45.000000000 -0500
29990 @@ -0,0 +1,108 @@
29991 +#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"
29992 +#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"
29993 +#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
29994 +#define GR_STOPMOD_MSG "denied modification of module state by "
29995 +#define GR_IOPERM_MSG "denied use of ioperm() by "
29996 +#define GR_IOPL_MSG "denied use of iopl() by "
29997 +#define GR_SHMAT_ACL_MSG "denied attach of shared memory of UID %u, PID %d, ID %u by "
29998 +#define GR_UNIX_CHROOT_MSG "denied connect() to abstract AF_UNIX socket outside of chroot by "
29999 +#define GR_SHMAT_CHROOT_MSG "denied attach of shared memory outside of chroot by "
30000 +#define GR_KMEM_MSG "denied write of /dev/kmem by "
30001 +#define GR_PORT_OPEN_MSG "denied open of /dev/port by "
30002 +#define GR_MEM_WRITE_MSG "denied write of /dev/mem by "
30003 +#define GR_MEM_MMAP_MSG "denied mmap write of /dev/[k]mem by "
30004 +#define GR_SYMLINK_MSG "not following symlink %.950s owned by %d.%d by "
30005 +#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"
30006 +#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"
30007 +#define GR_HIDDEN_ACL_MSG "%s access to hidden file %.950s by "
30008 +#define GR_OPEN_ACL_MSG "%s open of %.950s for%s%s by "
30009 +#define GR_CREATE_ACL_MSG "%s create of %.950s for%s%s by "
30010 +#define GR_FIFO_MSG "denied writing FIFO %.950s of %d.%d by "
30011 +#define GR_MKNOD_CHROOT_MSG "denied mknod of %.950s from chroot by "
30012 +#define GR_MKNOD_ACL_MSG "%s mknod of %.950s by "
30013 +#define GR_UNIXCONNECT_ACL_MSG "%s connect() to the unix domain socket %.950s by "
30014 +#define GR_TTYSNIFF_ACL_MSG "terminal being sniffed by IP:%u.%u.%u.%u %.480s[%.16s:%d], parent %.480s[%.16s:%d] against "
30015 +#define GR_MKDIR_ACL_MSG "%s mkdir of %.950s by "
30016 +#define GR_RMDIR_ACL_MSG "%s rmdir of %.950s by "
30017 +#define GR_UNLINK_ACL_MSG "%s unlink of %.950s by "
30018 +#define GR_SYMLINK_ACL_MSG "%s symlink from %.480s to %.480s by "
30019 +#define GR_HARDLINK_MSG "denied hardlink of %.930s (owned by %d.%d) to %.30s for "
30020 +#define GR_LINK_ACL_MSG "%s link of %.480s to %.480s by "
30021 +#define GR_INHERIT_ACL_MSG "successful inherit of %.480s's ACL for %.480s by "
30022 +#define GR_RENAME_ACL_MSG "%s rename of %.480s to %.480s by "
30023 +#define GR_PTRACE_EXEC_ACL_MSG "denied ptrace of %.950s by "
30024 +#define GR_NPROC_MSG "denied overstep of process limit by "
30025 +#define GR_EXEC_ACL_MSG "%s execution of %.950s by "
30026 +#define GR_EXEC_TPE_MSG "denied untrusted exec of %.950s by "
30027 +#define GR_SEGVSTART_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning uid %u from login for %lu seconds"
30028 +#define GR_SEGVNOSUID_ACL_MSG "possible exploit bruteforcing on " DEFAULTSECMSG " banning execution for %lu seconds"
30029 +#define GR_MOUNT_CHROOT_MSG "denied mount of %.256s as %.930s from chroot by "
30030 +#define GR_PIVOT_CHROOT_MSG "denied pivot_root from chroot by "
30031 +#define GR_TRUNCATE_ACL_MSG "%s truncate of %.950s by "
30032 +#define GR_ATIME_ACL_MSG "%s access time change of %.950s by "
30033 +#define GR_ACCESS_ACL_MSG "%s access of %.950s for%s%s%s by "
30034 +#define GR_CHROOT_CHROOT_MSG "denied double chroot to %.950s by "
30035 +#define GR_FCHMOD_ACL_MSG "%s fchmod of %.950s by "
30036 +#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
30037 +#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
30038 +#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
30039 +#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
30040 +#define GR_WRITLIB_ACL_MSG "denied load of writable library %.950s by "
30041 +#define GR_INITF_ACL_MSG "init_variables() failed %s by "
30042 +#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"
30043 +#define GR_DEV_ACL_MSG "/dev/grsec: %d bytes sent %d required, being fed garbaged by "
30044 +#define GR_SHUTS_ACL_MSG "shutdown auth success for "
30045 +#define GR_SHUTF_ACL_MSG "shutdown auth failure for "
30046 +#define GR_SHUTI_ACL_MSG "ignoring shutdown for disabled RBAC system for "
30047 +#define GR_SEGVMODS_ACL_MSG "segvmod auth success for "
30048 +#define GR_SEGVMODF_ACL_MSG "segvmod auth failure for "
30049 +#define GR_SEGVMODI_ACL_MSG "ignoring segvmod for disabled RBAC system for "
30050 +#define GR_ENABLE_ACL_MSG "%s RBAC system loaded by "
30051 +#define GR_ENABLEF_ACL_MSG "unable to load %s for "
30052 +#define GR_RELOADI_ACL_MSG "ignoring reload request for disabled RBAC system"
30053 +#define GR_RELOAD_ACL_MSG "%s RBAC system reloaded by "
30054 +#define GR_RELOADF_ACL_MSG "failed reload of %s for "
30055 +#define GR_SPROLEI_ACL_MSG "ignoring change to special role for disabled RBAC system for "
30056 +#define GR_SPROLES_ACL_MSG "successful change to special role %s (id %d) by "
30057 +#define GR_SPROLEL_ACL_MSG "special role %s (id %d) exited by "
30058 +#define GR_SPROLEF_ACL_MSG "special role %s failure for "
30059 +#define GR_UNSPROLEI_ACL_MSG "ignoring unauth of special role for disabled RBAC system for "
30060 +#define GR_UNSPROLES_ACL_MSG "successful unauth of special role %s (id %d) by "
30061 +#define GR_UNSPROLEF_ACL_MSG "special role unauth of %s failure for "
30062 +#define GR_INVMODE_ACL_MSG "invalid mode %d by "
30063 +#define GR_PRIORITY_CHROOT_MSG "denied priority change of process (%.16s:%d) by "
30064 +#define GR_FAILFORK_MSG "failed fork with errno %d by "
30065 +#define GR_NICE_CHROOT_MSG "denied priority change by "
30066 +#define GR_UNISIGLOG_MSG "signal %d sent to "
30067 +#define GR_DUALSIGLOG_MSG "signal %d sent to " DEFAULTSECMSG " by "
30068 +#define GR_SIG_ACL_MSG "denied send of signal %d to protected task " DEFAULTSECMSG " by "
30069 +#define GR_SYSCTL_MSG "denied modification of grsecurity sysctl value : %.32s by "
30070 +#define GR_SYSCTL_ACL_MSG "%s sysctl of %.950s for%s%s by "
30071 +#define GR_TIME_MSG "time set by "
30072 +#define GR_DEFACL_MSG "fatal: unable to find subject for (%.16s:%d), loaded by "
30073 +#define GR_MMAP_ACL_MSG "%s executable mmap of %.950s by "
30074 +#define GR_MPROTECT_ACL_MSG "%s executable mprotect of %.950s by "
30075 +#define GR_SOCK_MSG "denied socket(%.16s,%.16s,%.16s) by "
30076 +#define GR_SOCK2_MSG "denied socket(%d,%.16s,%.16s) by "
30077 +#define GR_BIND_MSG "denied bind() by "
30078 +#define GR_CONNECT_MSG "denied connect() by "
30079 +#define GR_BIND_ACL_MSG "denied bind() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30080 +#define GR_CONNECT_ACL_MSG "denied connect() to %u.%u.%u.%u port %u sock type %.16s protocol %.16s by "
30081 +#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"
30082 +#define GR_EXEC_CHROOT_MSG "exec of %.980s within chroot by process "
30083 +#define GR_CAP_ACL_MSG "use of %s denied for "
30084 +#define GR_USRCHANGE_ACL_MSG "change to uid %u denied for "
30085 +#define GR_GRPCHANGE_ACL_MSG "change to gid %u denied for "
30086 +#define GR_REMOUNT_AUDIT_MSG "remount of %.256s by "
30087 +#define GR_UNMOUNT_AUDIT_MSG "unmount of %.256s by "
30088 +#define GR_MOUNT_AUDIT_MSG "mount of %.256s to %.256s by "
30089 +#define GR_CHDIR_AUDIT_MSG "chdir to %.980s by "
30090 +#define GR_EXEC_AUDIT_MSG "exec of %.930s (%.128s) by "
30091 +#define GR_MSGQ_AUDIT_MSG "message queue created by "
30092 +#define GR_MSGQR_AUDIT_MSG "message queue of uid:%u euid:%u removed by "
30093 +#define GR_SEM_AUDIT_MSG "semaphore created by "
30094 +#define GR_SEMR_AUDIT_MSG "semaphore of uid:%u euid:%u removed by "
30095 +#define GR_SHM_AUDIT_MSG "shared memory of size %d created by "
30096 +#define GR_SHMR_AUDIT_MSG "shared memory of uid:%u euid:%u removed by "
30097 +#define GR_RESOURCE_MSG "denied resource overstep by requesting %lu for %.16s against limit %lu for "
30098 +#define GR_TEXTREL_AUDIT_MSG "text relocation in %s, VMA:0x%08lx 0x%08lx by "
30099 diff -urNp linux-2.6.27.10/include/linux/grsecurity.h linux-2.6.27.10/include/linux/grsecurity.h
30100 --- linux-2.6.27.10/include/linux/grsecurity.h  1969-12-31 19:00:00.000000000 -0500
30101 +++ linux-2.6.27.10/include/linux/grsecurity.h  2008-11-18 03:38:45.000000000 -0500
30102 @@ -0,0 +1,200 @@
30103 +#ifndef GR_SECURITY_H
30104 +#define GR_SECURITY_H
30105 +#include <linux/fs.h>
30106 +#include <linux/binfmts.h>
30107 +#include <linux/gracl.h>
30108 +
30109 +/* notify of brain-dead configs */
30110 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_PAGEEXEC) && !defined(CONFIG_PAX_SEGMEXEC) && !defined(CONFIG_PAX_KERNEXEC)
30111 +#error "CONFIG_PAX_NOEXEC enabled, but PAGEEXEC, SEGMEXEC, and KERNEXEC are disabled."
30112 +#endif
30113 +#if defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30114 +#error "CONFIG_PAX_NOEXEC enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30115 +#endif
30116 +#if defined(CONFIG_PAX_ASLR) && (defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK)) && !defined(CONFIG_PAX_EI_PAX) && !defined(CONFIG_PAX_PT_PAX_FLAGS)
30117 +#error "CONFIG_PAX_ASLR enabled, but neither CONFIG_PAX_EI_PAX nor CONFIG_PAX_PT_PAX_FLAGS are enabled."
30118 +#endif
30119 +#if defined(CONFIG_PAX_ASLR) && !defined(CONFIG_PAX_RANDKSTACK) && !defined(CONFIG_PAX_RANDUSTACK) && !defined(CONFIG_PAX_RANDMMAP)
30120 +#error "CONFIG_PAX_ASLR enabled, but RANDKSTACK, RANDUSTACK, and RANDMMAP are disabled."
30121 +#endif
30122 +#if defined(CONFIG_PAX) && !defined(CONFIG_PAX_NOEXEC) && !defined(CONFIG_PAX_ASLR)
30123 +#error "CONFIG_PAX enabled, but no PaX options are enabled."
30124 +#endif
30125 +
30126 +void gr_handle_brute_attach(struct task_struct *p);
30127 +void gr_handle_brute_check(void);
30128 +
30129 +char gr_roletype_to_char(void);
30130 +
30131 +int gr_check_user_change(int real, int effective, int fs);
30132 +int gr_check_group_change(int real, int effective, int fs);
30133 +
30134 +void gr_del_task_from_ip_table(struct task_struct *p);
30135 +
30136 +int gr_pid_is_chrooted(struct task_struct *p);
30137 +int gr_handle_chroot_nice(void);
30138 +int gr_handle_chroot_sysctl(const int op);
30139 +int gr_handle_chroot_setpriority(struct task_struct *p,
30140 +                                       const int niceval);
30141 +int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
30142 +int gr_handle_chroot_chroot(const struct dentry *dentry,
30143 +                                  const struct vfsmount *mnt);
30144 +void gr_handle_chroot_caps(struct task_struct *task);
30145 +void gr_handle_chroot_chdir(struct path *path);
30146 +int gr_handle_chroot_chmod(const struct dentry *dentry,
30147 +                                 const struct vfsmount *mnt, const int mode);
30148 +int gr_handle_chroot_mknod(const struct dentry *dentry,
30149 +                                 const struct vfsmount *mnt, const int mode);
30150 +int gr_handle_chroot_mount(const struct dentry *dentry,
30151 +                                 const struct vfsmount *mnt,
30152 +                                 const char *dev_name);
30153 +int gr_handle_chroot_pivot(void);
30154 +int gr_handle_chroot_unix(const pid_t pid);
30155 +
30156 +int gr_handle_rawio(const struct inode *inode);
30157 +int gr_handle_nproc(void);
30158 +
30159 +void gr_handle_ioperm(void);
30160 +void gr_handle_iopl(void);
30161 +
30162 +int gr_tpe_allow(const struct file *file);
30163 +
30164 +int gr_random_pid(void);
30165 +
30166 +void gr_log_forkfail(const int retval);
30167 +void gr_log_timechange(void);
30168 +void gr_log_signal(const int sig, const struct task_struct *t);
30169 +void gr_log_chdir(const struct dentry *dentry,
30170 +                        const struct vfsmount *mnt);
30171 +void gr_log_chroot_exec(const struct dentry *dentry,
30172 +                              const struct vfsmount *mnt);
30173 +void gr_handle_exec_args(struct linux_binprm *bprm, char **argv);
30174 +void gr_log_remount(const char *devname, const int retval);
30175 +void gr_log_unmount(const char *devname, const int retval);
30176 +void gr_log_mount(const char *from, const char *to, const int retval);
30177 +void gr_log_msgget(const int ret, const int msgflg);
30178 +void gr_log_msgrm(const uid_t uid, const uid_t cuid);
30179 +void gr_log_semget(const int err, const int semflg);
30180 +void gr_log_semrm(const uid_t uid, const uid_t cuid);
30181 +void gr_log_shmget(const int err, const int shmflg, const size_t size);
30182 +void gr_log_shmrm(const uid_t uid, const uid_t cuid);
30183 +void gr_log_textrel(struct vm_area_struct *vma);
30184 +
30185 +int gr_handle_follow_link(const struct inode *parent,
30186 +                                const struct inode *inode,
30187 +                                const struct dentry *dentry,
30188 +                                const struct vfsmount *mnt);
30189 +int gr_handle_fifo(const struct dentry *dentry,
30190 +                         const struct vfsmount *mnt,
30191 +                         const struct dentry *dir, const int flag,
30192 +                         const int acc_mode);
30193 +int gr_handle_hardlink(const struct dentry *dentry,
30194 +                             const struct vfsmount *mnt,
30195 +                             struct inode *inode,
30196 +                             const int mode, const char *to);
30197 +
30198 +int gr_task_is_capable(struct task_struct *task, const int cap);
30199 +int gr_is_capable_nolog(const int cap);
30200 +void gr_learn_resource(const struct task_struct *task, const int limit,
30201 +                             const unsigned long wanted, const int gt);
30202 +void gr_copy_label(struct task_struct *tsk);
30203 +void gr_handle_crash(struct task_struct *task, const int sig);
30204 +int gr_handle_signal(const struct task_struct *p, const int sig);
30205 +int gr_check_crash_uid(const uid_t uid);
30206 +int gr_check_protected_task(const struct task_struct *task);
30207 +int gr_acl_handle_mmap(const struct file *file,
30208 +                             const unsigned long prot);
30209 +int gr_acl_handle_mprotect(const struct file *file,
30210 +                                 const unsigned long prot);
30211 +int gr_check_hidden_task(const struct task_struct *tsk);
30212 +__u32 gr_acl_handle_truncate(const struct dentry *dentry,
30213 +                                   const struct vfsmount *mnt);
30214 +__u32 gr_acl_handle_utime(const struct dentry *dentry,
30215 +                                const struct vfsmount *mnt);
30216 +__u32 gr_acl_handle_access(const struct dentry *dentry,
30217 +                                 const struct vfsmount *mnt, const int fmode);
30218 +__u32 gr_acl_handle_fchmod(const struct dentry *dentry,
30219 +                                 const struct vfsmount *mnt, mode_t mode);
30220 +__u32 gr_acl_handle_chmod(const struct dentry *dentry,
30221 +                                const struct vfsmount *mnt, mode_t mode);
30222 +__u32 gr_acl_handle_chown(const struct dentry *dentry,
30223 +                                const struct vfsmount *mnt);
30224 +int gr_handle_ptrace(struct task_struct *task, const long request);
30225 +int gr_handle_proc_ptrace(struct task_struct *task);
30226 +__u32 gr_acl_handle_execve(const struct dentry *dentry,
30227 +                                 const struct vfsmount *mnt);
30228 +int gr_check_crash_exec(const struct file *filp);
30229 +int gr_acl_is_enabled(void);
30230 +void gr_set_kernel_label(struct task_struct *task);
30231 +void gr_set_role_label(struct task_struct *task, const uid_t uid,
30232 +                             const gid_t gid);
30233 +int gr_set_proc_label(const struct dentry *dentry,
30234 +                             const struct vfsmount *mnt);
30235 +__u32 gr_acl_handle_hidden_file(const struct dentry *dentry,
30236 +                                      const struct vfsmount *mnt);
30237 +__u32 gr_acl_handle_open(const struct dentry *dentry,
30238 +                               const struct vfsmount *mnt, const int fmode);
30239 +__u32 gr_acl_handle_creat(const struct dentry *dentry,
30240 +                                const struct dentry *p_dentry,
30241 +                                const struct vfsmount *p_mnt, const int fmode,
30242 +                                const int imode);
30243 +void gr_handle_create(const struct dentry *dentry,
30244 +                            const struct vfsmount *mnt);
30245 +__u32 gr_acl_handle_mknod(const struct dentry *new_dentry,
30246 +                                const struct dentry *parent_dentry,
30247 +                                const struct vfsmount *parent_mnt,
30248 +                                const int mode);
30249 +__u32 gr_acl_handle_mkdir(const struct dentry *new_dentry,
30250 +                                const struct dentry *parent_dentry,
30251 +                                const struct vfsmount *parent_mnt);
30252 +__u32 gr_acl_handle_rmdir(const struct dentry *dentry,
30253 +                                const struct vfsmount *mnt);
30254 +void gr_handle_delete(const ino_t ino, const dev_t dev);
30255 +__u32 gr_acl_handle_unlink(const struct dentry *dentry,
30256 +                                 const struct vfsmount *mnt);
30257 +__u32 gr_acl_handle_symlink(const struct dentry *new_dentry,
30258 +                                  const struct dentry *parent_dentry,
30259 +                                  const struct vfsmount *parent_mnt,
30260 +                                  const char *from);
30261 +__u32 gr_acl_handle_link(const struct dentry *new_dentry,
30262 +                               const struct dentry *parent_dentry,
30263 +                               const struct vfsmount *parent_mnt,
30264 +                               const struct dentry *old_dentry,
30265 +                               const struct vfsmount *old_mnt, const char *to);
30266 +int gr_acl_handle_rename(struct dentry *new_dentry,
30267 +                               struct dentry *parent_dentry,
30268 +                               const struct vfsmount *parent_mnt,
30269 +                               struct dentry *old_dentry,
30270 +                               struct inode *old_parent_inode,
30271 +                               struct vfsmount *old_mnt, const char *newname);
30272 +void gr_handle_rename(struct inode *old_dir, struct inode *new_dir,
30273 +                               struct dentry *old_dentry,
30274 +                               struct dentry *new_dentry,
30275 +                               struct vfsmount *mnt, const __u8 replace);
30276 +__u32 gr_check_link(const struct dentry *new_dentry,
30277 +                          const struct dentry *parent_dentry,
30278 +                          const struct vfsmount *parent_mnt,
30279 +                          const struct dentry *old_dentry,
30280 +                          const struct vfsmount *old_mnt);
30281 +int gr_acl_handle_filldir(const struct file *file, const char *name,
30282 +                                const unsigned int namelen, const ino_t ino);
30283 +
30284 +__u32 gr_acl_handle_unix(const struct dentry *dentry,
30285 +                               const struct vfsmount *mnt);
30286 +void gr_acl_handle_exit(void);
30287 +void gr_acl_handle_psacct(struct task_struct *task, const long code);
30288 +int gr_acl_handle_procpidmem(const struct task_struct *task);
30289 +
30290 +#ifdef CONFIG_GRKERNSEC
30291 +void gr_handle_mem_write(void);
30292 +void gr_handle_kmem_write(void);
30293 +void gr_handle_open_port(void);
30294 +int gr_handle_mem_mmap(const unsigned long offset,
30295 +                             struct vm_area_struct *vma);
30296 +
30297 +extern int grsec_enable_dmesg;
30298 +extern int grsec_enable_randsrc;
30299 +extern int grsec_enable_shm;
30300 +#endif
30301 +
30302 +#endif
30303 diff -urNp linux-2.6.27.10/include/linux/highmem.h linux-2.6.27.10/include/linux/highmem.h
30304 --- linux-2.6.27.10/include/linux/highmem.h     2008-11-07 12:55:34.000000000 -0500
30305 +++ linux-2.6.27.10/include/linux/highmem.h     2008-11-18 03:38:45.000000000 -0500
30306 @@ -122,6 +122,13 @@ static inline void clear_highpage(struct
30307         kunmap_atomic(kaddr, KM_USER0);
30308  }
30309  
30310 +static inline void sanitize_highpage(struct page *page)
30311 +{
30312 +       void *kaddr = kmap_atomic(page, KM_CLEARPAGE);
30313 +       clear_page(kaddr);
30314 +       kunmap_atomic(kaddr, KM_CLEARPAGE);
30315 +}
30316 +
30317  static inline void zero_user_segments(struct page *page,
30318         unsigned start1, unsigned end1,
30319         unsigned start2, unsigned end2)
30320 diff -urNp linux-2.6.27.10/include/linux/jbd2.h linux-2.6.27.10/include/linux/jbd2.h
30321 --- linux-2.6.27.10/include/linux/jbd2.h        2008-12-10 22:35:38.000000000 -0500
30322 +++ linux-2.6.27.10/include/linux/jbd2.h        2008-12-10 22:35:46.000000000 -0500
30323 @@ -66,7 +66,7 @@ extern u8 jbd2_journal_enable_debug;
30324                 }                                                       \
30325         } while (0)
30326  #else
30327 -#define jbd_debug(f, a...)     /**/
30328 +#define jbd_debug(f, a...)     do {} while (0)
30329  #endif
30330  
30331  static inline void *jbd2_alloc(size_t size, gfp_t flags)
30332 diff -urNp linux-2.6.27.10/include/linux/jbd.h linux-2.6.27.10/include/linux/jbd.h
30333 --- linux-2.6.27.10/include/linux/jbd.h 2008-12-21 01:16:52.000000000 -0500
30334 +++ linux-2.6.27.10/include/linux/jbd.h 2008-12-21 01:13:46.000000000 -0500
30335 @@ -66,7 +66,7 @@ extern u8 journal_enable_debug;
30336                 }                                                       \
30337         } while (0)
30338  #else
30339 -#define jbd_debug(f, a...)     /**/
30340 +#define jbd_debug(f, a...)     do {} while (0)
30341  #endif
30342  
30343  static inline void *jbd_alloc(size_t size, gfp_t flags)
30344 diff -urNp linux-2.6.27.10/include/linux/libata.h linux-2.6.27.10/include/linux/libata.h
30345 --- linux-2.6.27.10/include/linux/libata.h      2008-12-10 22:35:38.000000000 -0500
30346 +++ linux-2.6.27.10/include/linux/libata.h      2008-12-10 22:35:46.000000000 -0500
30347 @@ -64,11 +64,11 @@
30348  #ifdef ATA_VERBOSE_DEBUG
30349  #define VPRINTK(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30350  #else
30351 -#define VPRINTK(fmt, args...)
30352 +#define VPRINTK(fmt, args...) do {} while (0)
30353  #endif /* ATA_VERBOSE_DEBUG */
30354  #else
30355 -#define DPRINTK(fmt, args...)
30356 -#define VPRINTK(fmt, args...)
30357 +#define DPRINTK(fmt, args...) do {} while (0)
30358 +#define VPRINTK(fmt, args...) do {} while (0)
30359  #endif /* ATA_DEBUG */
30360  
30361  #define BPRINTK(fmt, args...) if (ap->flags & ATA_FLAG_DEBUGMSG) printk(KERN_ERR "%s: " fmt, __func__, ## args)
30362 diff -urNp linux-2.6.27.10/include/linux/mm.h linux-2.6.27.10/include/linux/mm.h
30363 --- linux-2.6.27.10/include/linux/mm.h  2008-11-07 12:55:34.000000000 -0500
30364 +++ linux-2.6.27.10/include/linux/mm.h  2008-12-21 00:44:29.000000000 -0500
30365 @@ -38,6 +38,7 @@ extern unsigned long mmap_min_addr;
30366  #include <asm/page.h>
30367  #include <asm/pgtable.h>
30368  #include <asm/processor.h>
30369 +#include <asm/mman.h>
30370  
30371  #define nth_page(page,n) pfn_to_page(page_to_pfn((page)) + (n))
30372  
30373 @@ -114,6 +115,10 @@ extern unsigned int kobjsize(const void 
30374  #define VM_MIXEDMAP    0x10000000      /* Can contain "struct page" and pure PFN pages */
30375  #define VM_SAO         0x20000000      /* Strong Access Ordering (powerpc) */
30376  
30377 +#ifdef CONFIG_PAX_PAGEEXEC
30378 +#define VM_PAGEEXEC    0x40000000      /* vma->vm_page_prot needs special handling */
30379 +#endif
30380 +
30381  #ifndef VM_STACK_DEFAULT_FLAGS         /* arch can override this */
30382  #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
30383  #endif
30384 @@ -874,6 +879,8 @@ struct shrinker {
30385  extern void register_shrinker(struct shrinker *);
30386  extern void unregister_shrinker(struct shrinker *);
30387  
30388 +pgprot_t vm_get_page_prot(unsigned long vm_flags);
30389 +
30390  int vma_wants_writenotify(struct vm_area_struct *vma);
30391  
30392  extern pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl);
30393 @@ -1129,6 +1136,7 @@ out:
30394  }
30395  
30396  extern int do_munmap(struct mm_struct *, unsigned long, size_t);
30397 +extern int __do_munmap(struct mm_struct *, unsigned long, size_t);
30398  
30399  extern unsigned long do_brk(unsigned long, unsigned long);
30400  
30401 @@ -1181,6 +1189,10 @@ extern struct vm_area_struct * find_vma(
30402  extern struct vm_area_struct * find_vma_prev(struct mm_struct * mm, unsigned long addr,
30403                                              struct vm_area_struct **pprev);
30404  
30405 +extern struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma);
30406 +extern void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma);
30407 +extern void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl);
30408 +
30409  /* Look up the first VMA which intersects the interval start_addr..end_addr-1,
30410     NULL if none.  Assume start_addr < end_addr. */
30411  static inline struct vm_area_struct * find_vma_intersection(struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
30412 @@ -1197,7 +1209,6 @@ static inline unsigned long vma_pages(st
30413         return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
30414  }
30415  
30416 -pgprot_t vm_get_page_prot(unsigned long vm_flags);
30417  struct vm_area_struct *find_extend_vma(struct mm_struct *, unsigned long addr);
30418  int remap_pfn_range(struct vm_area_struct *, unsigned long addr,
30419                         unsigned long pfn, unsigned long size, pgprot_t);
30420 @@ -1286,5 +1297,11 @@ int vmemmap_populate_basepages(struct pa
30421  int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
30422  void vmemmap_populate_print_last(void);
30423  
30424 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
30425 +extern void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot);
30426 +#else
30427 +static inline void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot) {}
30428 +#endif
30429 +
30430  #endif /* __KERNEL__ */
30431  #endif /* _LINUX_MM_H */
30432 diff -urNp linux-2.6.27.10/include/linux/mm_types.h linux-2.6.27.10/include/linux/mm_types.h
30433 --- linux-2.6.27.10/include/linux/mm_types.h    2008-11-07 12:55:34.000000000 -0500
30434 +++ linux-2.6.27.10/include/linux/mm_types.h    2008-11-18 03:38:45.000000000 -0500
30435 @@ -158,6 +158,8 @@ struct vm_area_struct {
30436  #ifdef CONFIG_NUMA
30437         struct mempolicy *vm_policy;    /* NUMA policy for the VMA */
30438  #endif
30439 +
30440 +       struct vm_area_struct *vm_mirror;/* PaX: mirror vma or NULL */
30441  };
30442  
30443  struct core_thread {
30444 @@ -257,6 +259,24 @@ struct mm_struct {
30445  #ifdef CONFIG_MMU_NOTIFIER
30446         struct mmu_notifier_mm *mmu_notifier_mm;
30447  #endif
30448 +
30449 +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) || defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30450 +       unsigned long pax_flags;
30451 +#endif
30452 +
30453 +#ifdef CONFIG_PAX_DLRESOLVE
30454 +       unsigned long call_dl_resolve;
30455 +#endif
30456 +
30457 +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT)
30458 +       unsigned long call_syscall;
30459 +#endif
30460 +
30461 +#ifdef CONFIG_PAX_ASLR
30462 +       unsigned long delta_mmap;               /* randomized offset */
30463 +       unsigned long delta_stack;              /* randomized offset */
30464 +#endif
30465 +
30466  };
30467  
30468  #endif /* _LINUX_MM_TYPES_H */
30469 diff -urNp linux-2.6.27.10/include/linux/module.h linux-2.6.27.10/include/linux/module.h
30470 --- linux-2.6.27.10/include/linux/module.h      2008-11-07 12:55:34.000000000 -0500
30471 +++ linux-2.6.27.10/include/linux/module.h      2008-11-18 03:38:45.000000000 -0500
30472 @@ -282,16 +282,16 @@ struct module
30473         int (*init)(void);
30474  
30475         /* If this is non-NULL, vfree after init() returns */
30476 -       void *module_init;
30477 +       void *module_init_rx, *module_init_rw;
30478  
30479         /* Here is the actual code + data, vfree'd on unload. */
30480 -       void *module_core;
30481 +       void *module_core_rx, *module_core_rw;
30482  
30483         /* Here are the sizes of the init and core sections */
30484 -       unsigned int init_size, core_size;
30485 +       unsigned int init_size_rw, core_size_rw;
30486  
30487         /* The size of the executable code in each section.  */
30488 -       unsigned int init_text_size, core_text_size;
30489 +       unsigned int init_size_rx, core_size_rx;
30490  
30491         /* The handle returned from unwind_add_table. */
30492         void *unwind_info;
30493 diff -urNp linux-2.6.27.10/include/linux/moduleloader.h linux-2.6.27.10/include/linux/moduleloader.h
30494 --- linux-2.6.27.10/include/linux/moduleloader.h        2008-11-07 12:55:34.000000000 -0500
30495 +++ linux-2.6.27.10/include/linux/moduleloader.h        2008-11-18 03:38:45.000000000 -0500
30496 @@ -17,9 +17,21 @@ int module_frob_arch_sections(Elf_Ehdr *
30497     sections.  Returns NULL on failure. */
30498  void *module_alloc(unsigned long size);
30499  
30500 +#ifdef CONFIG_PAX_KERNEXEC
30501 +void *module_alloc_exec(unsigned long size);
30502 +#else
30503 +#define module_alloc_exec(x) module_alloc(x)
30504 +#endif
30505 +
30506  /* Free memory returned from module_alloc. */
30507  void module_free(struct module *mod, void *module_region);
30508  
30509 +#ifdef CONFIG_PAX_KERNEXEC
30510 +void module_free_exec(struct module *mod, void *module_region);
30511 +#else
30512 +#define module_free_exec(x, y) module_free(x, y)
30513 +#endif
30514 +
30515  /* Apply the given relocation to the (simplified) ELF.  Return -error
30516     or 0. */
30517  int apply_relocate(Elf_Shdr *sechdrs,
30518 diff -urNp linux-2.6.27.10/include/linux/namei.h linux-2.6.27.10/include/linux/namei.h
30519 --- linux-2.6.27.10/include/linux/namei.h       2008-11-07 12:55:34.000000000 -0500
30520 +++ linux-2.6.27.10/include/linux/namei.h       2008-11-18 03:38:45.000000000 -0500
30521 @@ -21,7 +21,7 @@ struct nameidata {
30522         unsigned int    flags;
30523         int             last_type;
30524         unsigned        depth;
30525 -       char *saved_names[MAX_NESTED_LINKS + 1];
30526 +       const char *saved_names[MAX_NESTED_LINKS + 1];
30527  
30528         /* Intent data */
30529         union {
30530 @@ -80,12 +80,12 @@ extern int follow_up(struct vfsmount **,
30531  extern struct dentry *lock_rename(struct dentry *, struct dentry *);
30532  extern void unlock_rename(struct dentry *, struct dentry *);
30533  
30534 -static inline void nd_set_link(struct nameidata *nd, char *path)
30535 +static inline void nd_set_link(struct nameidata *nd, const char *path)
30536  {
30537         nd->saved_names[nd->depth] = path;
30538  }
30539  
30540 -static inline char *nd_get_link(struct nameidata *nd)
30541 +static inline const char *nd_get_link(struct nameidata *nd)
30542  {
30543         return nd->saved_names[nd->depth];
30544  }
30545 diff -urNp linux-2.6.27.10/include/linux/nodemask.h linux-2.6.27.10/include/linux/nodemask.h
30546 --- linux-2.6.27.10/include/linux/nodemask.h    2008-11-07 12:55:34.000000000 -0500
30547 +++ linux-2.6.27.10/include/linux/nodemask.h    2008-11-18 03:38:45.000000000 -0500
30548 @@ -442,11 +442,11 @@ static inline int num_node_state(enum no
30549  
30550  #define any_online_node(mask)                  \
30551  ({                                             \
30552 -       int node;                               \
30553 -       for_each_node_mask(node, (mask))        \
30554 -               if (node_online(node))          \
30555 +       int __node;                             \
30556 +       for_each_node_mask(__node, (mask))      \
30557 +               if (node_online(__node))        \
30558                         break;                  \
30559 -       node;                                   \
30560 +       __node;                                 \
30561  })
30562  
30563  #define num_online_nodes()     num_node_state(N_ONLINE)
30564 diff -urNp linux-2.6.27.10/include/linux/percpu.h linux-2.6.27.10/include/linux/percpu.h
30565 --- linux-2.6.27.10/include/linux/percpu.h      2008-11-07 12:55:34.000000000 -0500
30566 +++ linux-2.6.27.10/include/linux/percpu.h      2008-11-18 03:38:45.000000000 -0500
30567 @@ -43,7 +43,7 @@
30568  #endif
30569  
30570  #define PERCPU_ENOUGH_ROOM                                             \
30571 -       (__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE)
30572 +       ((unsigned long)(__per_cpu_end - __per_cpu_start + PERCPU_MODULE_RESERVE))
30573  #endif /* PERCPU_ENOUGH_ROOM */
30574  
30575  /*
30576 diff -urNp linux-2.6.27.10/include/linux/poison.h linux-2.6.27.10/include/linux/poison.h
30577 --- linux-2.6.27.10/include/linux/poison.h      2008-11-07 12:55:34.000000000 -0500
30578 +++ linux-2.6.27.10/include/linux/poison.h      2008-11-18 03:38:45.000000000 -0500
30579 @@ -7,8 +7,8 @@
30580   * under normal circumstances, used to verify that nobody uses
30581   * non-initialized list entries.
30582   */
30583 -#define LIST_POISON1  ((void *) 0x00100100)
30584 -#define LIST_POISON2  ((void *) 0x00200200)
30585 +#define LIST_POISON1  ((void *) 0xFF1001FFFF1001FFULL)
30586 +#define LIST_POISON2  ((void *) 0xFF2002FFFF2002FFULL)
30587  
30588  /********** include/linux/timer.h **********/
30589  /*
30590 diff -urNp linux-2.6.27.10/include/linux/random.h linux-2.6.27.10/include/linux/random.h
30591 --- linux-2.6.27.10/include/linux/random.h      2008-11-07 12:55:34.000000000 -0500
30592 +++ linux-2.6.27.10/include/linux/random.h      2008-11-18 03:38:45.000000000 -0500
30593 @@ -72,6 +72,11 @@ unsigned long randomize_range(unsigned l
30594  u32 random32(void);
30595  void srandom32(u32 seed);
30596  
30597 +static inline unsigned long pax_get_random_long(void)
30598 +{
30599 +       return random32() + (sizeof(long) > 4 ? (unsigned long)random32() << 32 : 0);
30600 +}
30601 +
30602  #endif /* __KERNEL___ */
30603  
30604  #endif /* _LINUX_RANDOM_H */
30605 diff -urNp linux-2.6.27.10/include/linux/sched.h linux-2.6.27.10/include/linux/sched.h
30606 --- linux-2.6.27.10/include/linux/sched.h       2008-12-10 22:35:38.000000000 -0500
30607 +++ linux-2.6.27.10/include/linux/sched.h       2008-12-10 22:35:46.000000000 -0500
30608 @@ -96,6 +96,7 @@ struct exec_domain;
30609  struct futex_pi_state;
30610  struct robust_list_head;
30611  struct bio;
30612 +struct linux_binprm;
30613  
30614  /*
30615   * List of flags we want to share for kernel threads,
30616 @@ -545,6 +546,15 @@ struct signal_struct {
30617         unsigned audit_tty;
30618         struct tty_audit_buf *tty_audit_buf;
30619  #endif
30620 +
30621 +#ifdef CONFIG_GRKERNSEC
30622 +       u32 curr_ip;
30623 +       u32 gr_saddr;
30624 +       u32 gr_daddr;
30625 +       u16 gr_sport;
30626 +       u16 gr_dport;
30627 +       u8 used_accept:1;
30628 +#endif
30629  };
30630  
30631  /* Context switch must be unlocked if interrupts are to be enabled */
30632 @@ -1030,7 +1040,7 @@ struct sched_rt_entity {
30633  
30634  struct task_struct {
30635         volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
30636 -       void *stack;
30637 +       struct thread_info *stack;
30638         atomic_t usage;
30639         unsigned int flags;     /* per process flags, defined below */
30640         unsigned int ptrace;
30641 @@ -1095,10 +1105,9 @@ struct task_struct {
30642         pid_t pid;
30643         pid_t tgid;
30644  
30645 -#ifdef CONFIG_CC_STACKPROTECTOR
30646         /* Canary value for the -fstack-protector gcc feature */
30647         unsigned long stack_canary;
30648 -#endif
30649 +
30650         /* 
30651          * pointers to (original) parent process, youngest child, younger sibling,
30652          * older sibling, respectively.  (p->father can be replaced with 
30653 @@ -1126,8 +1135,8 @@ struct task_struct {
30654         struct list_head thread_group;
30655  
30656         struct completion *vfork_done;          /* for vfork() */
30657 -       int __user *set_child_tid;              /* CLONE_CHILD_SETTID */
30658 -       int __user *clear_child_tid;            /* CLONE_CHILD_CLEARTID */
30659 +       pid_t __user *set_child_tid;            /* CLONE_CHILD_SETTID */
30660 +       pid_t __user *clear_child_tid;          /* CLONE_CHILD_CLEARTID */
30661  
30662         cputime_t utime, stime, utimescaled, stimescaled;
30663         cputime_t gtime;
30664 @@ -1307,8 +1316,64 @@ struct task_struct {
30665         int latency_record_count;
30666         struct latency_record latency_record[LT_SAVECOUNT];
30667  #endif
30668 +
30669 +#ifdef CONFIG_GRKERNSEC
30670 +       /* grsecurity */
30671 +       struct acl_subject_label *acl;
30672 +       struct acl_role_label *role;
30673 +       struct file *exec_file;
30674 +       u16 acl_role_id;
30675 +       u8 acl_sp_role;
30676 +       u8 is_writable;
30677 +       u8 brute;
30678 +#endif
30679 +
30680  };
30681  
30682 +#define MF_PAX_PAGEEXEC                0x01000000      /* Paging based non-executable pages */
30683 +#define MF_PAX_EMUTRAMP                0x02000000      /* Emulate trampolines */
30684 +#define MF_PAX_MPROTECT                0x04000000      /* Restrict mprotect() */
30685 +#define MF_PAX_RANDMMAP                0x08000000      /* Randomize mmap() base */
30686 +/*#define MF_PAX_RANDEXEC              0x10000000*/    /* Randomize ET_EXEC base */
30687 +#define MF_PAX_SEGMEXEC                0x20000000      /* Segmentation based non-executable pages */
30688 +
30689 +#ifdef CONFIG_PAX_SOFTMODE
30690 +extern unsigned int pax_softmode;
30691 +#endif
30692 +
30693 +extern int pax_check_flags(unsigned long *);
30694 +
30695 +/* if tsk != current then task_lock must be held on it */
30696 +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)
30697 +static inline unsigned long pax_get_flags(struct task_struct *tsk)
30698 +{
30699 +       if (likely(tsk->mm))
30700 +               return tsk->mm->pax_flags;
30701 +       else
30702 +               return 0UL;
30703 +}
30704 +
30705 +/* if tsk != current then task_lock must be held on it */
30706 +static inline long pax_set_flags(struct task_struct *tsk, unsigned long flags)
30707 +{
30708 +       if (likely(tsk->mm)) {
30709 +               tsk->mm->pax_flags = flags;
30710 +               return 0;
30711 +       }
30712 +       return -EINVAL;
30713 +}
30714 +#endif
30715 +
30716 +#ifdef CONFIG_PAX_HAVE_ACL_FLAGS
30717 +extern void pax_set_initial_flags(struct linux_binprm *bprm);
30718 +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS)
30719 +extern void (*pax_set_initial_flags_func)(struct linux_binprm *bprm);
30720 +#endif
30721 +
30722 +void pax_report_fault(struct pt_regs *regs, void *pc, void *sp);
30723 +void pax_report_insns(void *pc, void *sp);
30724 +void pax_report_refcount_overflow(struct pt_regs *regs);
30725 +
30726  /*
30727   * Priority of a process goes from 0..MAX_PRIO-1, valid RT
30728   * priority is 0..MAX_RT_PRIO-1, and SCHED_NORMAL/SCHED_BATCH
30729 @@ -1849,7 +1914,7 @@ extern void __cleanup_sighand(struct sig
30730  extern void exit_itimers(struct signal_struct *);
30731  extern void flush_itimer_signals(void);
30732  
30733 -extern NORET_TYPE void do_group_exit(int);
30734 +extern NORET_TYPE void do_group_exit(int) ATTRIB_NORET;
30735  
30736  extern void daemonize(const char *, ...);
30737  extern int allow_signal(int);
30738 @@ -1952,8 +2017,8 @@ static inline void unlock_task_sighand(s
30739  
30740  #ifndef __HAVE_THREAD_FUNCTIONS
30741  
30742 -#define task_thread_info(task) ((struct thread_info *)(task)->stack)
30743 -#define task_stack_page(task)  ((task)->stack)
30744 +#define task_thread_info(task) ((task)->stack)
30745 +#define task_stack_page(task)  ((void *)(task)->stack)
30746  
30747  static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
30748  {
30749 diff -urNp linux-2.6.27.10/include/linux/screen_info.h linux-2.6.27.10/include/linux/screen_info.h
30750 --- linux-2.6.27.10/include/linux/screen_info.h 2008-11-07 12:55:34.000000000 -0500
30751 +++ linux-2.6.27.10/include/linux/screen_info.h 2008-11-18 03:38:45.000000000 -0500
30752 @@ -42,7 +42,8 @@ struct screen_info {
30753         __u16 pages;            /* 0x32 */
30754         __u16 vesa_attributes;  /* 0x34 */
30755         __u32 capabilities;     /* 0x36 */
30756 -       __u8  _reserved[6];     /* 0x3a */
30757 +       __u16 vesapm_size;      /* 0x3a */
30758 +       __u8  _reserved[4];     /* 0x3c */
30759  } __attribute__((packed));
30760  
30761  #define VIDEO_TYPE_MDA         0x10    /* Monochrome Text Display      */
30762 diff -urNp linux-2.6.27.10/include/linux/shm.h linux-2.6.27.10/include/linux/shm.h
30763 --- linux-2.6.27.10/include/linux/shm.h 2008-11-07 12:55:34.000000000 -0500
30764 +++ linux-2.6.27.10/include/linux/shm.h 2008-11-18 03:38:45.000000000 -0500
30765 @@ -95,6 +95,10 @@ struct shmid_kernel /* private to the ke
30766         pid_t                   shm_cprid;
30767         pid_t                   shm_lprid;
30768         struct user_struct      *mlock_user;
30769 +#ifdef CONFIG_GRKERNSEC
30770 +       time_t                  shm_createtime;
30771 +       pid_t                   shm_lapid;
30772 +#endif
30773  };
30774  
30775  /* shm_mode upper byte flags */
30776 diff -urNp linux-2.6.27.10/include/linux/slab.h linux-2.6.27.10/include/linux/slab.h
30777 --- linux-2.6.27.10/include/linux/slab.h        2008-11-07 12:55:34.000000000 -0500
30778 +++ linux-2.6.27.10/include/linux/slab.h        2008-11-18 03:38:45.000000000 -0500
30779 @@ -45,10 +45,9 @@
30780   * ZERO_SIZE_PTR can be passed to kfree though in the same way that NULL can.
30781   * Both make kfree a no-op.
30782   */
30783 -#define ZERO_SIZE_PTR ((void *)16)
30784 +#define ZERO_SIZE_PTR ((void *)-1024L)
30785  
30786 -#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
30787 -                               (unsigned long)ZERO_SIZE_PTR)
30788 +#define ZERO_OR_NULL_PTR(x) (!(x) || (x) == ZERO_SIZE_PTR)
30789  
30790  /*
30791   * struct kmem_cache related prototypes
30792 diff -urNp linux-2.6.27.10/include/linux/sysctl.h linux-2.6.27.10/include/linux/sysctl.h
30793 --- linux-2.6.27.10/include/linux/sysctl.h      2008-11-07 12:55:34.000000000 -0500
30794 +++ linux-2.6.27.10/include/linux/sysctl.h      2008-11-18 03:38:45.000000000 -0500
30795 @@ -165,7 +165,11 @@ enum
30796         KERN_PANIC_ON_NMI=76, /* int: whether we will panic on an unrecovered */
30797  };
30798  
30799 -
30800 +#ifdef CONFIG_PAX_SOFTMODE
30801 +enum {
30802 +       PAX_SOFTMODE=1          /* PaX: disable/enable soft mode */
30803 +};
30804 +#endif
30805  
30806  /* CTL_VM names: */
30807  enum
30808 diff -urNp linux-2.6.27.10/include/linux/thread_info.h linux-2.6.27.10/include/linux/thread_info.h
30809 --- linux-2.6.27.10/include/linux/thread_info.h 2008-11-07 12:55:34.000000000 -0500
30810 +++ linux-2.6.27.10/include/linux/thread_info.h 2008-11-18 03:38:45.000000000 -0500
30811 @@ -23,7 +23,7 @@ struct restart_block {
30812                 };
30813                 /* For futex_wait */
30814                 struct {
30815 -                       u32 *uaddr;
30816 +                       u32 __user *uaddr;
30817                         u32 val;
30818                         u32 flags;
30819                         u32 bitset;
30820 diff -urNp linux-2.6.27.10/include/linux/uaccess.h linux-2.6.27.10/include/linux/uaccess.h
30821 --- linux-2.6.27.10/include/linux/uaccess.h     2008-11-07 12:55:34.000000000 -0500
30822 +++ linux-2.6.27.10/include/linux/uaccess.h     2008-11-18 03:38:45.000000000 -0500
30823 @@ -76,11 +76,11 @@ static inline unsigned long __copy_from_
30824                 long ret;                               \
30825                 mm_segment_t old_fs = get_fs();         \
30826                                                         \
30827 -               set_fs(KERNEL_DS);                      \
30828                 pagefault_disable();                    \
30829 +               set_fs(KERNEL_DS);                      \
30830                 ret = __get_user(retval, (__force typeof(retval) __user *)(addr));              \
30831 -               pagefault_enable();                     \
30832                 set_fs(old_fs);                         \
30833 +               pagefault_enable();                     \
30834                 ret;                                    \
30835         })
30836  
30837 diff -urNp linux-2.6.27.10/include/linux/vmalloc.h linux-2.6.27.10/include/linux/vmalloc.h
30838 --- linux-2.6.27.10/include/linux/vmalloc.h     2008-11-07 12:55:34.000000000 -0500
30839 +++ linux-2.6.27.10/include/linux/vmalloc.h     2008-11-18 03:38:45.000000000 -0500
30840 @@ -12,6 +12,11 @@ struct vm_area_struct;               /* vma defining 
30841  #define VM_MAP         0x00000004      /* vmap()ed pages */
30842  #define VM_USERMAP     0x00000008      /* suitable for remap_vmalloc_range */
30843  #define VM_VPAGES      0x00000010      /* buffer for pages was vmalloc'ed */
30844 +
30845 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
30846 +#define VM_KERNEXEC    0x00000020      /* allocate from executable kernel memory range */
30847 +#endif
30848 +
30849  /* bits [20..32] reserved for arch specific ioremap internals */
30850  
30851  /*
30852 diff -urNp linux-2.6.27.10/include/net/sctp/sctp.h linux-2.6.27.10/include/net/sctp/sctp.h
30853 --- linux-2.6.27.10/include/net/sctp/sctp.h     2008-11-07 12:55:34.000000000 -0500
30854 +++ linux-2.6.27.10/include/net/sctp/sctp.h     2008-11-18 03:38:45.000000000 -0500
30855 @@ -309,8 +309,8 @@ extern int sctp_debug_flag;
30856  
30857  #else  /* SCTP_DEBUG */
30858  
30859 -#define SCTP_DEBUG_PRINTK(whatever...)
30860 -#define SCTP_DEBUG_PRINTK_IPADDR(whatever...)
30861 +#define SCTP_DEBUG_PRINTK(whatever...) do {} while (0)
30862 +#define SCTP_DEBUG_PRINTK_IPADDR(whatever...) do {} while (0)
30863  #define SCTP_ENABLE_DEBUG
30864  #define SCTP_DISABLE_DEBUG
30865  #define SCTP_ASSERT(expr, str, func)
30866 diff -urNp linux-2.6.27.10/include/sound/core.h linux-2.6.27.10/include/sound/core.h
30867 --- linux-2.6.27.10/include/sound/core.h        2008-11-07 12:55:34.000000000 -0500
30868 +++ linux-2.6.27.10/include/sound/core.h        2008-11-18 03:38:45.000000000 -0500
30869 @@ -406,9 +406,9 @@ void snd_verbose_printd(const char *file
30870  
30871  #else /* !CONFIG_SND_DEBUG */
30872  
30873 -#define snd_printd(fmt, args...)       /* nothing */
30874 +#define snd_printd(fmt, args...)       do {} while (0)
30875  #define snd_assert(expr, args...)      (void)(expr)
30876 -#define snd_BUG()                      /* nothing */
30877 +#define snd_BUG()                      do {} while (0)
30878  
30879  #endif /* CONFIG_SND_DEBUG */
30880  
30881 @@ -422,7 +422,7 @@ void snd_verbose_printd(const char *file
30882   */
30883  #define snd_printdd(format, args...) snd_printk(format, ##args)
30884  #else
30885 -#define snd_printdd(format, args...) /* nothing */
30886 +#define snd_printdd(format, args...) do {} while (0)
30887  #endif
30888  
30889  
30890 diff -urNp linux-2.6.27.10/include/video/uvesafb.h linux-2.6.27.10/include/video/uvesafb.h
30891 --- linux-2.6.27.10/include/video/uvesafb.h     2008-11-07 12:55:34.000000000 -0500
30892 +++ linux-2.6.27.10/include/video/uvesafb.h     2008-11-18 03:38:45.000000000 -0500
30893 @@ -175,6 +175,7 @@ struct uvesafb_par {
30894         u8 ypan;                        /* 0 - nothing, 1 - ypan, 2 - ywrap */
30895         u8 pmi_setpal;                  /* PMI for palette changes */
30896         u16 *pmi_base;                  /* protected mode interface location */
30897 +       u8 *pmi_code;                   /* protected mode code location */
30898         void *pmi_start;
30899         void *pmi_pal;
30900         u8 *vbe_state_orig;             /*
30901 diff -urNp linux-2.6.27.10/init/do_mounts.c linux-2.6.27.10/init/do_mounts.c
30902 --- linux-2.6.27.10/init/do_mounts.c    2008-11-07 12:55:34.000000000 -0500
30903 +++ linux-2.6.27.10/init/do_mounts.c    2008-11-18 03:38:45.000000000 -0500
30904 @@ -214,11 +214,11 @@ static void __init get_fs_names(char *pa
30905  
30906  static int __init do_mount_root(char *name, char *fs, int flags, void *data)
30907  {
30908 -       int err = sys_mount(name, "/root", fs, flags, data);
30909 +       int err = sys_mount((char __user *)name, (char __user *)"/root", (char __user *)fs, flags, (void __user *)data);
30910         if (err)
30911                 return err;
30912  
30913 -       sys_chdir("/root");
30914 +       sys_chdir((char __user *)"/root");
30915         ROOT_DEV = current->fs->pwd.mnt->mnt_sb->s_dev;
30916         printk("VFS: Mounted root (%s filesystem)%s.\n",
30917                current->fs->pwd.mnt->mnt_sb->s_type->name,
30918 @@ -304,18 +304,18 @@ void __init change_floppy(char *fmt, ...
30919         va_start(args, fmt);
30920         vsprintf(buf, fmt, args);
30921         va_end(args);
30922 -       fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
30923 +       fd = sys_open((char __user *)"/dev/root", O_RDWR | O_NDELAY, 0);
30924         if (fd >= 0) {
30925                 sys_ioctl(fd, FDEJECT, 0);
30926                 sys_close(fd);
30927         }
30928         printk(KERN_NOTICE "VFS: Insert %s and press ENTER\n", buf);
30929 -       fd = sys_open("/dev/console", O_RDWR, 0);
30930 +       fd = sys_open((char __user *)"/dev/console", O_RDWR, 0);
30931         if (fd >= 0) {
30932                 sys_ioctl(fd, TCGETS, (long)&termios);
30933                 termios.c_lflag &= ~ICANON;
30934                 sys_ioctl(fd, TCSETSF, (long)&termios);
30935 -               sys_read(fd, &c, 1);
30936 +               sys_read(fd, (char __user *)&c, 1);
30937                 termios.c_lflag |= ICANON;
30938                 sys_ioctl(fd, TCSETSF, (long)&termios);
30939                 sys_close(fd);
30940 @@ -402,7 +402,7 @@ void __init prepare_namespace(void)
30941  
30942         mount_root();
30943  out:
30944 -       sys_mount(".", "/", NULL, MS_MOVE, NULL);
30945 -       sys_chroot(".");
30946 +       sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
30947 +       sys_chroot((char __user *)".");
30948  }
30949  
30950 diff -urNp linux-2.6.27.10/init/do_mounts.h linux-2.6.27.10/init/do_mounts.h
30951 --- linux-2.6.27.10/init/do_mounts.h    2008-11-07 12:55:34.000000000 -0500
30952 +++ linux-2.6.27.10/init/do_mounts.h    2008-11-18 03:38:45.000000000 -0500
30953 @@ -14,15 +14,15 @@ extern int root_mountflags;
30954  
30955  static inline int create_dev(char *name, dev_t dev)
30956  {
30957 -       sys_unlink(name);
30958 -       return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
30959 +       sys_unlink((char __user *)name);
30960 +       return sys_mknod((char __user *)name, S_IFBLK|0600, new_encode_dev(dev));
30961  }
30962  
30963  #if BITS_PER_LONG == 32
30964  static inline u32 bstat(char *name)
30965  {
30966         struct stat64 stat;
30967 -       if (sys_stat64(name, &stat) != 0)
30968 +       if (sys_stat64((char __user *)name, (struct stat64 __user *)&stat) != 0)
30969                 return 0;
30970         if (!S_ISBLK(stat.st_mode))
30971                 return 0;
30972 diff -urNp linux-2.6.27.10/init/do_mounts_initrd.c linux-2.6.27.10/init/do_mounts_initrd.c
30973 --- linux-2.6.27.10/init/do_mounts_initrd.c     2008-11-07 12:55:34.000000000 -0500
30974 +++ linux-2.6.27.10/init/do_mounts_initrd.c     2008-11-18 03:38:45.000000000 -0500
30975 @@ -32,7 +32,7 @@ static int __init do_linuxrc(void * shel
30976         sys_close(old_fd);sys_close(root_fd);
30977         sys_close(0);sys_close(1);sys_close(2);
30978         sys_setsid();
30979 -       (void) sys_open("/dev/console",O_RDWR,0);
30980 +       (void) sys_open((const char __user *)"/dev/console",O_RDWR,0);
30981         (void) sys_dup(0);
30982         (void) sys_dup(0);
30983         return kernel_execve(shell, argv, envp_init);
30984 @@ -47,13 +47,13 @@ static void __init handle_initrd(void)
30985         create_dev("/dev/root.old", Root_RAM0);
30986         /* mount initrd on rootfs' /root */
30987         mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
30988 -       sys_mkdir("/old", 0700);
30989 -       root_fd = sys_open("/", 0, 0);
30990 -       old_fd = sys_open("/old", 0, 0);
30991 +       sys_mkdir((const char __user *)"/old", 0700);
30992 +       root_fd = sys_open((const char __user *)"/", 0, 0);
30993 +       old_fd = sys_open((const char __user *)"/old", 0, 0);
30994         /* move initrd over / and chdir/chroot in initrd root */
30995 -       sys_chdir("/root");
30996 -       sys_mount(".", "/", NULL, MS_MOVE, NULL);
30997 -       sys_chroot(".");
30998 +       sys_chdir((const char __user *)"/root");
30999 +       sys_mount((char __user *)".", (char __user *)"/", NULL, MS_MOVE, NULL);
31000 +       sys_chroot((const char __user *)".");
31001  
31002         /*
31003          * In case that a resume from disk is carried out by linuxrc or one of
31004 @@ -70,15 +70,15 @@ static void __init handle_initrd(void)
31005  
31006         /* move initrd to rootfs' /old */
31007         sys_fchdir(old_fd);
31008 -       sys_mount("/", ".", NULL, MS_MOVE, NULL);
31009 +       sys_mount((char __user *)"/", (char __user *)".", NULL, MS_MOVE, NULL);
31010         /* switch root and cwd back to / of rootfs */
31011         sys_fchdir(root_fd);
31012 -       sys_chroot(".");
31013 +       sys_chroot((const char __user *)".");
31014         sys_close(old_fd);
31015         sys_close(root_fd);
31016  
31017         if (new_decode_dev(real_root_dev) == Root_RAM0) {
31018 -               sys_chdir("/old");
31019 +               sys_chdir((const char __user *)"/old");
31020                 return;
31021         }
31022  
31023 @@ -86,17 +86,17 @@ static void __init handle_initrd(void)
31024         mount_root();
31025  
31026         printk(KERN_NOTICE "Trying to move old root to /initrd ... ");
31027 -       error = sys_mount("/old", "/root/initrd", NULL, MS_MOVE, NULL);
31028 +       error = sys_mount((char __user *)"/old", (char __user *)"/root/initrd", NULL, MS_MOVE, NULL);
31029         if (!error)
31030                 printk("okay\n");
31031         else {
31032 -               int fd = sys_open("/dev/root.old", O_RDWR, 0);
31033 +               int fd = sys_open((const char __user *)"/dev/root.old", O_RDWR, 0);
31034                 if (error == -ENOENT)
31035                         printk("/initrd does not exist. Ignored.\n");
31036                 else
31037                         printk("failed\n");
31038                 printk(KERN_NOTICE "Unmounting old root\n");
31039 -               sys_umount("/old", MNT_DETACH);
31040 +               sys_umount((char __user *)"/old", MNT_DETACH);
31041                 printk(KERN_NOTICE "Trying to free ramdisk memory ... ");
31042                 if (fd < 0) {
31043                         error = fd;
31044 @@ -119,11 +119,11 @@ int __init initrd_load(void)
31045                  * mounted in the normal path.
31046                  */
31047                 if (rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) {
31048 -                       sys_unlink("/initrd.image");
31049 +                       sys_unlink((const char __user *)"/initrd.image");
31050                         handle_initrd();
31051                         return 1;
31052                 }
31053         }
31054 -       sys_unlink("/initrd.image");
31055 +       sys_unlink((const char __user *)"/initrd.image");
31056         return 0;
31057  }
31058 diff -urNp linux-2.6.27.10/init/do_mounts_md.c linux-2.6.27.10/init/do_mounts_md.c
31059 --- linux-2.6.27.10/init/do_mounts_md.c 2008-11-07 12:55:34.000000000 -0500
31060 +++ linux-2.6.27.10/init/do_mounts_md.c 2008-11-18 03:38:45.000000000 -0500
31061 @@ -166,7 +166,7 @@ static void __init md_setup_drive(void)
31062                         partitioned ? "_d" : "", minor,
31063                         md_setup_args[ent].device_names);
31064  
31065 -               fd = sys_open(name, 0, 0);
31066 +               fd = sys_open((char __user *)name, 0, 0);
31067                 if (fd < 0) {
31068                         printk(KERN_ERR "md: open failed - cannot start "
31069                                         "array %s\n", name);
31070 @@ -229,7 +229,7 @@ static void __init md_setup_drive(void)
31071                          * array without it
31072                          */
31073                         sys_close(fd);
31074 -                       fd = sys_open(name, 0, 0);
31075 +                       fd = sys_open((char __user *)name, 0, 0);
31076                         sys_ioctl(fd, BLKRRPART, 0);
31077                 }
31078                 sys_close(fd);
31079 @@ -270,7 +270,7 @@ void __init md_run_setup(void)
31080         if (raid_noautodetect)
31081                 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
31082         else {
31083 -               int fd = sys_open("/dev/md0", 0, 0);
31084 +               int fd = sys_open((char __user *)"/dev/md0", 0, 0);
31085                 if (fd >= 0) {
31086                         sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
31087                         sys_close(fd);
31088 diff -urNp linux-2.6.27.10/init/initramfs.c linux-2.6.27.10/init/initramfs.c
31089 --- linux-2.6.27.10/init/initramfs.c    2008-11-07 12:55:34.000000000 -0500
31090 +++ linux-2.6.27.10/init/initramfs.c    2008-11-18 03:38:45.000000000 -0500
31091 @@ -230,7 +230,7 @@ static int __init maybe_link(void)
31092         if (nlink >= 2) {
31093                 char *old = find_link(major, minor, ino, mode, collected);
31094                 if (old)
31095 -                       return (sys_link(old, collected) < 0) ? -1 : 1;
31096 +                       return (sys_link((char __user *)old, (char __user *)collected) < 0) ? -1 : 1;
31097         }
31098         return 0;
31099  }
31100 @@ -239,11 +239,11 @@ static void __init clean_path(char *path
31101  {
31102         struct stat st;
31103  
31104 -       if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
31105 +       if (!sys_newlstat((char __user *)path, (struct stat __user *)&st) && (st.st_mode^mode) & S_IFMT) {
31106                 if (S_ISDIR(st.st_mode))
31107 -                       sys_rmdir(path);
31108 +                       sys_rmdir((char __user *)path);
31109                 else
31110 -                       sys_unlink(path);
31111 +                       sys_unlink((char __user *)path);
31112         }
31113  }
31114  
31115 @@ -266,7 +266,7 @@ static int __init do_name(void)
31116                         int openflags = O_WRONLY|O_CREAT;
31117                         if (ml != 1)
31118                                 openflags |= O_TRUNC;
31119 -                       wfd = sys_open(collected, openflags, mode);
31120 +                       wfd = sys_open((char __user *)collected, openflags, mode);
31121  
31122                         if (wfd >= 0) {
31123                                 sys_fchown(wfd, uid, gid);
31124 @@ -275,15 +275,15 @@ static int __init do_name(void)
31125                         }
31126                 }
31127         } else if (S_ISDIR(mode)) {
31128 -               sys_mkdir(collected, mode);
31129 -               sys_chown(collected, uid, gid);
31130 -               sys_chmod(collected, mode);
31131 +               sys_mkdir((char __user *)collected, mode);
31132 +               sys_chown((char __user *)collected, uid, gid);
31133 +               sys_chmod((char __user *)collected, mode);
31134         } else if (S_ISBLK(mode) || S_ISCHR(mode) ||
31135                    S_ISFIFO(mode) || S_ISSOCK(mode)) {
31136                 if (maybe_link() == 0) {
31137 -                       sys_mknod(collected, mode, rdev);
31138 -                       sys_chown(collected, uid, gid);
31139 -                       sys_chmod(collected, mode);
31140 +                       sys_mknod((char __user *)collected, mode, rdev);
31141 +                       sys_chown((char __user *)collected, uid, gid);
31142 +                       sys_chmod((char __user *)collected, mode);
31143                 }
31144         }
31145         return 0;
31146 @@ -292,13 +292,13 @@ static int __init do_name(void)
31147  static int __init do_copy(void)
31148  {
31149         if (count >= body_len) {
31150 -               sys_write(wfd, victim, body_len);
31151 +               sys_write(wfd, (char __user *)victim, body_len);
31152                 sys_close(wfd);
31153                 eat(body_len);
31154                 state = SkipIt;
31155                 return 0;
31156         } else {
31157 -               sys_write(wfd, victim, count);
31158 +               sys_write(wfd, (char __user *)victim, count);
31159                 body_len -= count;
31160                 eat(count);
31161                 return 1;
31162 @@ -309,8 +309,8 @@ static int __init do_symlink(void)
31163  {
31164         collected[N_ALIGN(name_len) + body_len] = '\0';
31165         clean_path(collected, 0);
31166 -       sys_symlink(collected + N_ALIGN(name_len), collected);
31167 -       sys_lchown(collected, uid, gid);
31168 +       sys_symlink((char __user *)collected + N_ALIGN(name_len), (char __user *)collected);
31169 +       sys_lchown((char __user *)collected, uid, gid);
31170         state = SkipIt;
31171         next_state = Reset;
31172         return 0;
31173 diff -urNp linux-2.6.27.10/init/Kconfig linux-2.6.27.10/init/Kconfig
31174 --- linux-2.6.27.10/init/Kconfig        2008-11-07 12:55:34.000000000 -0500
31175 +++ linux-2.6.27.10/init/Kconfig        2008-11-18 03:38:45.000000000 -0500
31176 @@ -561,6 +561,7 @@ config SYSCTL_SYSCALL
31177  config KALLSYMS
31178          bool "Load all symbols for debugging/ksymoops" if EMBEDDED
31179          default y
31180 +        depends on !GRKERNSEC_HIDESYM
31181          help
31182            Say Y here to let the kernel print out symbolic crash information and
31183            symbolic stack backtraces. This increases the size of the kernel
31184 @@ -780,8 +781,8 @@ config MARKERS
31185  source "arch/Kconfig"
31186  
31187  config PROC_PAGE_MONITOR
31188 -       default y
31189 -       depends on PROC_FS && MMU
31190 +       default n
31191 +       depends on PROC_FS && MMU && !GRKERNSEC
31192         bool "Enable /proc page monitoring" if EMBEDDED
31193         help
31194           Various /proc files exist to monitor process memory utilization:
31195 @@ -797,9 +798,9 @@ config HAVE_GENERIC_DMA_COHERENT
31196  
31197  config SLABINFO
31198         bool
31199 -       depends on PROC_FS
31200 +       depends on PROC_FS && !GRKERNSEC_PROC_ADD
31201         depends on SLAB || SLUB_DEBUG
31202 -       default y
31203 +       default n
31204  
31205  config RT_MUTEXES
31206         boolean
31207 diff -urNp linux-2.6.27.10/init/main.c linux-2.6.27.10/init/main.c
31208 --- linux-2.6.27.10/init/main.c 2008-11-07 12:55:34.000000000 -0500
31209 +++ linux-2.6.27.10/init/main.c 2008-11-18 03:38:45.000000000 -0500
31210 @@ -101,6 +101,7 @@ static inline void mark_rodata_ro(void) 
31211  #ifdef CONFIG_TC
31212  extern void tc_init(void);
31213  #endif
31214 +extern void grsecurity_init(void);
31215  
31216  enum system_states system_state;
31217  EXPORT_SYMBOL(system_state);
31218 @@ -187,6 +188,40 @@ static int __init set_reset_devices(char
31219  
31220  __setup("reset_devices", set_reset_devices);
31221  
31222 +#if defined(CONFIG_PAX_MEMORY_UDEREF) && defined(CONFIG_X86_32)
31223 +static int __init setup_pax_nouderef(char *str)
31224 +{
31225 +       unsigned int cpu;
31226 +
31227 +#ifdef CONFIG_PAX_KERNEXEC
31228 +       unsigned long cr0;
31229 +
31230 +       pax_open_kernel(cr0);
31231 +#endif
31232 +
31233 +       for (cpu = 0; cpu < NR_CPUS; cpu++)
31234 +               get_cpu_gdt_table(cpu)[GDT_ENTRY_KERNEL_DS].b = 0x00cf9300;
31235 +
31236 +#ifdef CONFIG_PAX_KERNEXEC
31237 +       pax_close_kernel(cr0);
31238 +#endif
31239 +
31240 +       return 1;
31241 +}
31242 +__setup("pax_nouderef", setup_pax_nouderef);
31243 +#endif
31244 +
31245 +#ifdef CONFIG_PAX_SOFTMODE
31246 +unsigned int pax_softmode;
31247 +
31248 +static int __init setup_pax_softmode(char *str)
31249 +{
31250 +       get_option(&str, &pax_softmode);
31251 +       return 1;
31252 +}
31253 +__setup("pax_softmode=", setup_pax_softmode);
31254 +#endif
31255 +
31256  static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
31257  char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
31258  static const char *panic_later, *panic_param;
31259 @@ -385,7 +420,7 @@ static void __init setup_nr_cpu_ids(void
31260  }
31261  
31262  #ifndef CONFIG_HAVE_SETUP_PER_CPU_AREA
31263 -unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
31264 +unsigned long __per_cpu_offset[NR_CPUS] __read_only;
31265  
31266  EXPORT_SYMBOL(__per_cpu_offset);
31267  
31268 @@ -704,6 +739,7 @@ int do_one_initcall(initcall_t fn)
31269  {
31270         int count = preempt_count();
31271         ktime_t t0, t1, delta;
31272 +       const char *msg1 = "", *msg2 = "";
31273         char msgbuf[64];
31274         int result;
31275  
31276 @@ -729,15 +765,15 @@ int do_one_initcall(initcall_t fn)
31277                 sprintf(msgbuf, "error code %d ", result);
31278  
31279         if (preempt_count() != count) {
31280 -               strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
31281 +               msg1 = " preemption imbalance";
31282                 preempt_count() = count;
31283         }
31284         if (irqs_disabled()) {
31285 -               strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
31286 +               msg2 = " disabled interrupts";
31287                 local_irq_enable();
31288         }
31289 -       if (msgbuf[0]) {
31290 -               printk("initcall %pF returned with %s\n", fn, msgbuf);
31291 +       if (msgbuf[0] || *msg1 || *msg2) {
31292 +               printk("initcall %pF returned with %s%s%s\n", fn, msgbuf, msg1, msg2);
31293         }
31294  
31295         return result;
31296 @@ -876,6 +912,8 @@ static int __init kernel_init(void * unu
31297                 prepare_namespace();
31298         }
31299  
31300 +       grsecurity_init();
31301 +
31302         /*
31303          * Ok, we have completed the initial bootup, and
31304          * we're essentially up and running. Get rid of the
31305 diff -urNp linux-2.6.27.10/init/noinitramfs.c linux-2.6.27.10/init/noinitramfs.c
31306 --- linux-2.6.27.10/init/noinitramfs.c  2008-11-07 12:55:34.000000000 -0500
31307 +++ linux-2.6.27.10/init/noinitramfs.c  2008-11-18 03:38:45.000000000 -0500
31308 @@ -29,7 +29,7 @@ static int __init default_rootfs(void)
31309  {
31310         int err;
31311  
31312 -       err = sys_mkdir("/dev", 0755);
31313 +       err = sys_mkdir((const char __user *)"/dev", 0755);
31314         if (err < 0)
31315                 goto out;
31316  
31317 @@ -39,7 +39,7 @@ static int __init default_rootfs(void)
31318         if (err < 0)
31319                 goto out;
31320  
31321 -       err = sys_mkdir("/root", 0700);
31322 +       err = sys_mkdir((const char __user *)"/root", 0700);
31323         if (err < 0)
31324                 goto out;
31325  
31326 diff -urNp linux-2.6.27.10/ipc/ipc_sysctl.c linux-2.6.27.10/ipc/ipc_sysctl.c
31327 --- linux-2.6.27.10/ipc/ipc_sysctl.c    2008-11-07 12:55:34.000000000 -0500
31328 +++ linux-2.6.27.10/ipc/ipc_sysctl.c    2008-11-18 03:38:45.000000000 -0500
31329 @@ -268,7 +268,7 @@ static struct ctl_table ipc_kern_table[]
31330                 .extra1         = &zero,
31331                 .extra2         = &one,
31332         },
31333 -       {}
31334 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31335  };
31336  
31337  static struct ctl_table ipc_root_table[] = {
31338 @@ -278,7 +278,7 @@ static struct ctl_table ipc_root_table[]
31339                 .mode           = 0555,
31340                 .child          = ipc_kern_table,
31341         },
31342 -       {}
31343 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
31344  };
31345  
31346  static int __init ipc_sysctl_init(void)
31347 diff -urNp linux-2.6.27.10/ipc/msg.c linux-2.6.27.10/ipc/msg.c
31348 --- linux-2.6.27.10/ipc/msg.c   2008-11-07 12:55:34.000000000 -0500
31349 +++ linux-2.6.27.10/ipc/msg.c   2008-11-18 03:38:45.000000000 -0500
31350 @@ -38,6 +38,7 @@
31351  #include <linux/nsproxy.h>
31352  #include <linux/ipc_namespace.h>
31353  #include <linux/vs_base.h>
31354 +#include <linux/grsecurity.h>
31355  
31356  #include <asm/current.h>
31357  #include <asm/uaccess.h>
31358 @@ -314,6 +315,7 @@ asmlinkage long sys_msgget(key_t key, in
31359         struct ipc_namespace *ns;
31360         struct ipc_ops msg_ops;
31361         struct ipc_params msg_params;
31362 +       long err;
31363  
31364         ns = current->nsproxy->ipc_ns;
31365  
31366 @@ -324,7 +326,11 @@ asmlinkage long sys_msgget(key_t key, in
31367         msg_params.key = key;
31368         msg_params.flg = msgflg;
31369  
31370 -       return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31371 +       err = ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params);
31372 +
31373 +       gr_log_msgget(err, msgflg);
31374 +
31375 +       return err;
31376  }
31377  
31378  static inline unsigned long
31379 @@ -434,6 +440,7 @@ static int msgctl_down(struct ipc_namesp
31380  
31381         switch (cmd) {
31382         case IPC_RMID:
31383 +               gr_log_msgrm(ipcp->uid, ipcp->cuid);
31384                 freeque(ns, ipcp);
31385                 goto out_up;
31386         case IPC_SET:
31387 diff -urNp linux-2.6.27.10/ipc/sem.c linux-2.6.27.10/ipc/sem.c
31388 --- linux-2.6.27.10/ipc/sem.c   2008-11-07 12:55:34.000000000 -0500
31389 +++ linux-2.6.27.10/ipc/sem.c   2008-11-18 03:38:45.000000000 -0500
31390 @@ -83,6 +83,7 @@
31391  #include <linux/ipc_namespace.h>
31392  #include <linux/vs_base.h>
31393  #include <linux/vs_limit.h>
31394 +#include <linux/grsecurity.h>
31395  
31396  #include <asm/uaccess.h>
31397  #include "util.h"
31398 @@ -313,6 +314,7 @@ asmlinkage long sys_semget(key_t key, in
31399         struct ipc_namespace *ns;
31400         struct ipc_ops sem_ops;
31401         struct ipc_params sem_params;
31402 +       long err;
31403  
31404         ns = current->nsproxy->ipc_ns;
31405  
31406 @@ -327,7 +329,11 @@ asmlinkage long sys_semget(key_t key, in
31407         sem_params.flg = semflg;
31408         sem_params.u.nsems = nsems;
31409  
31410 -       return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31411 +       err = ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
31412 +
31413 +       gr_log_semget(err, semflg);
31414 +
31415 +       return err;
31416  }
31417  
31418  /*
31419 @@ -870,6 +876,7 @@ static int semctl_down(struct ipc_namesp
31420  
31421         switch(cmd){
31422         case IPC_RMID:
31423 +               gr_log_semrm(ipcp->uid, ipcp->cuid);
31424                 freeary(ns, ipcp);
31425                 goto out_up;
31426         case IPC_SET:
31427 diff -urNp linux-2.6.27.10/ipc/shm.c linux-2.6.27.10/ipc/shm.c
31428 --- linux-2.6.27.10/ipc/shm.c   2008-11-07 12:55:34.000000000 -0500
31429 +++ linux-2.6.27.10/ipc/shm.c   2008-11-18 03:38:45.000000000 -0500
31430 @@ -39,6 +39,7 @@
31431  #include <linux/ipc_namespace.h>
31432  #include <linux/vs_context.h>
31433  #include <linux/vs_limit.h>
31434 +#include <linux/grsecurity.h>
31435  
31436  #include <asm/uaccess.h>
31437  
31438 @@ -69,6 +70,14 @@ static void shm_destroy (struct ipc_name
31439  static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
31440  #endif
31441  
31442 +#ifdef CONFIG_GRKERNSEC
31443 +extern int gr_handle_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31444 +                          const time_t shm_createtime, const uid_t cuid,
31445 +                          const int shmid);
31446 +extern int gr_chroot_shmat(const pid_t shm_cprid, const pid_t shm_lapid,
31447 +                          const time_t shm_createtime);
31448 +#endif
31449 +
31450  void shm_init_ns(struct ipc_namespace *ns)
31451  {
31452         ns->shm_ctlmax = SHMMAX;
31453 @@ -87,6 +96,8 @@ static void do_shm_rmid(struct ipc_names
31454         struct shmid_kernel *shp;
31455         shp = container_of(ipcp, struct shmid_kernel, shm_perm);
31456  
31457 +       gr_log_shmrm(shp->shm_perm.uid, shp->shm_perm.cuid);
31458 +
31459         if (shp->shm_nattch){
31460                 shp->shm_perm.mode |= SHM_DEST;
31461                 /* Do not find it any more */
31462 @@ -392,6 +403,14 @@ static int newseg(struct ipc_namespace *
31463         shp->shm_lprid = 0;
31464         shp->shm_atim = shp->shm_dtim = 0;
31465         shp->shm_ctim = get_seconds();
31466 +#ifdef CONFIG_GRKERNSEC
31467 +       {
31468 +               struct timespec timeval;
31469 +               do_posix_clock_monotonic_gettime(&timeval);
31470 +
31471 +               shp->shm_createtime = timeval.tv_sec;
31472 +       }
31473 +#endif
31474         shp->shm_segsz = size;
31475         shp->shm_nattch = 0;
31476         shp->shm_file = file;
31477 @@ -445,6 +464,7 @@ asmlinkage long sys_shmget (key_t key, s
31478         struct ipc_namespace *ns;
31479         struct ipc_ops shm_ops;
31480         struct ipc_params shm_params;
31481 +       long err;
31482  
31483         ns = current->nsproxy->ipc_ns;
31484  
31485 @@ -456,7 +476,11 @@ asmlinkage long sys_shmget (key_t key, s
31486         shm_params.flg = shmflg;
31487         shm_params.u.size = size;
31488  
31489 -       return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31490 +       err = ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params);
31491 +
31492 +       gr_log_shmget(err, shmflg, size);
31493 +
31494 +       return err;
31495  }
31496  
31497  static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version)
31498 @@ -869,9 +893,21 @@ long do_shmat(int shmid, char __user *sh
31499         if (err)
31500                 goto out_unlock;
31501  
31502 +#ifdef CONFIG_GRKERNSEC
31503 +       if (!gr_handle_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime,
31504 +                            shp->shm_perm.cuid, shmid) ||
31505 +           !gr_chroot_shmat(shp->shm_cprid, shp->shm_lapid, shp->shm_createtime)) {
31506 +               err = -EACCES;
31507 +               goto out_unlock;
31508 +       }
31509 +#endif
31510 +
31511         path.dentry = dget(shp->shm_file->f_path.dentry);
31512         path.mnt    = shp->shm_file->f_path.mnt;
31513         shp->shm_nattch++;
31514 +#ifdef CONFIG_GRKERNSEC
31515 +       shp->shm_lapid = current->pid;
31516 +#endif
31517         size = i_size_read(path.dentry->d_inode);
31518         shm_unlock(shp);
31519  
31520 diff -urNp linux-2.6.27.10/kernel/acct.c linux-2.6.27.10/kernel/acct.c
31521 --- linux-2.6.27.10/kernel/acct.c       2008-11-07 12:55:34.000000000 -0500
31522 +++ linux-2.6.27.10/kernel/acct.c       2008-11-18 03:38:45.000000000 -0500
31523 @@ -573,7 +573,7 @@ static void do_acct_process(struct bsd_a
31524          */
31525         flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
31526         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
31527 -       file->f_op->write(file, (char *)&ac,
31528 +       file->f_op->write(file, (char __user *)&ac,
31529                                sizeof(acct_t), &file->f_pos);
31530         current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim;
31531         set_fs(fs);
31532 diff -urNp linux-2.6.27.10/kernel/capability.c linux-2.6.27.10/kernel/capability.c
31533 --- linux-2.6.27.10/kernel/capability.c 2008-11-07 12:55:34.000000000 -0500
31534 +++ linux-2.6.27.10/kernel/capability.c 2008-11-18 03:38:45.000000000 -0500
31535 @@ -13,6 +13,7 @@
31536  #include <linux/syscalls.h>
31537  #include <linux/pid_namespace.h>
31538  #include <linux/vs_context.h>
31539 +#include <linux/grsecurity.h>
31540  #include <asm/uaccess.h>
31541  
31542  /*
31543 @@ -498,10 +499,21 @@ asmlinkage long sys_capset(cap_user_head
31544         /* here for now so we don't require task locking */
31545         if (vs_check_bit(VXC_CAP_MASK, cap) && !vx_mcaps(1L << cap))
31546                 return 0;
31547 -       if (has_capability(current, cap)) {
31548 +       if (has_capability(current, cap) && gr_task_is_capable(current, cap)) {
31549                 current->flags |= PF_SUPERPRIV;
31550                 return 1;
31551         }
31552         return 0;
31553  }
31554 +
31555 +int capable_nolog(int cap)
31556 +{
31557 +       if (has_capability(current, cap) && gr_is_capable_nolog(cap)) {
31558 +               current->flags |= PF_SUPERPRIV;
31559 +               return 1;
31560 +       }
31561 +       return 0;
31562 +}
31563 +
31564  EXPORT_SYMBOL(capable);
31565 +EXPORT_SYMBOL(capable_nolog);
31566 diff -urNp linux-2.6.27.10/kernel/configs.c linux-2.6.27.10/kernel/configs.c
31567 --- linux-2.6.27.10/kernel/configs.c    2008-11-07 12:55:34.000000000 -0500
31568 +++ linux-2.6.27.10/kernel/configs.c    2008-11-18 03:38:45.000000000 -0500
31569 @@ -79,8 +79,19 @@ static int __init ikconfig_init(void)
31570         struct proc_dir_entry *entry;
31571  
31572         /* create the current config file */
31573 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31574 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31575 +       entry = proc_create("config.gz", S_IFREG | S_IRUSR, NULL,
31576 +                           &ikconfig_file_ops);
31577 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31578 +       entry = proc_create("config.gz", S_IFREG | S_IRUSR | S_IRGRP, NULL,
31579 +                           &ikconfig_file_ops);
31580 +#endif
31581 +#else
31582         entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
31583                             &ikconfig_file_ops);
31584 +#endif
31585 +
31586         if (!entry)
31587                 return -ENOMEM;
31588  
31589 diff -urNp linux-2.6.27.10/kernel/cpu.c linux-2.6.27.10/kernel/cpu.c
31590 --- linux-2.6.27.10/kernel/cpu.c        2008-11-07 12:55:34.000000000 -0500
31591 +++ linux-2.6.27.10/kernel/cpu.c        2008-11-18 03:38:45.000000000 -0500
31592 @@ -40,7 +40,7 @@ EXPORT_SYMBOL(cpu_possible_map);
31593  /* Serializes the updates to cpu_online_map, cpu_present_map */
31594  static DEFINE_MUTEX(cpu_add_remove_lock);
31595  
31596 -static __cpuinitdata RAW_NOTIFIER_HEAD(cpu_chain);
31597 +static RAW_NOTIFIER_HEAD(cpu_chain);
31598  
31599  /* If set, cpu_up and cpu_down will return -EBUSY and do nothing.
31600   * Should always be manipulated under cpu_add_remove_lock
31601 diff -urNp linux-2.6.27.10/kernel/exit.c linux-2.6.27.10/kernel/exit.c
31602 --- linux-2.6.27.10/kernel/exit.c       2008-11-07 12:55:34.000000000 -0500
31603 +++ linux-2.6.27.10/kernel/exit.c       2008-11-29 19:01:27.000000000 -0500
31604 @@ -40,7 +40,6 @@
31605  #include <linux/cn_proc.h>
31606  #include <linux/mutex.h>
31607  #include <linux/futex.h>
31608 -#include <linux/compat.h>
31609  #include <linux/pipe_fs_i.h>
31610  #include <linux/audit.h> /* for audit_free() */
31611  #include <linux/resource.h>
31612 @@ -52,6 +51,11 @@
31613  #include <linux/vs_network.h> 
31614  #include <linux/vs_pid.h> 
31615  #include <linux/vserver/global.h>
31616 +#include <linux/grsecurity.h>
31617 +
31618 +#ifdef CONFIG_GRKERNSEC
31619 +extern rwlock_t grsec_exec_file_lock;
31620 +#endif
31621  
31622  #include <asm/uaccess.h>
31623  #include <asm/unistd.h>
31624 @@ -133,7 +137,6 @@ static void __exit_signal(struct task_st
31625          * doing sigqueue_free() if we have SIGQUEUE_PREALLOC signals.
31626          */
31627         flush_sigqueue(&tsk->pending);
31628 -
31629         tsk->signal = NULL;
31630         tsk->sighand = NULL;
31631         spin_unlock(&sighand->siglock);
31632 @@ -158,6 +161,8 @@ void release_task(struct task_struct * p
31633         struct task_struct *leader;
31634         int zap_leader;
31635  repeat:
31636 +       gr_del_task_from_ip_table(p);
31637 +
31638         tracehook_prepare_release_task(p);
31639         atomic_dec(&p->user->processes);
31640         proc_flush_task(p);
31641 @@ -321,11 +326,22 @@ static void reparent_to_kthreadd(void)
31642  {
31643         write_lock_irq(&tasklist_lock);
31644  
31645 +#ifdef CONFIG_GRKERNSEC
31646 +       write_lock(&grsec_exec_file_lock);
31647 +       if (current->exec_file) {
31648 +               fput(current->exec_file);
31649 +               current->exec_file = NULL;
31650 +       }
31651 +       write_unlock(&grsec_exec_file_lock);
31652 +#endif
31653 +
31654         ptrace_unlink(current);
31655         /* Reparent to init */
31656         current->real_parent = current->parent = kthreadd_task;
31657         list_move_tail(&current->sibling, &current->real_parent->children);
31658  
31659 +       gr_set_kernel_label(current);
31660 +
31661         /* Set the exit signal to SIGCHLD so we signal init on exit */
31662         current->exit_signal = SIGCHLD;
31663  
31664 @@ -419,6 +435,17 @@ void daemonize(const char *name, ...)
31665         vsnprintf(current->comm, sizeof(current->comm), name, args);
31666         va_end(args);
31667  
31668 +#ifdef CONFIG_GRKERNSEC
31669 +       write_lock(&grsec_exec_file_lock);
31670 +       if (current->exec_file) {
31671 +               fput(current->exec_file);
31672 +               current->exec_file = NULL;
31673 +       }
31674 +       write_unlock(&grsec_exec_file_lock);
31675 +#endif
31676 +
31677 +       gr_set_kernel_label(current);
31678 +
31679         /*
31680          * If we were started as result of loading a module, close all of the
31681          * user space pages.  We don't need them, and if we didn't close them
31682 @@ -1054,14 +1081,6 @@ NORET_TYPE void do_exit(long code)
31683                 exit_itimers(tsk->signal);
31684         }
31685         acct_collect(code, group_dead);
31686 -#ifdef CONFIG_FUTEX
31687 -       if (unlikely(tsk->robust_list))
31688 -               exit_robust_list(tsk);
31689 -#ifdef CONFIG_COMPAT
31690 -       if (unlikely(tsk->compat_robust_list))
31691 -               compat_exit_robust_list(tsk);
31692 -#endif
31693 -#endif
31694         if (group_dead)
31695                 tty_audit_exit();
31696         if (unlikely(tsk->audit_context))
31697 @@ -1070,6 +1089,9 @@ NORET_TYPE void do_exit(long code)
31698         tsk->exit_code = code;
31699         taskstats_exit(tsk, group_dead);
31700  
31701 +       gr_acl_handle_psacct(tsk, code);
31702 +       gr_acl_handle_exit();
31703 +
31704         exit_mm(tsk);
31705  
31706         if (group_dead)
31707 @@ -1272,7 +1294,7 @@ static int wait_task_zombie(struct task_
31708         if (unlikely(options & WNOWAIT)) {
31709                 uid_t uid = p->uid;
31710                 int exit_code = p->exit_code;
31711 -               int why, status;
31712 +               int why;
31713  
31714                 get_task_struct(p);
31715                 read_unlock(&tasklist_lock);
31716 diff -urNp linux-2.6.27.10/kernel/fork.c linux-2.6.27.10/kernel/fork.c
31717 --- linux-2.6.27.10/kernel/fork.c       2008-12-21 01:16:52.000000000 -0500
31718 +++ linux-2.6.27.10/kernel/fork.c       2008-12-21 01:13:46.000000000 -0500
31719 @@ -40,6 +40,7 @@
31720  #include <linux/jiffies.h>
31721  #include <linux/tracehook.h>
31722  #include <linux/futex.h>
31723 +#include <linux/compat.h>
31724  #include <linux/task_io_accounting_ops.h>
31725  #include <linux/rcupdate.h>
31726  #include <linux/ptrace.h>
31727 @@ -58,6 +59,7 @@
31728  #include <linux/vs_limit.h>
31729  #include <linux/vs_memory.h>
31730  #include <linux/vserver/global.h>
31731 +#include <linux/grsecurity.h>
31732  
31733  #include <asm/pgtable.h>
31734  #include <asm/pgalloc.h>
31735 @@ -234,7 +236,7 @@ static struct task_struct *dup_task_stru
31736         setup_thread_stack(tsk, orig);
31737  
31738  #ifdef CONFIG_CC_STACKPROTECTOR
31739 -       tsk->stack_canary = get_random_int();
31740 +       tsk->stack_canary = pax_get_random_long();
31741  #endif
31742  
31743         /* One for us, one for whoever does the "release_task()" (usually parent) */
31744 @@ -271,8 +273,8 @@ static int dup_mmap(struct mm_struct *mm
31745         mm->locked_vm = 0;
31746         mm->mmap = NULL;
31747         mm->mmap_cache = NULL;
31748 -       mm->free_area_cache = oldmm->mmap_base;
31749 -       mm->cached_hole_size = ~0UL;
31750 +       mm->free_area_cache = oldmm->free_area_cache;
31751 +       mm->cached_hole_size = oldmm->cached_hole_size;
31752         mm->map_count = 0;
31753         cpus_clear(mm->cpu_vm_mask);
31754         mm->mm_rb = RB_ROOT;
31755 @@ -309,6 +311,7 @@ static int dup_mmap(struct mm_struct *mm
31756                 tmp->vm_flags &= ~VM_LOCKED;
31757                 tmp->vm_mm = mm;
31758                 tmp->vm_next = NULL;
31759 +               tmp->vm_mirror = NULL;
31760                 anon_vma_link(tmp);
31761                 file = tmp->vm_file;
31762                 if (file) {
31763 @@ -356,6 +359,31 @@ static int dup_mmap(struct mm_struct *mm
31764                 if (retval)
31765                         goto out;
31766         }
31767 +
31768 +#ifdef CONFIG_PAX_SEGMEXEC
31769 +       if (oldmm->pax_flags & MF_PAX_SEGMEXEC) {
31770 +               struct vm_area_struct *mpnt_m;
31771 +
31772 +               for (mpnt = oldmm->mmap, mpnt_m = mm->mmap; mpnt; mpnt = mpnt->vm_next, mpnt_m = mpnt_m->vm_next) {
31773 +                       BUG_ON(!mpnt_m || mpnt_m->vm_mirror || mpnt->vm_mm != oldmm || mpnt_m->vm_mm != mm);
31774 +
31775 +                       if (!mpnt->vm_mirror)
31776 +                               continue;
31777 +
31778 +                       if (mpnt->vm_end <= SEGMEXEC_TASK_SIZE) {
31779 +                               BUG_ON(mpnt->vm_mirror->vm_mirror != mpnt);
31780 +                               mpnt->vm_mirror = mpnt_m;
31781 +                       } else {
31782 +                               BUG_ON(mpnt->vm_mirror->vm_mirror == mpnt || mpnt->vm_mirror->vm_mirror->vm_mm != mm);
31783 +                               mpnt_m->vm_mirror = mpnt->vm_mirror->vm_mirror;
31784 +                               mpnt_m->vm_mirror->vm_mirror = mpnt_m;
31785 +                               mpnt->vm_mirror->vm_mirror = mpnt;
31786 +                       }
31787 +               }
31788 +               BUG_ON(mpnt_m);
31789 +       }
31790 +#endif
31791 +
31792         /* a new mm has just been created */
31793         arch_dup_mmap(oldmm, mm);
31794         retval = 0;
31795 @@ -521,6 +549,18 @@ void mm_release(struct task_struct *tsk,
31796  {
31797         struct completion *vfork_done = tsk->vfork_done;
31798  
31799 +       /* Get rid of any futexes when releasing the mm */
31800 +#ifdef CONFIG_FUTEX
31801 +       if (unlikely(tsk->robust_list))
31802 +               exit_robust_list(tsk);
31803 +       tsk->robust_list = NULL;
31804 +#ifdef CONFIG_COMPAT
31805 +       if (unlikely(tsk->compat_robust_list))
31806 +               compat_exit_robust_list(tsk);
31807 +       tsk->compat_robust_list = NULL;
31808 +#endif
31809 +#endif
31810 +
31811         /* Get rid of any cached register state */
31812         deactivate_mm(tsk, mm);
31813  
31814 @@ -539,7 +579,7 @@ void mm_release(struct task_struct *tsk,
31815         if (tsk->clear_child_tid
31816             && !(tsk->flags & PF_SIGNALED)
31817             && atomic_read(&mm->mm_users) > 1) {
31818 -               u32 __user * tidptr = tsk->clear_child_tid;
31819 +               pid_t __user * tidptr = tsk->clear_child_tid;
31820                 tsk->clear_child_tid = NULL;
31821  
31822                 /*
31823 @@ -547,7 +587,7 @@ void mm_release(struct task_struct *tsk,
31824                  * not set up a proper pointer then tough luck.
31825                  */
31826                 put_user(0, tidptr);
31827 -               sys_futex(tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31828 +               sys_futex((u32 __user *)tidptr, FUTEX_WAKE, 1, NULL, NULL, 0);
31829         }
31830  }
31831  
31832 @@ -942,6 +982,9 @@ static struct task_struct *copy_process(
31833         DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
31834  #endif
31835         retval = -EAGAIN;
31836 +
31837 +       gr_learn_resource(p, RLIMIT_NPROC, atomic_read(&p->user->processes), 0);
31838 +
31839         if (!vx_nproc_avail(1))
31840                 goto bad_fork_cleanup_vm;
31841         if (atomic_read(&p->user->processes) >=
31842 @@ -1108,6 +1151,8 @@ static struct task_struct *copy_process(
31843                         goto bad_fork_free_pid;
31844         }
31845  
31846 +       gr_copy_label(p);
31847 +
31848         p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL;
31849         /*
31850          * Clear TID on mm_release()?
31851 @@ -1293,6 +1338,8 @@ bad_fork_cleanup_count:
31852  bad_fork_free:
31853         free_task(p);
31854  fork_out:
31855 +       gr_log_forkfail(retval);
31856 +
31857         return ERR_PTR(retval);
31858  }
31859  
31860 @@ -1369,6 +1416,8 @@ long do_fork(unsigned long clone_flags,
31861                 if (clone_flags & CLONE_PARENT_SETTID)
31862                         put_user(nr, parent_tidptr);
31863  
31864 +               gr_handle_brute_check();
31865 +
31866                 if (clone_flags & CLONE_VFORK) {
31867                         p->vfork_done = &vfork;
31868                         init_completion(&vfork);
31869 diff -urNp linux-2.6.27.10/kernel/futex.c linux-2.6.27.10/kernel/futex.c
31870 --- linux-2.6.27.10/kernel/futex.c      2008-11-07 12:55:34.000000000 -0500
31871 +++ linux-2.6.27.10/kernel/futex.c      2008-11-18 03:38:45.000000000 -0500
31872 @@ -188,6 +188,11 @@ static int get_futex_key(u32 __user *uad
31873         struct page *page;
31874         int err;
31875  
31876 +#ifdef CONFIG_PAX_SEGMEXEC
31877 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && address >= SEGMEXEC_TASK_SIZE)
31878 +               return -EFAULT;
31879 +#endif
31880 +
31881         /*
31882          * The futex address must be "naturally" aligned.
31883          */
31884 @@ -214,8 +219,8 @@ static int get_futex_key(u32 __user *uad
31885          * The futex is hashed differently depending on whether
31886          * it's in a shared or private mapping.  So check vma first.
31887          */
31888 -       vma = find_extend_vma(mm, address);
31889 -       if (unlikely(!vma))
31890 +       vma = find_vma(mm, address);
31891 +       if (unlikely(!vma || address < vma->vm_start))
31892                 return -EFAULT;
31893  
31894         /*
31895 @@ -1345,7 +1350,7 @@ static int futex_wait(u32 __user *uaddr,
31896                 struct restart_block *restart;
31897                 restart = &current_thread_info()->restart_block;
31898                 restart->fn = futex_wait_restart;
31899 -               restart->futex.uaddr = (u32 *)uaddr;
31900 +               restart->futex.uaddr = uaddr;
31901                 restart->futex.val = val;
31902                 restart->futex.time = abs_time->tv64;
31903                 restart->futex.bitset = bitset;
31904 @@ -1906,7 +1911,7 @@ retry:
31905   */
31906  static inline int fetch_robust_entry(struct robust_list __user **entry,
31907                                      struct robust_list __user * __user *head,
31908 -                                    int *pi)
31909 +                                    unsigned int *pi)
31910  {
31911         unsigned long uentry;
31912  
31913 diff -urNp linux-2.6.27.10/kernel/irq/handle.c linux-2.6.27.10/kernel/irq/handle.c
31914 --- linux-2.6.27.10/kernel/irq/handle.c 2008-11-07 12:55:34.000000000 -0500
31915 +++ linux-2.6.27.10/kernel/irq/handle.c 2008-11-18 03:38:45.000000000 -0500
31916 @@ -55,7 +55,8 @@ struct irq_desc irq_desc[NR_IRQS] __cach
31917                 .depth = 1,
31918                 .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
31919  #ifdef CONFIG_SMP
31920 -               .affinity = CPU_MASK_ALL
31921 +               .affinity = CPU_MASK_ALL,
31922 +               .cpu = 0,
31923  #endif
31924         }
31925  };
31926 diff -urNp linux-2.6.27.10/kernel/kallsyms.c linux-2.6.27.10/kernel/kallsyms.c
31927 --- linux-2.6.27.10/kernel/kallsyms.c   2008-11-07 12:55:34.000000000 -0500
31928 +++ linux-2.6.27.10/kernel/kallsyms.c   2008-11-18 03:38:45.000000000 -0500
31929 @@ -62,6 +62,19 @@ static inline int is_kernel_text(unsigne
31930  
31931  static inline int is_kernel(unsigned long addr)
31932  {
31933 +
31934 +#ifdef CONFIG_PAX_KERNEXEC
31935 +
31936 +#ifdef CONFIG_MODULES
31937 +       if ((unsigned long)MODULES_VADDR <= ktla_ktva(addr) &&
31938 +           ktla_ktva(addr) < (unsigned long)MODULES_END)
31939 +               return 0;
31940 +#endif
31941 +
31942 +       if (is_kernel_inittext(addr))
31943 +               return 1;
31944 +#endif
31945 +
31946         if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end)
31947                 return 1;
31948         return in_gate_area_no_task(addr);
31949 @@ -366,7 +379,6 @@ static unsigned long get_ksymbol_core(st
31950  
31951  static void reset_iter(struct kallsym_iter *iter, loff_t new_pos)
31952  {
31953 -       iter->name[0] = '\0';
31954         iter->nameoff = get_symbol_offset(new_pos);
31955         iter->pos = new_pos;
31956  }
31957 @@ -450,7 +462,7 @@ static int kallsyms_open(struct inode *i
31958         struct kallsym_iter *iter;
31959         int ret;
31960  
31961 -       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
31962 +       iter = kzalloc(sizeof(*iter), GFP_KERNEL);
31963         if (!iter)
31964                 return -ENOMEM;
31965         reset_iter(iter, 0);
31966 @@ -472,7 +484,15 @@ static const struct file_operations kall
31967  
31968  static int __init kallsyms_init(void)
31969  {
31970 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
31971 +#ifdef CONFIG_GRKERNSEC_PROC_USER
31972 +       proc_create("kallsyms", S_IFREG | S_IRUSR, NULL, &kallsyms_operations);
31973 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
31974 +       proc_create("kallsyms", S_IFREG | S_IRUSR | S_IRGRP, NULL, &kallsyms_operations);
31975 +#endif
31976 +#else
31977         proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
31978 +#endif
31979         return 0;
31980  }
31981  __initcall(kallsyms_init);
31982 diff -urNp linux-2.6.27.10/kernel/kmod.c linux-2.6.27.10/kernel/kmod.c
31983 --- linux-2.6.27.10/kernel/kmod.c       2008-11-07 12:55:34.000000000 -0500
31984 +++ linux-2.6.27.10/kernel/kmod.c       2008-11-18 03:38:45.000000000 -0500
31985 @@ -108,7 +108,7 @@ int request_module(const char *fmt, ...)
31986                 return -ENOMEM;
31987         }
31988  
31989 -       ret = call_usermodehelper(modprobe_path, argv, envp, 1);
31990 +       ret = call_usermodehelper(modprobe_path, argv, envp, UMH_WAIT_PROC);
31991         atomic_dec(&kmod_concurrent);
31992         return ret;
31993  }
31994 diff -urNp linux-2.6.27.10/kernel/kprobes.c linux-2.6.27.10/kernel/kprobes.c
31995 --- linux-2.6.27.10/kernel/kprobes.c    2008-11-07 12:55:34.000000000 -0500
31996 +++ linux-2.6.27.10/kernel/kprobes.c    2008-11-18 03:38:45.000000000 -0500
31997 @@ -182,7 +182,7 @@ kprobe_opcode_t __kprobes *get_insn_slot
31998          * kernel image and loaded module images reside. This is required
31999          * so x86_64 can correctly handle the %rip-relative fixups.
32000          */
32001 -       kip->insns = module_alloc(PAGE_SIZE);
32002 +       kip->insns = module_alloc_exec(PAGE_SIZE);
32003         if (!kip->insns) {
32004                 kfree(kip);
32005                 return NULL;
32006 @@ -214,7 +214,7 @@ static int __kprobes collect_one_slot(st
32007                         hlist_add_head(&kip->hlist,
32008                                        &kprobe_insn_pages);
32009                 } else {
32010 -                       module_free(NULL, kip->insns);
32011 +                       module_free_exec(NULL, kip->insns);
32012                         kfree(kip);
32013                 }
32014                 return 1;
32015 diff -urNp linux-2.6.27.10/kernel/lockdep.c linux-2.6.27.10/kernel/lockdep.c
32016 --- linux-2.6.27.10/kernel/lockdep.c    2008-11-07 12:55:34.000000000 -0500
32017 +++ linux-2.6.27.10/kernel/lockdep.c    2008-11-18 03:38:45.000000000 -0500
32018 @@ -627,6 +627,10 @@ static int static_obj(void *obj)
32019         int i;
32020  #endif
32021  
32022 +#ifdef CONFIG_PAX_KERNEXEC
32023 +       start = (unsigned long )&_data;
32024 +#endif
32025 +
32026         /*
32027          * static variable?
32028          */
32029 @@ -638,9 +642,12 @@ static int static_obj(void *obj)
32030          * percpu var?
32031          */
32032         for_each_possible_cpu(i) {
32033 +#ifdef CONFIG_X86_32
32034 +               start = per_cpu_offset(i);
32035 +#else
32036                 start = (unsigned long) &__per_cpu_start + per_cpu_offset(i);
32037 -               end   = (unsigned long) &__per_cpu_start + PERCPU_ENOUGH_ROOM
32038 -                                       + per_cpu_offset(i);
32039 +#endif
32040 +               end   = start + PERCPU_ENOUGH_ROOM;
32041  
32042                 if ((addr >= start) && (addr < end))
32043                         return 1;
32044 diff -urNp linux-2.6.27.10/kernel/module.c linux-2.6.27.10/kernel/module.c
32045 --- linux-2.6.27.10/kernel/module.c     2008-11-07 12:55:34.000000000 -0500
32046 +++ linux-2.6.27.10/kernel/module.c     2008-12-21 01:17:47.000000000 -0500
32047 @@ -44,6 +44,11 @@
32048  #include <linux/unwind.h>
32049  #include <asm/uaccess.h>
32050  #include <asm/cacheflush.h>
32051 +
32052 +#ifdef CONFIG_PAX_KERNEXEC
32053 +#include <asm/desc.h>
32054 +#endif
32055 +
32056  #include <linux/license.h>
32057  #include <asm/sections.h>
32058  
32059 @@ -71,7 +76,10 @@ static DECLARE_WAIT_QUEUE_HEAD(module_wq
32060  static BLOCKING_NOTIFIER_HEAD(module_notify_list);
32061  
32062  /* Bounds of module allocation, for speeding __module_text_address */
32063 -static unsigned long module_addr_min = -1UL, module_addr_max = 0;
32064 +static unsigned long module_addr_min_rw = -1UL, module_addr_max_rw = 0;
32065 +static unsigned long module_addr_min_rx = -1UL, module_addr_max_rx = 0;
32066 +
32067 +extern int gr_check_modstop(void);
32068  
32069  int register_module_notifier(struct notifier_block * nb)
32070  {
32071 @@ -217,7 +225,7 @@ static bool each_symbol(bool (*fn)(const
32072                 return true;
32073  
32074         list_for_each_entry(mod, &modules, list) {
32075 -               struct symsearch arr[] = {
32076 +               struct symsearch modarr[] = {
32077                         { mod->syms, mod->syms + mod->num_syms, mod->crcs,
32078                           NOT_GPL_ONLY, false },
32079                         { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
32080 @@ -239,7 +247,7 @@ static bool each_symbol(bool (*fn)(const
32081  #endif
32082                 };
32083  
32084 -               if (each_symbol_in_section(arr, ARRAY_SIZE(arr), mod, fn, data))
32085 +               if (each_symbol_in_section(modarr, ARRAY_SIZE(modarr), mod, fn, data))
32086                         return true;
32087         }
32088         return false;
32089 @@ -375,6 +383,8 @@ static inline unsigned int block_size(in
32090         return val;
32091  }
32092  
32093 +EXPORT_SYMBOL(__per_cpu_start);
32094 +
32095  static void *percpu_modalloc(unsigned long size, unsigned long align,
32096                              const char *name)
32097  {
32098 @@ -382,7 +392,7 @@ static void *percpu_modalloc(unsigned lo
32099         unsigned int i;
32100         void *ptr;
32101  
32102 -       if (align > PAGE_SIZE) {
32103 +       if (align-1 >= PAGE_SIZE) {
32104                 printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n",
32105                        name, align, PAGE_SIZE);
32106                 align = PAGE_SIZE;
32107 @@ -464,7 +474,11 @@ static void percpu_modcopy(void *pcpudes
32108         int cpu;
32109  
32110         for_each_possible_cpu(cpu)
32111 +#ifdef CONFIG_X86_32
32112 +               memcpy(pcpudest + __per_cpu_offset[cpu], from, size);
32113 +#else
32114                 memcpy(pcpudest + per_cpu_offset(cpu), from, size);
32115 +#endif
32116  }
32117  
32118  static int percpu_modinit(void)
32119 @@ -722,6 +736,9 @@ sys_delete_module(const char __user *nam
32120         char name[MODULE_NAME_LEN];
32121         int ret, forced = 0;
32122  
32123 +       if (gr_check_modstop())
32124 +               return -EPERM;
32125 +
32126         if (!capable(CAP_SYS_MODULE))
32127                 return -EPERM;
32128  
32129 @@ -1430,16 +1447,19 @@ static void free_module(struct module *m
32130         module_unload_free(mod);
32131  
32132         /* This may be NULL, but that's OK */
32133 -       module_free(mod, mod->module_init);
32134 +       module_free(mod, mod->module_init_rw);
32135 +       module_free_exec(mod, mod->module_init_rx);
32136         kfree(mod->args);
32137         if (mod->percpu)
32138                 percpu_modfree(mod->percpu);
32139  
32140         /* Free lock-classes: */
32141 -       lockdep_free_key_range(mod->module_core, mod->core_size);
32142 +       lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx);
32143 +       lockdep_free_key_range(mod->module_core_rw, mod->core_size_rw);
32144  
32145         /* Finally, free the core (containing the module structure) */
32146 -       module_free(mod, mod->module_core);
32147 +       module_free_exec(mod, mod->module_core_rx);
32148 +       module_free(mod, mod->module_core_rw);
32149  }
32150  
32151  void *__symbol_get(const char *symbol)
32152 @@ -1505,10 +1525,14 @@ static int simplify_symbols(Elf_Shdr *se
32153                             struct module *mod)
32154  {
32155         Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
32156 -       unsigned long secbase;
32157 +       unsigned long secbase, symbol;
32158         unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32159         int ret = 0;
32160  
32161 +#ifdef CONFIG_PAX_KERNEXEC
32162 +       unsigned long cr0;
32163 +#endif
32164 +
32165         for (i = 1; i < n; i++) {
32166                 switch (sym[i].st_shndx) {
32167                 case SHN_COMMON:
32168 @@ -1527,10 +1551,19 @@ static int simplify_symbols(Elf_Shdr *se
32169                         break;
32170  
32171                 case SHN_UNDEF:
32172 -                       sym[i].st_value
32173 -                         = resolve_symbol(sechdrs, versindex,
32174 +                       symbol = resolve_symbol(sechdrs, versindex,
32175                                            strtab + sym[i].st_name, mod);
32176  
32177 +#ifdef CONFIG_PAX_KERNEXEC
32178 +                       pax_open_kernel(cr0);
32179 +#endif
32180 +
32181 +                       sym[i].st_value = symbol;
32182 +
32183 +#ifdef CONFIG_PAX_KERNEXEC
32184 +                       pax_close_kernel(cr0);
32185 +#endif
32186 +
32187                         /* Ok if resolved.  */
32188                         if (!IS_ERR_VALUE(sym[i].st_value))
32189                                 break;
32190 @@ -1545,11 +1578,27 @@ static int simplify_symbols(Elf_Shdr *se
32191  
32192                 default:
32193                         /* Divert to percpu allocation if a percpu var. */
32194 -                       if (sym[i].st_shndx == pcpuindex)
32195 +                       if (sym[i].st_shndx == pcpuindex) {
32196 +
32197 +#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
32198 +                               secbase = (unsigned long)mod->percpu - (unsigned long)__per_cpu_start;
32199 +#else
32200                                 secbase = (unsigned long)mod->percpu;
32201 -                       else
32202 +#endif
32203 +
32204 +                       } else
32205                                 secbase = sechdrs[sym[i].st_shndx].sh_addr;
32206 +
32207 +#ifdef CONFIG_PAX_KERNEXEC
32208 +                       pax_open_kernel(cr0);
32209 +#endif
32210 +
32211                         sym[i].st_value += secbase;
32212 +
32213 +#ifdef CONFIG_PAX_KERNEXEC
32214 +                       pax_close_kernel(cr0);
32215 +#endif
32216 +
32217                         break;
32218                 }
32219         }
32220 @@ -1601,11 +1650,12 @@ static void layout_sections(struct modul
32221                             || strncmp(secstrings + s->sh_name,
32222                                        ".init", 5) == 0)
32223                                 continue;
32224 -                       s->sh_entsize = get_offset(&mod->core_size, s);
32225 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32226 +                               s->sh_entsize = get_offset(&mod->core_size_rw, s);
32227 +                       else
32228 +                               s->sh_entsize = get_offset(&mod->core_size_rx, s);
32229                         DEBUGP("\t%s\n", secstrings + s->sh_name);
32230                 }
32231 -               if (m == 0)
32232 -                       mod->core_text_size = mod->core_size;
32233         }
32234  
32235         DEBUGP("Init section allocation order:\n");
32236 @@ -1619,12 +1669,13 @@ static void layout_sections(struct modul
32237                             || strncmp(secstrings + s->sh_name,
32238                                        ".init", 5) != 0)
32239                                 continue;
32240 -                       s->sh_entsize = (get_offset(&mod->init_size, s)
32241 -                                        | INIT_OFFSET_MASK);
32242 +                       if ((s->sh_flags & SHF_WRITE) || !(s->sh_flags & SHF_ALLOC))
32243 +                               s->sh_entsize = get_offset(&mod->init_size_rw, s);
32244 +                       else
32245 +                               s->sh_entsize = get_offset(&mod->init_size_rx, s);
32246 +                       s->sh_entsize |= INIT_OFFSET_MASK;
32247                         DEBUGP("\t%s\n", secstrings + s->sh_name);
32248                 }
32249 -               if (m == 0)
32250 -                       mod->init_text_size = mod->init_size;
32251         }
32252  }
32253  
32254 @@ -1764,14 +1815,31 @@ static void add_kallsyms(struct module *
32255  {
32256         unsigned int i;
32257  
32258 +#ifdef CONFIG_PAX_KERNEXEC
32259 +       unsigned long cr0;
32260 +#endif
32261 +
32262         mod->symtab = (void *)sechdrs[symindex].sh_addr;
32263         mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
32264         mod->strtab = (void *)sechdrs[strindex].sh_addr;
32265  
32266         /* Set types up while we still have access to sections. */
32267 -       for (i = 0; i < mod->num_symtab; i++)
32268 -               mod->symtab[i].st_info
32269 -                       = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32270 +
32271 +       for (i = 0; i < mod->num_symtab; i++) {
32272 +               char type = elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
32273 +
32274 +#ifdef CONFIG_PAX_KERNEXEC
32275 +               pax_open_kernel(cr0);
32276 +#endif
32277 +
32278 +               mod->symtab[i].st_info = type;
32279 +
32280 +#ifdef CONFIG_PAX_KERNEXEC
32281 +               pax_close_kernel(cr0);
32282 +#endif
32283 +
32284 +       }
32285 +
32286  }
32287  #else
32288  static inline void add_kallsyms(struct module *mod,
32289 @@ -1783,16 +1851,30 @@ static inline void add_kallsyms(struct m
32290  }
32291  #endif /* CONFIG_KALLSYMS */
32292  
32293 -static void *module_alloc_update_bounds(unsigned long size)
32294 +static void *module_alloc_update_bounds_rw(unsigned long size)
32295  {
32296         void *ret = module_alloc(size);
32297  
32298         if (ret) {
32299                 /* Update module bounds. */
32300 -               if ((unsigned long)ret < module_addr_min)
32301 -                       module_addr_min = (unsigned long)ret;
32302 -               if ((unsigned long)ret + size > module_addr_max)
32303 -                       module_addr_max = (unsigned long)ret + size;
32304 +               if ((unsigned long)ret < module_addr_min_rw)
32305 +                       module_addr_min_rw = (unsigned long)ret;
32306 +               if ((unsigned long)ret + size > module_addr_max_rw)
32307 +                       module_addr_max_rw = (unsigned long)ret + size;
32308 +       }
32309 +       return ret;
32310 +}
32311 +
32312 +static void *module_alloc_update_bounds_rx(unsigned long size)
32313 +{
32314 +       void *ret = module_alloc_exec(size);
32315 +
32316 +       if (ret) {
32317 +               /* Update module bounds. */
32318 +               if ((unsigned long)ret < module_addr_min_rx)
32319 +                       module_addr_min_rx = (unsigned long)ret;
32320 +               if ((unsigned long)ret + size > module_addr_max_rx)
32321 +                       module_addr_max_rx = (unsigned long)ret + size;
32322         }
32323         return ret;
32324  }
32325 @@ -1837,6 +1919,10 @@ static noinline struct module *load_modu
32326         struct exception_table_entry *extable;
32327         mm_segment_t old_fs;
32328  
32329 +#ifdef CONFIG_PAX_KERNEXEC
32330 +       unsigned long cr0;
32331 +#endif
32332 +
32333         DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
32334                umod, len, uargs);
32335         if (len < sizeof(*hdr))
32336 @@ -1998,22 +2084,57 @@ static noinline struct module *load_modu
32337         layout_sections(mod, hdr, sechdrs, secstrings);
32338  
32339         /* Do the allocs. */
32340 -       ptr = module_alloc_update_bounds(mod->core_size);
32341 +       ptr = module_alloc_update_bounds_rw(mod->core_size_rw);
32342         if (!ptr) {
32343                 err = -ENOMEM;
32344                 goto free_percpu;
32345         }
32346 -       memset(ptr, 0, mod->core_size);
32347 -       mod->module_core = ptr;
32348 +       memset(ptr, 0, mod->core_size_rw);
32349 +       mod->module_core_rw = ptr;
32350 +
32351 +       ptr = module_alloc_update_bounds_rw(mod->init_size_rw);
32352 +       if (!ptr && mod->init_size_rw) {
32353 +               err = -ENOMEM;
32354 +               goto free_core_rw;
32355 +       }
32356 +       memset(ptr, 0, mod->init_size_rw);
32357 +       mod->module_init_rw = ptr;
32358 +
32359 +       ptr = module_alloc_update_bounds_rx(mod->core_size_rx);
32360 +       if (!ptr) {
32361 +               err = -ENOMEM;
32362 +               goto free_init_rw;
32363 +       }
32364 +
32365 +#ifdef CONFIG_PAX_KERNEXEC
32366 +       pax_open_kernel(cr0);
32367 +#endif
32368 +
32369 +       memset(ptr, 0, mod->core_size_rx);
32370  
32371 -       ptr = module_alloc_update_bounds(mod->init_size);
32372 -       if (!ptr && mod->init_size) {
32373 +#ifdef CONFIG_PAX_KERNEXEC
32374 +       pax_close_kernel(cr0);
32375 +#endif
32376 +
32377 +       mod->module_core_rx = ptr;
32378 +
32379 +       ptr = module_alloc_update_bounds_rx(mod->init_size_rx);
32380 +       if (!ptr && mod->init_size_rx) {
32381                 err = -ENOMEM;
32382 -               goto free_core;
32383 +               goto free_core_rx;
32384         }
32385 -       memset(ptr, 0, mod->init_size);
32386 -       mod->module_init = ptr;
32387  
32388 +#ifdef CONFIG_PAX_KERNEXEC
32389 +       pax_open_kernel(cr0);
32390 +#endif
32391 +
32392 +       memset(ptr, 0, mod->init_size_rx);
32393 +
32394 +#ifdef CONFIG_PAX_KERNEXEC
32395 +       pax_close_kernel(cr0);
32396 +#endif
32397 +
32398 +       mod->module_init_rx = ptr;
32399         /* Transfer each section which specifies SHF_ALLOC */
32400         DEBUGP("final section addresses:\n");
32401         for (i = 0; i < hdr->e_shnum; i++) {
32402 @@ -2022,17 +2143,41 @@ static noinline struct module *load_modu
32403                 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
32404                         continue;
32405  
32406 -               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK)
32407 -                       dest = mod->module_init
32408 -                               + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32409 -               else
32410 -                       dest = mod->module_core + sechdrs[i].sh_entsize;
32411 +               if (sechdrs[i].sh_entsize & INIT_OFFSET_MASK) {
32412 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32413 +                               dest = mod->module_init_rw
32414 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32415 +                       else
32416 +                               dest = mod->module_init_rx
32417 +                                       + (sechdrs[i].sh_entsize & ~INIT_OFFSET_MASK);
32418 +               } else {
32419 +                       if ((sechdrs[i].sh_flags & SHF_WRITE) || !(sechdrs[i].sh_flags & SHF_ALLOC))
32420 +                               dest = mod->module_core_rw + sechdrs[i].sh_entsize;
32421 +                       else
32422 +                               dest = mod->module_core_rx + sechdrs[i].sh_entsize;
32423 +               }
32424  
32425 -               if (sechdrs[i].sh_type != SHT_NOBITS)
32426 -                       memcpy(dest, (void *)sechdrs[i].sh_addr,
32427 -                              sechdrs[i].sh_size);
32428 +               if (sechdrs[i].sh_type != SHT_NOBITS) {
32429 +
32430 +#ifdef CONFIG_PAX_KERNEXEC
32431 +                       if (!(sechdrs[i].sh_flags & SHF_WRITE) && (sechdrs[i].sh_flags & SHF_ALLOC)) {
32432 +                               pax_open_kernel(cr0);
32433 +                               memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32434 +                               pax_close_kernel(cr0);
32435 +                       } else
32436 +#endif
32437 +
32438 +                       memcpy(dest, (void *)sechdrs[i].sh_addr, sechdrs[i].sh_size);
32439 +               }
32440                 /* Update sh_addr to point to copy in image. */
32441 -               sechdrs[i].sh_addr = (unsigned long)dest;
32442 +
32443 +#ifdef CONFIG_PAX_KERNEXEC
32444 +               if (sechdrs[i].sh_flags & SHF_EXECINSTR)
32445 +                       sechdrs[i].sh_addr = ktva_ktla((unsigned long)dest);
32446 +               else
32447 +#endif
32448 +
32449 +                       sechdrs[i].sh_addr = (unsigned long)dest;
32450                 DEBUGP("\t0x%lx %s\n", sechdrs[i].sh_addr, secstrings + sechdrs[i].sh_name);
32451         }
32452         /* Module has been moved. */
32453 @@ -2120,8 +2265,8 @@ static noinline struct module *load_modu
32454  
32455         /* Now do relocations. */
32456         for (i = 1; i < hdr->e_shnum; i++) {
32457 -               const char *strtab = (char *)sechdrs[strindex].sh_addr;
32458                 unsigned int info = sechdrs[i].sh_info;
32459 +               strtab = (char *)sechdrs[strindex].sh_addr;
32460  
32461                 /* Not a valid relocation section? */
32462                 if (info >= hdr->e_shnum)
32463 @@ -2180,12 +2325,12 @@ static noinline struct module *load_modu
32464          * Do it before processing of module parameters, so the module
32465          * can provide parameter accessor functions of its own.
32466          */
32467 -       if (mod->module_init)
32468 -               flush_icache_range((unsigned long)mod->module_init,
32469 -                                  (unsigned long)mod->module_init
32470 -                                  + mod->init_size);
32471 -       flush_icache_range((unsigned long)mod->module_core,
32472 -                          (unsigned long)mod->module_core + mod->core_size);
32473 +       if (mod->module_init_rx)
32474 +               flush_icache_range((unsigned long)mod->module_init_rx,
32475 +                                  (unsigned long)mod->module_init_rx
32476 +                                  + mod->init_size_rx);
32477 +       flush_icache_range((unsigned long)mod->module_core_rx,
32478 +                          (unsigned long)mod->module_core_rx + mod->core_size_rx);
32479  
32480         set_fs(old_fs);
32481  
32482 @@ -2238,9 +2383,13 @@ static noinline struct module *load_modu
32483         kobject_put(&mod->mkobj.kobj);
32484   free_unload:
32485         module_unload_free(mod);
32486 -       module_free(mod, mod->module_init);
32487 - free_core:
32488 -       module_free(mod, mod->module_core);
32489 +       module_free_exec(mod, mod->module_init_rx);
32490 + free_core_rx:
32491 +       module_free_exec(mod, mod->module_core_rx);
32492 + free_init_rw:
32493 +       module_free(mod, mod->module_init_rw);
32494 + free_core_rw:
32495 +       module_free(mod, mod->module_core_rw);
32496   free_percpu:
32497         if (percpu)
32498                 percpu_modfree(percpu);
32499 @@ -2265,6 +2414,9 @@ sys_init_module(void __user *umod,
32500         struct module *mod;
32501         int ret = 0;
32502  
32503 +       if (gr_check_modstop())
32504 +               return -EPERM;
32505 +
32506         /* Must have permission */
32507         if (!capable(CAP_SYS_MODULE))
32508                 return -EPERM;
32509 @@ -2320,10 +2472,12 @@ sys_init_module(void __user *umod,
32510         /* Drop initial reference. */
32511         module_put(mod);
32512         unwind_remove_table(mod->unwind_info, 1);
32513 -       module_free(mod, mod->module_init);
32514 -       mod->module_init = NULL;
32515 -       mod->init_size = 0;
32516 -       mod->init_text_size = 0;
32517 +       module_free(mod, mod->module_init_rw);
32518 +       module_free_exec(mod, mod->module_init_rx);
32519 +       mod->module_init_rw = NULL;
32520 +       mod->module_init_rx = NULL;
32521 +       mod->init_size_rw = 0;
32522 +       mod->init_size_rx = 0;
32523         mutex_unlock(&module_mutex);
32524  
32525         return 0;
32526 @@ -2331,6 +2485,13 @@ sys_init_module(void __user *umod,
32527  
32528  static inline int within(unsigned long addr, void *start, unsigned long size)
32529  {
32530 +
32531 +#ifdef CONFIG_PAX_KERNEXEC
32532 +       if (ktla_ktva(addr) >= (unsigned long)start &&
32533 +           ktla_ktva(addr) < (unsigned long)start + size)
32534 +               return 1;
32535 +#endif
32536 +
32537         return ((void *)addr >= start && (void *)addr < start + size);
32538  }
32539  
32540 @@ -2354,10 +2515,14 @@ static const char *get_ksymbol(struct mo
32541         unsigned long nextval;
32542  
32543         /* At worse, next value is at end of module */
32544 -       if (within(addr, mod->module_init, mod->init_size))
32545 -               nextval = (unsigned long)mod->module_init+mod->init_text_size;
32546 +       if (within(addr, mod->module_init_rx, mod->init_size_rx))
32547 +               nextval = (unsigned long)mod->module_init_rx+mod->init_size_rx;
32548 +       else if (within(addr, mod->module_init_rw, mod->init_size_rw))
32549 +               nextval = (unsigned long)mod->module_init_rw+mod->init_size_rw;
32550 +       else if (within(addr, mod->module_core_rx, mod->core_size_rx))
32551 +               nextval = (unsigned long)mod->module_core_rx+mod->core_size_rx;
32552         else
32553 -               nextval = (unsigned long)mod->module_core+mod->core_text_size;
32554 +               nextval = (unsigned long)mod->module_core_rw+mod->core_size_rw;
32555  
32556         /* Scan for closest preceeding symbol, and next symbol. (ELF
32557            starts real symbols at 1). */
32558 @@ -2402,8 +2567,10 @@ const char *module_address_lookup(unsign
32559  
32560         preempt_disable();
32561         list_for_each_entry(mod, &modules, list) {
32562 -               if (within(addr, mod->module_init, mod->init_size)
32563 -                   || within(addr, mod->module_core, mod->core_size)) {
32564 +               if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32565 +                   within(addr, mod->module_init_rw, mod->init_size_rw) ||
32566 +                   within(addr, mod->module_core_rx, mod->core_size_rx) ||
32567 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
32568                         if (modname)
32569                                 *modname = mod->name;
32570                         ret = get_ksymbol(mod, addr, size, offset);
32571 @@ -2425,8 +2592,10 @@ int lookup_module_symbol_name(unsigned l
32572  
32573         preempt_disable();
32574         list_for_each_entry(mod, &modules, list) {
32575 -               if (within(addr, mod->module_init, mod->init_size) ||
32576 -                   within(addr, mod->module_core, mod->core_size)) {
32577 +               if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32578 +                   within(addr, mod->module_init_rw, mod->init_size_rw) ||
32579 +                   within(addr, mod->module_core_rx, mod->core_size_rx) ||
32580 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
32581                         const char *sym;
32582  
32583                         sym = get_ksymbol(mod, addr, NULL, NULL);
32584 @@ -2449,8 +2618,10 @@ int lookup_module_symbol_attrs(unsigned 
32585  
32586         preempt_disable();
32587         list_for_each_entry(mod, &modules, list) {
32588 -               if (within(addr, mod->module_init, mod->init_size) ||
32589 -                   within(addr, mod->module_core, mod->core_size)) {
32590 +               if (within(addr, mod->module_init_rx, mod->init_size_rx) ||
32591 +                   within(addr, mod->module_init_rw, mod->init_size_rw) ||
32592 +                   within(addr, mod->module_core_rx, mod->core_size_rx) ||
32593 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
32594                         const char *sym;
32595  
32596                         sym = get_ksymbol(mod, addr, size, offset);
32597 @@ -2581,7 +2752,7 @@ static int m_show(struct seq_file *m, vo
32598         char buf[8];
32599  
32600         seq_printf(m, "%s %u",
32601 -                  mod->name, mod->init_size + mod->core_size);
32602 +                  mod->name, mod->init_size_rx + mod->init_size_rw + mod->core_size_rx + mod->core_size_rw);
32603         print_unload_info(m, mod);
32604  
32605         /* Informative for users. */
32606 @@ -2590,7 +2761,7 @@ static int m_show(struct seq_file *m, vo
32607                    mod->state == MODULE_STATE_COMING ? "Loading":
32608                    "Live");
32609         /* Used by oprofile and other similar tools. */
32610 -       seq_printf(m, " 0x%p", mod->module_core);
32611 +       seq_printf(m, " 0x%p 0x%p", mod->module_core_rx, mod->module_core_rw);
32612  
32613         /* Taints info */
32614         if (mod->taints)
32615 @@ -2646,7 +2817,8 @@ int is_module_address(unsigned long addr
32616         preempt_disable();
32617  
32618         list_for_each_entry(mod, &modules, list) {
32619 -               if (within(addr, mod->module_core, mod->core_size)) {
32620 +               if (within(addr, mod->module_core_rx, mod->core_size_rx) ||
32621 +                   within(addr, mod->module_core_rw, mod->core_size_rw)) {
32622                         preempt_enable();
32623                         return 1;
32624                 }
32625 @@ -2663,12 +2835,16 @@ struct module *__module_text_address(uns
32626  {
32627         struct module *mod;
32628  
32629 -       if (addr < module_addr_min || addr > module_addr_max)
32630 +#ifdef CONFIG_X86_32
32631 +       addr = ktla_ktva(addr);
32632 +#endif
32633 +
32634 +       if (addr < module_addr_min_rx || addr > module_addr_max_rx)
32635                 return NULL;
32636  
32637         list_for_each_entry(mod, &modules, list)
32638 -               if (within(addr, mod->module_init, mod->init_text_size)
32639 -                   || within(addr, mod->module_core, mod->core_text_size))
32640 +               if (within(addr, mod->module_init_rx, mod->init_size_rx)
32641 +                   || within(addr, mod->module_core_rx, mod->core_size_rx))
32642                         return mod;
32643         return NULL;
32644  }
32645 diff -urNp linux-2.6.27.10/kernel/mutex.c linux-2.6.27.10/kernel/mutex.c
32646 --- linux-2.6.27.10/kernel/mutex.c      2008-11-07 12:55:34.000000000 -0500
32647 +++ linux-2.6.27.10/kernel/mutex.c      2008-11-18 03:38:45.000000000 -0500
32648 @@ -83,7 +83,7 @@ __mutex_lock_slowpath(atomic_t *lock_cou
32649   *
32650   * This function is similar to (but not equivalent to) down().
32651   */
32652 -void inline __sched mutex_lock(struct mutex *lock)
32653 +inline void __sched mutex_lock(struct mutex *lock)
32654  {
32655         might_sleep();
32656         /*
32657 diff -urNp linux-2.6.27.10/kernel/panic.c linux-2.6.27.10/kernel/panic.c
32658 --- linux-2.6.27.10/kernel/panic.c      2008-11-07 12:55:34.000000000 -0500
32659 +++ linux-2.6.27.10/kernel/panic.c      2008-11-18 03:38:45.000000000 -0500
32660 @@ -349,6 +349,8 @@ EXPORT_SYMBOL(warn_slowpath);
32661   */
32662  void __stack_chk_fail(void)
32663  {
32664 +       print_symbol("stack corrupted in: %s\n", (unsigned long)__builtin_return_address(0));
32665 +       dump_stack();
32666         panic("stack-protector: Kernel stack is corrupted");
32667  }
32668  EXPORT_SYMBOL(__stack_chk_fail);
32669 diff -urNp linux-2.6.27.10/kernel/pid.c linux-2.6.27.10/kernel/pid.c
32670 --- linux-2.6.27.10/kernel/pid.c        2008-11-07 12:55:34.000000000 -0500
32671 +++ linux-2.6.27.10/kernel/pid.c        2008-11-18 03:38:45.000000000 -0500
32672 @@ -36,6 +36,7 @@
32673  #include <linux/syscalls.h>
32674  #include <linux/vs_pid.h>
32675  #include <linux/vserver/global.h>
32676 +#include <linux/grsecurity.h>
32677  
32678  #define pid_hashfn(nr, ns)     \
32679         hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift)
32680 @@ -45,7 +46,7 @@ struct pid init_struct_pid = INIT_STRUCT
32681  
32682  int pid_max = PID_MAX_DEFAULT;
32683  
32684 -#define RESERVED_PIDS          300
32685 +#define RESERVED_PIDS          500
32686  
32687  int pid_max_min = RESERVED_PIDS + 1;
32688  int pid_max_max = PID_MAX_LIMIT;
32689 @@ -381,7 +382,14 @@ EXPORT_SYMBOL(pid_task);
32690  struct task_struct *find_task_by_pid_type_ns(int type, int nr,
32691                 struct pid_namespace *ns)
32692  {
32693 -       return pid_task(find_pid_ns(nr, ns), type);
32694 +       struct task_struct *task;
32695 +
32696 +       task = pid_task(find_pid_ns(nr, ns), type);
32697 +
32698 +       if (gr_pid_is_chrooted(task))
32699 +               return NULL;
32700 +
32701 +       return task;
32702  }
32703  
32704  EXPORT_SYMBOL(find_task_by_pid_type_ns);
32705 diff -urNp linux-2.6.27.10/kernel/posix-cpu-timers.c linux-2.6.27.10/kernel/posix-cpu-timers.c
32706 --- linux-2.6.27.10/kernel/posix-cpu-timers.c   2008-11-07 12:55:34.000000000 -0500
32707 +++ linux-2.6.27.10/kernel/posix-cpu-timers.c   2008-11-18 03:38:45.000000000 -0500
32708 @@ -6,6 +6,7 @@
32709  #include <linux/posix-timers.h>
32710  #include <linux/errno.h>
32711  #include <linux/math64.h>
32712 +#include <linux/grsecurity.h>
32713  #include <asm/uaccess.h>
32714  
32715  static int check_clock(const clockid_t which_clock)
32716 @@ -1176,6 +1177,7 @@ static void check_process_timers(struct 
32717                         __group_send_sig_info(SIGKILL, SEND_SIG_PRIV, tsk);
32718                         return;
32719                 }
32720 +               gr_learn_resource(tsk, RLIMIT_CPU, psecs, 1);
32721                 if (psecs >= sig->rlim[RLIMIT_CPU].rlim_cur) {
32722                         /*
32723                          * At the soft limit, send a SIGXCPU every second.
32724 @@ -1370,17 +1372,17 @@ void run_posix_cpu_timers(struct task_st
32725          * timer call will interfere.
32726          */
32727         list_for_each_entry_safe(timer, next, &firing, it.cpu.entry) {
32728 -               int firing;
32729 +               int __firing;
32730                 spin_lock(&timer->it_lock);
32731                 list_del_init(&timer->it.cpu.entry);
32732 -               firing = timer->it.cpu.firing;
32733 +               __firing = timer->it.cpu.firing;
32734                 timer->it.cpu.firing = 0;
32735                 /*
32736                  * The firing flag is -1 if we collided with a reset
32737                  * of the timer, which already reported this
32738                  * almost-firing as an overrun.  So don't generate an event.
32739                  */
32740 -               if (likely(firing >= 0)) {
32741 +               if (likely(__firing >= 0)) {
32742                         cpu_timer_fire(timer);
32743                 }
32744                 spin_unlock(&timer->it_lock);
32745 diff -urNp linux-2.6.27.10/kernel/power/poweroff.c linux-2.6.27.10/kernel/power/poweroff.c
32746 --- linux-2.6.27.10/kernel/power/poweroff.c     2008-11-07 12:55:34.000000000 -0500
32747 +++ linux-2.6.27.10/kernel/power/poweroff.c     2008-11-18 03:38:45.000000000 -0500
32748 @@ -37,7 +37,7 @@ static struct sysrq_key_op    sysrq_powerof
32749         .enable_mask    = SYSRQ_ENABLE_BOOT,
32750  };
32751  
32752 -static int pm_sysrq_init(void)
32753 +static int __init pm_sysrq_init(void)
32754  {
32755         register_sysrq_key('o', &sysrq_poweroff_op);
32756         return 0;
32757 diff -urNp linux-2.6.27.10/kernel/printk.c linux-2.6.27.10/kernel/printk.c
32758 --- linux-2.6.27.10/kernel/printk.c     2008-11-07 12:55:34.000000000 -0500
32759 +++ linux-2.6.27.10/kernel/printk.c     2008-11-18 03:38:45.000000000 -0500
32760 @@ -32,6 +32,7 @@
32761  #include <linux/bootmem.h>
32762  #include <linux/syscalls.h>
32763  #include <linux/vs_cvirt.h>
32764 +#include <linux/grsecurity.h>
32765  
32766  #include <asm/uaccess.h>
32767  
32768 @@ -293,6 +294,11 @@ int do_syslog(int type, char __user *buf
32769         char c;
32770         int error = 0;
32771  
32772 +#ifdef CONFIG_GRKERNSEC_DMESG
32773 +       if (grsec_enable_dmesg && !capable(CAP_SYS_ADMIN))
32774 +               return -EPERM;
32775 +#endif
32776 +
32777         error = security_syslog(type);
32778         if (error)
32779                 return error;
32780 diff -urNp linux-2.6.27.10/kernel/ptrace.c linux-2.6.27.10/kernel/ptrace.c
32781 --- linux-2.6.27.10/kernel/ptrace.c     2008-11-07 12:55:34.000000000 -0500
32782 +++ linux-2.6.27.10/kernel/ptrace.c     2008-11-18 03:38:45.000000000 -0500
32783 @@ -21,6 +21,7 @@
32784  #include <linux/pid_namespace.h>
32785  #include <linux/syscalls.h>
32786  #include <linux/vs_context.h>
32787 +#include <linux/grsecurity.h>
32788  
32789  #include <asm/pgtable.h>
32790  #include <asm/uaccess.h>
32791 @@ -132,12 +133,12 @@ int __ptrace_may_access(struct task_stru
32792              (current->uid != task->uid) ||
32793              (current->gid != task->egid) ||
32794              (current->gid != task->sgid) ||
32795 -            (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
32796 +            (current->gid != task->gid)) && !capable_nolog(CAP_SYS_PTRACE))
32797                 return -EPERM;
32798         smp_rmb();
32799         if (task->mm)
32800                 dumpable = get_dumpable(task->mm);
32801 -       if (!dumpable && !capable(CAP_SYS_PTRACE))
32802 +       if (!dumpable && !capable_nolog(CAP_SYS_PTRACE))
32803                 return -EPERM;
32804  
32805         return security_ptrace_may_access(task, mode);
32806 @@ -193,7 +194,7 @@ repeat:
32807  
32808         /* Go */
32809         task->ptrace |= PT_PTRACED;
32810 -       if (capable(CAP_SYS_PTRACE))
32811 +       if (capable_nolog(CAP_SYS_PTRACE))
32812                 task->ptrace |= PT_PTRACE_CAP;
32813  
32814         __ptrace_link(task, current);
32815 @@ -582,6 +583,11 @@ asmlinkage long sys_ptrace(long request,
32816         if (ret < 0)
32817                 goto out_put_task_struct;
32818  
32819 +       if (gr_handle_ptrace(child, request)) {
32820 +               ret = -EPERM;
32821 +               goto out_put_task_struct;
32822 +       }
32823 +
32824         ret = arch_ptrace(child, request, addr, data);
32825         if (ret < 0)
32826                 goto out_put_task_struct;
32827 diff -urNp linux-2.6.27.10/kernel/relay.c linux-2.6.27.10/kernel/relay.c
32828 --- linux-2.6.27.10/kernel/relay.c      2008-11-07 12:55:34.000000000 -0500
32829 +++ linux-2.6.27.10/kernel/relay.c      2008-11-18 03:38:45.000000000 -0500
32830 @@ -1291,7 +1291,7 @@ static int subbuf_splice_actor(struct fi
32831                 return 0;
32832  
32833         ret = *nonpad_ret = splice_to_pipe(pipe, &spd);
32834 -       if (ret < 0 || ret < total_len)
32835 +       if ((int)ret < 0 || ret < total_len)
32836                 return ret;
32837  
32838          if (read_start + ret == nonpad_end)
32839 diff -urNp linux-2.6.27.10/kernel/resource.c linux-2.6.27.10/kernel/resource.c
32840 --- linux-2.6.27.10/kernel/resource.c   2008-11-07 12:55:34.000000000 -0500
32841 +++ linux-2.6.27.10/kernel/resource.c   2008-11-18 03:38:45.000000000 -0500
32842 @@ -131,8 +131,18 @@ static const struct file_operations proc
32843  
32844  static int __init ioresources_init(void)
32845  {
32846 +#ifdef CONFIG_GRKERNSEC_PROC_ADD
32847 +#ifdef CONFIG_GRKERNSEC_PROC_USER
32848 +       proc_create("ioports", S_IRUSR, NULL, &proc_ioports_operations);
32849 +       proc_create("iomem", S_IRUSR, NULL, &proc_iomem_operations);
32850 +#elif defined(CONFIG_GRKERNSEC_PROC_USERGROUP)
32851 +       proc_create("ioports", S_IRUSR | S_IRGRP, NULL, &proc_ioports_operations);
32852 +       proc_create("iomem", S_IRUSR | S_IRGRP, NULL, &proc_iomem_operations);
32853 +#endif
32854 +#else
32855         proc_create("ioports", 0, NULL, &proc_ioports_operations);
32856         proc_create("iomem", 0, NULL, &proc_iomem_operations);
32857 +#endif
32858         return 0;
32859  }
32860  __initcall(ioresources_init);
32861 diff -urNp linux-2.6.27.10/kernel/sched.c linux-2.6.27.10/kernel/sched.c
32862 --- linux-2.6.27.10/kernel/sched.c      2008-12-21 01:16:52.000000000 -0500
32863 +++ linux-2.6.27.10/kernel/sched.c      2008-12-21 01:13:46.000000000 -0500
32864 @@ -71,6 +71,7 @@
32865  #include <linux/ftrace.h>
32866  #include <linux/vs_sched.h>
32867  #include <linux/vs_cvirt.h>
32868 +#include <linux/grsecurity.h>
32869  
32870  #include <asm/tlb.h>
32871  #include <asm/irq_regs.h>
32872 @@ -4962,7 +4963,8 @@ asmlinkage long sys_nice(int increment)
32873         if (nice > 19)
32874                 nice = 19;
32875  
32876 -       if (increment < 0 && !can_nice(current, nice))
32877 +       if (increment < 0 && (!can_nice(current, nice) ||
32878 +                             gr_handle_chroot_nice()))
32879                 return vx_flags(VXF_IGNEG_NICE, 0) ? 0 : -EPERM;
32880  
32881         retval = security_task_setnice(current, nice);
32882 @@ -6225,7 +6227,7 @@ static struct ctl_table sd_ctl_dir[] = {
32883                 .procname       = "sched_domain",
32884                 .mode           = 0555,
32885         },
32886 -       {0, },
32887 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32888  };
32889  
32890  static struct ctl_table sd_ctl_root[] = {
32891 @@ -6235,7 +6237,7 @@ static struct ctl_table sd_ctl_root[] = 
32892                 .mode           = 0555,
32893                 .child          = sd_ctl_dir,
32894         },
32895 -       {0, },
32896 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
32897  };
32898  
32899  static struct ctl_table *sd_alloc_ctl_entry(int n)
32900 diff -urNp linux-2.6.27.10/kernel/signal.c linux-2.6.27.10/kernel/signal.c
32901 --- linux-2.6.27.10/kernel/signal.c     2008-11-07 12:55:34.000000000 -0500
32902 +++ linux-2.6.27.10/kernel/signal.c     2008-11-18 03:38:45.000000000 -0500
32903 @@ -26,6 +26,7 @@
32904  #include <linux/capability.h>
32905  #include <linux/freezer.h>
32906  #include <linux/pid_namespace.h>
32907 +#include <linux/grsecurity.h>
32908  #include <linux/nsproxy.h>
32909  #include <linux/vs_context.h>
32910  #include <linux/vs_pid.h>
32911 @@ -595,6 +596,9 @@ static int check_kill_permission(int sig
32912                 return error;
32913         }
32914  skip:
32915 +       if (gr_handle_signal(t, sig))
32916 +               return -EPERM;
32917 +
32918         return security_task_kill(t, info, sig, 0);
32919  }
32920  
32921 @@ -884,8 +888,8 @@ static void print_fatal_signal(struct pt
32922                 for (i = 0; i < 16; i++) {
32923                         unsigned char insn;
32924  
32925 -                       __get_user(insn, (unsigned char *)(regs->ip + i));
32926 -                       printk("%02x ", insn);
32927 +                       if (!get_user(insn, (unsigned char __user *)(regs->ip + i)))
32928 +                               printk("%02x ", insn);
32929                 }
32930         }
32931  #endif
32932 @@ -908,7 +912,7 @@ __group_send_sig_info(int sig, struct si
32933         return send_signal(sig, info, p, 1);
32934  }
32935  
32936 -static int
32937 +int
32938  specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
32939  {
32940         return send_signal(sig, info, t, 0);
32941 @@ -946,8 +950,12 @@ force_sig_info(int sig, struct siginfo *
32942         if (action->sa.sa_handler == SIG_DFL)
32943                 t->signal->flags &= ~SIGNAL_UNKILLABLE;
32944         ret = specific_send_sig_info(sig, info, t);
32945 +
32946         spin_unlock_irqrestore(&t->sighand->siglock, flags);
32947  
32948 +       gr_log_signal(sig, t);
32949 +       gr_handle_crash(t, sig);
32950 +
32951         return ret;
32952  }
32953  
32954 @@ -1018,6 +1026,8 @@ int group_send_sig_info(int sig, struct 
32955                         ret = __group_send_sig_info(sig, info, p);
32956                         unlock_task_sighand(p, &flags);
32957                 }
32958 +               if (!ret)
32959 +                       gr_log_signal(sig, p);
32960         }
32961  
32962         return ret;
32963 diff -urNp linux-2.6.27.10/kernel/softirq.c linux-2.6.27.10/kernel/softirq.c
32964 --- linux-2.6.27.10/kernel/softirq.c    2008-11-07 12:55:34.000000000 -0500
32965 +++ linux-2.6.27.10/kernel/softirq.c    2008-11-18 03:38:45.000000000 -0500
32966 @@ -453,9 +453,9 @@ void tasklet_kill(struct tasklet_struct 
32967                 printk("Attempt to kill tasklet from interrupt\n");
32968  
32969         while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
32970 -               do
32971 +               do {
32972                         yield();
32973 -               while (test_bit(TASKLET_STATE_SCHED, &t->state));
32974 +               } while (test_bit(TASKLET_STATE_SCHED, &t->state));
32975         }
32976         tasklet_unlock_wait(t);
32977         clear_bit(TASKLET_STATE_SCHED, &t->state);
32978 diff -urNp linux-2.6.27.10/kernel/sys.c linux-2.6.27.10/kernel/sys.c
32979 --- linux-2.6.27.10/kernel/sys.c        2008-11-07 12:55:34.000000000 -0500
32980 +++ linux-2.6.27.10/kernel/sys.c        2008-11-18 03:38:45.000000000 -0500
32981 @@ -33,6 +33,7 @@
32982  #include <linux/task_io_accounting_ops.h>
32983  #include <linux/seccomp.h>
32984  #include <linux/cpu.h>
32985 +#include <linux/grsecurity.h>
32986  
32987  #include <linux/compat.h>
32988  #include <linux/syscalls.h>
32989 @@ -125,6 +126,12 @@ static int set_one_prio(struct task_stru
32990                 error = -EACCES;
32991                 goto out;
32992         }
32993 +
32994 +       if (gr_handle_chroot_setpriority(p, niceval)) {
32995 +               error = -EACCES;
32996 +               goto out;
32997 +       }
32998 +
32999         no_nice = security_task_setnice(p, niceval);
33000         if (no_nice) {
33001                 error = no_nice;
33002 @@ -181,10 +188,10 @@ asmlinkage long sys_setpriority(int whic
33003                                 if ((who != current->uid) && !(user = find_user(who)))
33004                                         goto out_unlock;        /* No processes for this user */
33005  
33006 -                       do_each_thread(g, p)
33007 +                       do_each_thread(g, p) {
33008                                 if (p->uid == who)
33009                                         error = set_one_prio(p, niceval, error);
33010 -                       while_each_thread(g, p);
33011 +                       } while_each_thread(g, p);
33012                         if (who != current->uid)
33013                                 free_uid(user);         /* For find_user() */
33014                         break;
33015 @@ -243,13 +250,13 @@ asmlinkage long sys_getpriority(int whic
33016                                 if ((who != current->uid) && !(user = find_user(who)))
33017                                         goto out_unlock;        /* No processes for this user */
33018  
33019 -                       do_each_thread(g, p)
33020 +                       do_each_thread(g, p) {
33021                                 if (p->uid == who) {
33022                                         niceval = 20 - task_nice(p);
33023                                         if (niceval > retval)
33024                                                 retval = niceval;
33025                                 }
33026 -                       while_each_thread(g, p);
33027 +                       } while_each_thread(g, p);
33028                         if (who != current->uid)
33029                                 free_uid(user);         /* for find_user() */
33030                         break;
33031 @@ -499,6 +506,10 @@ asmlinkage long sys_setregid(gid_t rgid,
33032                 else
33033                         return -EPERM;
33034         }
33035 +
33036 +       if (gr_check_group_change(new_rgid, new_egid, -1))
33037 +               return -EPERM;
33038 +
33039         if (new_egid != old_egid) {
33040                 set_dumpable(current->mm, suid_dumpable);
33041                 smp_wmb();
33042 @@ -506,6 +517,9 @@ asmlinkage long sys_setregid(gid_t rgid,
33043         if (rgid != (gid_t) -1 ||
33044             (egid != (gid_t) -1 && egid != old_rgid))
33045                 current->sgid = new_egid;
33046 +
33047 +       gr_set_role_label(current, current->uid, new_rgid);
33048 +
33049         current->fsgid = new_egid;
33050         current->egid = new_egid;
33051         current->gid = new_rgid;
33052 @@ -528,11 +542,17 @@ asmlinkage long sys_setgid(gid_t gid)
33053         if (retval)
33054                 return retval;
33055  
33056 +       if (gr_check_group_change(gid, gid, gid))
33057 +               return -EPERM;
33058 +
33059         if (capable(CAP_SETGID)) {
33060                 if (old_egid != gid) {
33061                         set_dumpable(current->mm, suid_dumpable);
33062                         smp_wmb();
33063                 }
33064 +
33065 +               gr_set_role_label(current, current->uid, gid);
33066 +
33067                 current->gid = current->egid = current->sgid = current->fsgid = gid;
33068         } else if ((gid == current->gid) || (gid == current->sgid)) {
33069                 if (old_egid != gid) {
33070 @@ -570,6 +590,9 @@ static int set_user(uid_t new_ruid, int 
33071                 set_dumpable(current->mm, suid_dumpable);
33072                 smp_wmb();
33073         }
33074 +
33075 +       gr_set_role_label(current, new_ruid, current->gid);
33076 +
33077         current->uid = new_ruid;
33078         return 0;
33079  }
33080 @@ -619,6 +642,9 @@ asmlinkage long sys_setreuid(uid_t ruid,
33081                         return -EPERM;
33082         }
33083  
33084 +       if (gr_check_user_change(new_ruid, new_euid, -1))
33085 +               return -EPERM;
33086 +
33087         if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
33088                 return -EAGAIN;
33089  
33090 @@ -665,6 +691,12 @@ asmlinkage long sys_setuid(uid_t uid)
33091         old_suid = current->suid;
33092         new_suid = old_suid;
33093         
33094 +       if (gr_check_crash_uid(uid))
33095 +               return -EPERM;
33096 +
33097 +       if (gr_check_user_change(uid, uid, uid))
33098 +               return -EPERM;
33099 +
33100         if (capable(CAP_SETUID)) {
33101                 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
33102                         return -EAGAIN;
33103 @@ -712,6 +744,10 @@ asmlinkage long sys_setresuid(uid_t ruid
33104                     (suid != current->euid) && (suid != current->suid))
33105                         return -EPERM;
33106         }
33107 +
33108 +       if (gr_check_user_change(ruid, euid, -1))
33109 +               return -EPERM;
33110 +
33111         if (ruid != (uid_t) -1) {
33112                 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
33113                         return -EAGAIN;
33114 @@ -766,6 +802,10 @@ asmlinkage long sys_setresgid(gid_t rgid
33115                     (sgid != current->egid) && (sgid != current->sgid))
33116                         return -EPERM;
33117         }
33118 +
33119 +       if (gr_check_group_change(rgid, egid, -1))
33120 +               return -EPERM;
33121 +
33122         if (egid != (gid_t) -1) {
33123                 if (egid != current->egid) {
33124                         set_dumpable(current->mm, suid_dumpable);
33125 @@ -774,8 +814,10 @@ asmlinkage long sys_setresgid(gid_t rgid
33126                 current->egid = egid;
33127         }
33128         current->fsgid = current->egid;
33129 -       if (rgid != (gid_t) -1)
33130 +       if (rgid != (gid_t) -1) {
33131 +               gr_set_role_label(current, current->uid, rgid);
33132                 current->gid = rgid;
33133 +       }
33134         if (sgid != (gid_t) -1)
33135                 current->sgid = sgid;
33136  
33137 @@ -810,6 +852,9 @@ asmlinkage long sys_setfsuid(uid_t uid)
33138         if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
33139                 return old_fsuid;
33140  
33141 +       if (gr_check_user_change(-1, -1, uid))
33142 +               return old_fsuid;
33143 +
33144         if (uid == current->uid || uid == current->euid ||
33145             uid == current->suid || uid == current->fsuid || 
33146             capable(CAP_SETUID)) {
33147 @@ -842,6 +887,9 @@ asmlinkage long sys_setfsgid(gid_t gid)
33148         if (gid == current->gid || gid == current->egid ||
33149             gid == current->sgid || gid == current->fsgid || 
33150             capable(CAP_SETGID)) {
33151 +               if (gr_check_group_change(-1, -1, gid))
33152 +                       return old_fsgid;
33153 +
33154                 if (gid != old_fsgid) {
33155                         set_dumpable(current->mm, suid_dumpable);
33156                         smp_wmb();
33157 @@ -923,7 +971,10 @@ asmlinkage long sys_setpgid(pid_t pid, p
33158         write_lock_irq(&tasklist_lock);
33159  
33160         err = -ESRCH;
33161 -       p = find_task_by_vpid(pid);
33162 +       /* grsec: replaced find_task_by_vpid with equivalent call which
33163 +          lacks the chroot restriction
33164 +       */
33165 +       p = pid_task(find_pid_ns(pid, current->nsproxy->pid_ns), PIDTYPE_PID);
33166         if (!p)
33167                 goto out;
33168  
33169 @@ -1655,7 +1706,7 @@ asmlinkage long sys_prctl(int option, un
33170                         error = get_dumpable(current->mm);
33171                         break;
33172                 case PR_SET_DUMPABLE:
33173 -                       if (arg2 < 0 || arg2 > 1) {
33174 +                       if (arg2 > 1) {
33175                                 error = -EINVAL;
33176                                 break;
33177                         }
33178 diff -urNp linux-2.6.27.10/kernel/sysctl.c linux-2.6.27.10/kernel/sysctl.c
33179 --- linux-2.6.27.10/kernel/sysctl.c     2008-12-10 22:35:38.000000000 -0500
33180 +++ linux-2.6.27.10/kernel/sysctl.c     2008-12-10 22:35:46.000000000 -0500
33181 @@ -61,6 +61,13 @@
33182  static int deprecated_sysctl_warning(struct __sysctl_args *args);
33183  
33184  #if defined(CONFIG_SYSCTL)
33185 +#include <linux/grsecurity.h>
33186 +#include <linux/grinternal.h>
33187 +
33188 +extern __u32 gr_handle_sysctl(const ctl_table *table, const int op);
33189 +extern int gr_handle_sysctl_mod(const char *dirname, const char *name,
33190 +                               const int op);
33191 +extern int gr_handle_chroot_sysctl(const int op);
33192  
33193  /* External variables not in a header file. */
33194  extern int C_A_D;
33195 @@ -155,6 +162,7 @@ static int proc_do_cad_pid(struct ctl_ta
33196  static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp,
33197                                void __user *buffer, size_t *lenp, loff_t *ppos);
33198  #endif
33199 +extern ctl_table grsecurity_table[];
33200  
33201  static struct ctl_table root_table[];
33202  static struct ctl_table_root sysctl_table_root;
33203 @@ -187,6 +195,21 @@ extern struct ctl_table epoll_table[];
33204  int sysctl_legacy_va_layout;
33205  #endif
33206  
33207 +#ifdef CONFIG_PAX_SOFTMODE
33208 +static ctl_table pax_table[] = {
33209 +       {
33210 +               .ctl_name       = CTL_UNNUMBERED,
33211 +               .procname       = "softmode",
33212 +               .data           = &pax_softmode,
33213 +               .maxlen         = sizeof(unsigned int),
33214 +               .mode           = 0600,
33215 +               .proc_handler   = &proc_dointvec,
33216 +       },
33217 +
33218 +       { .ctl_name = 0 }
33219 +};
33220 +#endif
33221 +
33222  extern int prove_locking;
33223  extern int lock_stat;
33224  
33225 @@ -223,6 +246,7 @@ static struct ctl_table root_table[] = {
33226                 .mode           = 0555,
33227                 .child          = dev_table,
33228         },
33229 +
33230  /*
33231   * NOTE: do not add new entries to this table unless you have read
33232   * Documentation/sysctl/ctl_unnumbered.txt
33233 @@ -850,6 +874,25 @@ static struct ctl_table kern_table[] = {
33234                 .proc_handler   = &proc_dointvec,
33235         },
33236  #endif
33237 +
33238 +#if defined(CONFIG_GRKERNSEC_SYSCTL) || defined(CONFIG_GRKERNSEC_MODSTOP)
33239 +       {
33240 +               .ctl_name       = CTL_UNNUMBERED,
33241 +               .procname       = "grsecurity",
33242 +               .mode           = 0500,
33243 +               .child          = grsecurity_table,
33244 +       },
33245 +#endif
33246 +
33247 +#ifdef CONFIG_PAX_SOFTMODE
33248 +       {
33249 +               .ctl_name       = CTL_UNNUMBERED,
33250 +               .procname       = "pax",
33251 +               .mode           = 0500,
33252 +               .child          = pax_table,
33253 +       },
33254 +#endif
33255 +
33256  /*
33257   * NOTE: do not add new entries to this table unless you have read
33258   * Documentation/sysctl/ctl_unnumbered.txt
33259 @@ -1179,6 +1222,7 @@ static struct ctl_table vm_table[] = {
33260                 .extra2         = &one,
33261         },
33262  #endif
33263 +
33264  /*
33265   * NOTE: do not add new entries to this table unless you have read
33266   * Documentation/sysctl/ctl_unnumbered.txt
33267 @@ -1553,6 +1597,8 @@ static int do_sysctl_strategy(struct ctl
33268         return 0;
33269  }
33270  
33271 +static int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op);
33272 +
33273  static int parse_table(int __user *name, int nlen,
33274                        void __user *oldval, size_t __user *oldlenp,
33275                        void __user *newval, size_t newlen,
33276 @@ -1571,7 +1617,7 @@ repeat:
33277                 if (n == table->ctl_name) {
33278                         int error;
33279                         if (table->child) {
33280 -                               if (sysctl_perm(root, table, MAY_EXEC))
33281 +                               if (sysctl_perm_nochk(root, table, MAY_EXEC))
33282                                         return -EPERM;
33283                                 name++;
33284                                 nlen--;
33285 @@ -1656,6 +1702,33 @@ int sysctl_perm(struct ctl_table_root *r
33286         int error;
33287         int mode;
33288  
33289 +       if (table->parent != NULL && table->parent->procname != NULL &&
33290 +          table->procname != NULL &&
33291 +           gr_handle_sysctl_mod(table->parent->procname, table->procname, op))
33292 +               return -EACCES;
33293 +       if (gr_handle_chroot_sysctl(op))
33294 +               return -EACCES;
33295 +       error = gr_handle_sysctl(table, op);
33296 +       if (error)
33297 +               return error;
33298 +
33299 +       error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33300 +       if (error)
33301 +               return error;
33302 +
33303 +       if (root->permissions)
33304 +               mode = root->permissions(root, current->nsproxy, table);
33305 +       else
33306 +               mode = table->mode;
33307 +
33308 +       return test_perm(mode, op);
33309 +}
33310 +
33311 +int sysctl_perm_nochk(struct ctl_table_root *root, struct ctl_table *table, int op)
33312 +{
33313 +       int error;
33314 +       int mode;
33315 +
33316         error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
33317         if (error)
33318                 return error;
33319 diff -urNp linux-2.6.27.10/kernel/time/tick-broadcast.c linux-2.6.27.10/kernel/time/tick-broadcast.c
33320 --- linux-2.6.27.10/kernel/time/tick-broadcast.c        2008-11-07 12:55:34.000000000 -0500
33321 +++ linux-2.6.27.10/kernel/time/tick-broadcast.c        2008-11-18 03:38:45.000000000 -0500
33322 @@ -114,7 +114,7 @@ int tick_device_uses_broadcast(struct cl
33323                  * then clear the broadcast bit.
33324                  */
33325                 if (!(dev->features & CLOCK_EVT_FEAT_C3STOP)) {
33326 -                       int cpu = smp_processor_id();
33327 +                       cpu = smp_processor_id();
33328  
33329                         cpu_clear(cpu, tick_broadcast_mask);
33330                         tick_broadcast_clear_oneshot(cpu);
33331 diff -urNp linux-2.6.27.10/kernel/time.c linux-2.6.27.10/kernel/time.c
33332 --- linux-2.6.27.10/kernel/time.c       2008-11-07 12:55:34.000000000 -0500
33333 +++ linux-2.6.27.10/kernel/time.c       2008-11-18 03:38:45.000000000 -0500
33334 @@ -37,6 +37,7 @@
33335  #include <linux/fs.h>
33336  #include <linux/slab.h>
33337  #include <linux/math64.h>
33338 +#include <linux/grsecurity.h>
33339  
33340  #include <asm/uaccess.h>
33341  #include <asm/unistd.h>
33342 @@ -92,6 +93,9 @@ asmlinkage long sys_stime(time_t __user 
33343                 return err;
33344  
33345         vx_settimeofday(&tv);
33346 +
33347 +       gr_log_timechange();
33348 +
33349         return 0;
33350  }
33351  
33352 @@ -200,6 +204,8 @@ asmlinkage long sys_settimeofday(struct 
33353                         return -EFAULT;
33354         }
33355  
33356 +       gr_log_timechange();
33357 +
33358         return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
33359  }
33360  
33361 @@ -238,7 +244,7 @@ EXPORT_SYMBOL(current_fs_time);
33362   * Avoid unnecessary multiplications/divisions in the
33363   * two most common HZ cases:
33364   */
33365 -unsigned int inline jiffies_to_msecs(const unsigned long j)
33366 +inline unsigned int jiffies_to_msecs(const unsigned long j)
33367  {
33368  #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ)
33369         return (MSEC_PER_SEC / HZ) * j;
33370 @@ -254,7 +260,7 @@ unsigned int inline jiffies_to_msecs(con
33371  }
33372  EXPORT_SYMBOL(jiffies_to_msecs);
33373  
33374 -unsigned int inline jiffies_to_usecs(const unsigned long j)
33375 +inline unsigned int jiffies_to_usecs(const unsigned long j)
33376  {
33377  #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ)
33378         return (USEC_PER_SEC / HZ) * j;
33379 diff -urNp linux-2.6.27.10/kernel/utsname_sysctl.c linux-2.6.27.10/kernel/utsname_sysctl.c
33380 --- linux-2.6.27.10/kernel/utsname_sysctl.c     2008-11-07 12:55:34.000000000 -0500
33381 +++ linux-2.6.27.10/kernel/utsname_sysctl.c     2008-11-18 03:38:45.000000000 -0500
33382 @@ -124,7 +124,7 @@ static struct ctl_table uts_kern_table[]
33383                 .proc_handler   = proc_do_uts_string,
33384                 .strategy       = sysctl_uts_string,
33385         },
33386 -       {}
33387 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33388  };
33389  
33390  static struct ctl_table uts_root_table[] = {
33391 @@ -134,7 +134,7 @@ static struct ctl_table uts_root_table[]
33392                 .mode           = 0555,
33393                 .child          = uts_kern_table,
33394         },
33395 -       {}
33396 +       { 0, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL }
33397  };
33398  
33399  static int __init utsname_sysctl_init(void)
33400 diff -urNp linux-2.6.27.10/lib/radix-tree.c linux-2.6.27.10/lib/radix-tree.c
33401 --- linux-2.6.27.10/lib/radix-tree.c    2008-11-07 12:55:34.000000000 -0500
33402 +++ linux-2.6.27.10/lib/radix-tree.c    2008-11-18 03:38:45.000000000 -0500
33403 @@ -81,7 +81,7 @@ struct radix_tree_preload {
33404         int nr;
33405         struct radix_tree_node *nodes[RADIX_TREE_MAX_PATH];
33406  };
33407 -DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads) = { 0, };
33408 +DEFINE_PER_CPU(struct radix_tree_preload, radix_tree_preloads);
33409  
33410  static inline gfp_t root_gfp_mask(struct radix_tree_root *root)
33411  {
33412 diff -urNp linux-2.6.27.10/localversion-grsec linux-2.6.27.10/localversion-grsec
33413 --- linux-2.6.27.10/localversion-grsec  1969-12-31 19:00:00.000000000 -0500
33414 +++ linux-2.6.27.10/localversion-grsec  2008-11-18 03:38:45.000000000 -0500
33415 @@ -0,0 +1 @@
33416 +-grsec
33417 diff -urNp linux-2.6.27.10/Makefile linux-2.6.27.10/Makefile
33418 --- linux-2.6.27.10/Makefile    2008-12-21 01:18:11.000000000 -0500
33419 +++ linux-2.6.27.10/Makefile    2008-12-21 01:18:21.000000000 -0500
33420 @@ -221,7 +221,7 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH"
33421  
33422  HOSTCC       = gcc
33423  HOSTCXX      = g++
33424 -HOSTCFLAGS   = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
33425 +HOSTCFLAGS   = -Wall -W -Wno-unused -Wno-sign-compare -Wstrict-prototypes -O2 -fomit-frame-pointer
33426  HOSTCXXFLAGS = -O2
33427  
33428  # Decide whether to build built-in, modular, or both.
33429 @@ -619,7 +619,7 @@ export mod_strip_cmd
33430  
33431  
33432  ifeq ($(KBUILD_EXTMOD),)
33433 -core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
33434 +core-y         += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ grsecurity/
33435  
33436  vmlinux-dirs   := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
33437                      $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
33438 diff -urNp linux-2.6.27.10/mm/filemap.c linux-2.6.27.10/mm/filemap.c
33439 --- linux-2.6.27.10/mm/filemap.c        2008-11-07 12:55:34.000000000 -0500
33440 +++ linux-2.6.27.10/mm/filemap.c        2008-11-18 03:38:45.000000000 -0500
33441 @@ -33,6 +33,7 @@
33442  #include <linux/cpuset.h>
33443  #include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
33444  #include <linux/memcontrol.h>
33445 +#include <linux/grsecurity.h>
33446  #include "internal.h"
33447  
33448  /*
33449 @@ -1588,7 +1589,7 @@ int generic_file_mmap(struct file * file
33450         struct address_space *mapping = file->f_mapping;
33451  
33452         if (!mapping->a_ops->readpage)
33453 -               return -ENOEXEC;
33454 +               return -ENODEV;
33455         file_accessed(file);
33456         vma->vm_ops = &generic_file_vm_ops;
33457         vma->vm_flags |= VM_CAN_NONLINEAR;
33458 @@ -1949,6 +1950,7 @@ inline int generic_write_checks(struct f
33459                          *pos = i_size_read(inode);
33460  
33461                 if (limit != RLIM_INFINITY) {
33462 +                       gr_learn_resource(current, RLIMIT_FSIZE,*pos, 0);
33463                         if (*pos >= limit) {
33464                                 send_sig(SIGXFSZ, current, 0);
33465                                 return -EFBIG;
33466 diff -urNp linux-2.6.27.10/mm/fremap.c linux-2.6.27.10/mm/fremap.c
33467 --- linux-2.6.27.10/mm/fremap.c 2008-11-07 12:55:34.000000000 -0500
33468 +++ linux-2.6.27.10/mm/fremap.c 2008-11-18 03:38:45.000000000 -0500
33469 @@ -151,6 +151,13 @@ asmlinkage long sys_remap_file_pages(uns
33470   retry:
33471         vma = find_vma(mm, start);
33472  
33473 +#ifdef CONFIG_PAX_SEGMEXEC
33474 +       if (vma && (mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_MAYEXEC)) {
33475 +               up_read(&mm->mmap_sem);
33476 +               return err;
33477 +       }
33478 +#endif
33479 +
33480         /*
33481          * Make sure the vma is shared, that it supports prefaulting,
33482          * and that the remapped range is valid and fully within
33483 diff -urNp linux-2.6.27.10/mm/hugetlb.c linux-2.6.27.10/mm/hugetlb.c
33484 --- linux-2.6.27.10/mm/hugetlb.c        2008-11-18 11:38:40.000000000 -0500
33485 +++ linux-2.6.27.10/mm/hugetlb.c        2008-11-18 11:40:53.000000000 -0500
33486 @@ -1833,6 +1833,26 @@ int unmap_ref_private(struct mm_struct *
33487         return 1;
33488  }
33489  
33490 +#ifdef CONFIG_PAX_SEGMEXEC
33491 +static void pax_mirror_huge_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m)
33492 +{
33493 +       struct mm_struct *mm = vma->vm_mm;
33494 +       struct vm_area_struct *vma_m;
33495 +       unsigned long address_m;
33496 +       pte_t *ptep_m;
33497 +
33498 +       vma_m = pax_find_mirror_vma(vma);
33499 +       if (!vma_m)
33500 +               return;
33501 +
33502 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33503 +       address_m = address + SEGMEXEC_TASK_SIZE;
33504 +       ptep_m = huge_pte_offset(mm, address_m & HPAGE_MASK);
33505 +       get_page(page_m);
33506 +       set_huge_pte_at(mm, address_m, ptep_m, make_huge_pte(vma_m, page_m, 0));
33507 +}
33508 +#endif
33509 +
33510  static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma,
33511                         unsigned long address, pte_t *ptep, pte_t pte,
33512                         struct page *pagecache_page)
33513 @@ -1904,6 +1924,11 @@ retry_avoidcopy:
33514                 huge_ptep_clear_flush(vma, address, ptep);
33515                 set_huge_pte_at(mm, address, ptep,
33516                                 make_huge_pte(vma, new_page, 1));
33517 +
33518 +#ifdef CONFIG_PAX_SEGMEXEC
33519 +               pax_mirror_huge_pte(vma, address, new_page);
33520 +#endif
33521 +
33522                 /* Make the old page be freed below */
33523                 new_page = old_page;
33524         }
33525 @@ -2013,6 +2038,10 @@ retry:
33526                                 && (vma->vm_flags & VM_SHARED)));
33527         set_huge_pte_at(mm, address, ptep, new_pte);
33528  
33529 +#ifdef CONFIG_PAX_SEGMEXEC
33530 +       pax_mirror_huge_pte(vma, address, page);
33531 +#endif
33532 +
33533         if (write_access && !(vma->vm_flags & VM_SHARED)) {
33534                 /* Optimization, do the COW without a second fault */
33535                 ret = hugetlb_cow(mm, vma, address, ptep, new_pte, page);
33536 @@ -2041,6 +2070,28 @@ int hugetlb_fault(struct mm_struct *mm, 
33537         static DEFINE_MUTEX(hugetlb_instantiation_mutex);
33538         struct hstate *h = hstate_vma(vma);
33539  
33540 +#ifdef CONFIG_PAX_SEGMEXEC
33541 +       struct vm_area_struct *vma_m;
33542 +
33543 +       vma_m = pax_find_mirror_vma(vma);
33544 +       if (vma_m) {
33545 +               unsigned long address_m;
33546 +
33547 +               if (vma->vm_start > vma_m->vm_start) {
33548 +                       address_m = address;
33549 +                       address -= SEGMEXEC_TASK_SIZE;
33550 +                       vma = vma_m;
33551 +                       h = hstate_vma(vma);
33552 +               } else
33553 +                       address_m = address + SEGMEXEC_TASK_SIZE;
33554 +
33555 +               if (!huge_pte_alloc(mm, address_m, huge_page_size(h)))
33556 +                       return VM_FAULT_OOM;
33557 +               address_m &= HPAGE_MASK;
33558 +               unmap_hugepage_range(vma, address_m, address_m + HPAGE_SIZE, NULL);
33559 +       }
33560 +#endif
33561 +
33562         ptep = huge_pte_alloc(mm, address, huge_page_size(h));
33563         if (!ptep)
33564                 return VM_FAULT_OOM;
33565 diff -urNp linux-2.6.27.10/mm/madvise.c linux-2.6.27.10/mm/madvise.c
33566 --- linux-2.6.27.10/mm/madvise.c        2008-11-07 12:55:34.000000000 -0500
33567 +++ linux-2.6.27.10/mm/madvise.c        2008-11-18 03:38:45.000000000 -0500
33568 @@ -43,6 +43,10 @@ static long madvise_behavior(struct vm_a
33569         pgoff_t pgoff;
33570         int new_flags = vma->vm_flags;
33571  
33572 +#ifdef CONFIG_PAX_SEGMEXEC
33573 +       struct vm_area_struct *vma_m;
33574 +#endif
33575 +
33576         switch (behavior) {
33577         case MADV_NORMAL:
33578                 new_flags = new_flags & ~VM_RAND_READ & ~VM_SEQ_READ;
33579 @@ -92,6 +96,13 @@ success:
33580         /*
33581          * vm_flags is protected by the mmap_sem held in write mode.
33582          */
33583 +
33584 +#ifdef CONFIG_PAX_SEGMEXEC
33585 +       vma_m = pax_find_mirror_vma(vma);
33586 +       if (vma_m)
33587 +               vma_m->vm_flags = new_flags & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT);
33588 +#endif
33589 +
33590         vma->vm_flags = new_flags;
33591  
33592  out:
33593 @@ -236,6 +247,17 @@ madvise_vma(struct vm_area_struct *vma, 
33594  
33595         case MADV_DONTNEED:
33596                 error = madvise_dontneed(vma, prev, start, end);
33597 +
33598 +#ifdef CONFIG_PAX_SEGMEXEC
33599 +               if (!error) {
33600 +                       struct vm_area_struct *vma_m, *prev_m;
33601 +
33602 +                       vma_m = pax_find_mirror_vma(vma);
33603 +                       if (vma_m)
33604 +                               error = madvise_dontneed(vma_m, &prev_m, start + SEGMEXEC_TASK_SIZE, end + SEGMEXEC_TASK_SIZE);
33605 +               }
33606 +#endif
33607 +
33608                 break;
33609  
33610         default:
33611 @@ -308,6 +330,16 @@ asmlinkage long sys_madvise(unsigned lon
33612         if (end < start)
33613                 goto out;
33614  
33615 +#ifdef CONFIG_PAX_SEGMEXEC
33616 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
33617 +               if (end > SEGMEXEC_TASK_SIZE)
33618 +                       goto out;
33619 +       } else
33620 +#endif
33621 +
33622 +       if (end > TASK_SIZE)
33623 +               goto out;
33624 +
33625         error = 0;
33626         if (end == start)
33627                 goto out;
33628 diff -urNp linux-2.6.27.10/mm/memory.c linux-2.6.27.10/mm/memory.c
33629 --- linux-2.6.27.10/mm/memory.c 2008-11-07 12:55:34.000000000 -0500
33630 +++ linux-2.6.27.10/mm/memory.c 2008-11-18 03:38:45.000000000 -0500
33631 @@ -52,6 +52,7 @@
33632  #include <linux/writeback.h>
33633  #include <linux/memcontrol.h>
33634  #include <linux/mmu_notifier.h>
33635 +#include <linux/grsecurity.h>
33636  
33637  #include <asm/pgalloc.h>
33638  #include <asm/uaccess.h>
33639 @@ -1146,11 +1147,11 @@ int get_user_pages(struct task_struct *t
33640         vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE);
33641         i = 0;
33642  
33643 -       do {
33644 +       while (len) {
33645                 struct vm_area_struct *vma;
33646                 unsigned int foll_flags;
33647  
33648 -               vma = find_extend_vma(mm, start);
33649 +               vma = find_vma(mm, start);
33650                 if (!vma && in_gate_area(tsk, start)) {
33651                         unsigned long pg = start & PAGE_MASK;
33652                         struct vm_area_struct *gate_vma = get_gate_vma(tsk);
33653 @@ -1190,7 +1191,7 @@ int get_user_pages(struct task_struct *t
33654                         continue;
33655                 }
33656  
33657 -               if (!vma || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33658 +               if (!vma || start < vma->vm_start || (vma->vm_flags & (VM_IO | VM_PFNMAP))
33659                                 || !(vm_flags & vma->vm_flags))
33660                         return i ? : -EFAULT;
33661  
33662 @@ -1263,7 +1264,7 @@ int get_user_pages(struct task_struct *t
33663                         start += PAGE_SIZE;
33664                         len--;
33665                 } while (len && start < vma->vm_end);
33666 -       } while (len);
33667 +       }
33668         return i;
33669  }
33670  EXPORT_SYMBOL(get_user_pages);
33671 @@ -1741,6 +1742,186 @@ static inline void cow_user_page(struct 
33672                 copy_user_highpage(dst, src, va, vma);
33673  }
33674  
33675 +#ifdef CONFIG_PAX_SEGMEXEC
33676 +static void pax_unmap_mirror_pte(struct vm_area_struct *vma, unsigned long address, pmd_t *pmd)
33677 +{
33678 +       struct mm_struct *mm = vma->vm_mm;
33679 +       spinlock_t *ptl;
33680 +       pte_t *pte, entry;
33681 +
33682 +       pte = pte_offset_map_lock(mm, pmd, address, &ptl);
33683 +       entry = *pte;
33684 +       if (!pte_present(entry)) {
33685 +               if (!pte_none(entry)) {
33686 +                       BUG_ON(pte_file(entry));
33687 +                       free_swap_and_cache(pte_to_swp_entry(entry));
33688 +                       pte_clear_not_present_full(mm, address, pte, 0);
33689 +               }
33690 +       } else {
33691 +               struct page *page;
33692 +
33693 +               flush_cache_page(vma, address, pte_pfn(entry));
33694 +               entry = ptep_clear_flush(vma, address, pte);
33695 +               BUG_ON(pte_dirty(entry));
33696 +               page = vm_normal_page(vma, address, entry);
33697 +               if (page) {
33698 +                       update_hiwater_rss(mm);
33699 +                       if (PageAnon(page))
33700 +                               dec_mm_counter(mm, anon_rss);
33701 +                       else
33702 +                               dec_mm_counter(mm, file_rss);
33703 +                       page_remove_rmap(page, vma);
33704 +                       page_cache_release(page);
33705 +               }
33706 +       }
33707 +       pte_unmap_unlock(pte, ptl);
33708 +}
33709 +
33710 +/* PaX: if vma is mirrored, synchronize the mirror's PTE
33711 + *
33712 + * the ptl of the lower mapped page is held on entry and is not released on exit
33713 + * or inside to ensure atomic changes to the PTE states (swapout, mremap, munmap, etc)
33714 + */
33715 +static void pax_mirror_anon_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33716 +{
33717 +       struct mm_struct *mm = vma->vm_mm;
33718 +       unsigned long address_m;
33719 +       spinlock_t *ptl_m;
33720 +       struct vm_area_struct *vma_m;
33721 +       pmd_t *pmd_m;
33722 +       pte_t *pte_m, entry_m;
33723 +
33724 +       BUG_ON(!page_m || !PageAnon(page_m));
33725 +
33726 +       vma_m = pax_find_mirror_vma(vma);
33727 +       if (!vma_m)
33728 +               return;
33729 +
33730 +       BUG_ON(!PageLocked(page_m));
33731 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33732 +       address_m = address + SEGMEXEC_TASK_SIZE;
33733 +       pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33734 +       pte_m = pte_offset_map_nested(pmd_m, address_m);
33735 +       ptl_m = pte_lockptr(mm, pmd_m);
33736 +       if (ptl != ptl_m) {
33737 +               spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33738 +               if (!pte_none(*pte_m))
33739 +                       goto out;
33740 +       }
33741 +
33742 +       entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33743 +       page_cache_get(page_m);
33744 +       page_add_anon_rmap(page_m, vma_m, address_m);
33745 +       inc_mm_counter(mm, anon_rss);
33746 +       set_pte_at(mm, address_m, pte_m, entry_m);
33747 +       update_mmu_cache(vma_m, address_m, entry_m);
33748 +out:
33749 +       if (ptl != ptl_m)
33750 +               spin_unlock(ptl_m);
33751 +       pte_unmap_nested(pte_m);
33752 +       unlock_page(page_m);
33753 +}
33754 +
33755 +void pax_mirror_file_pte(struct vm_area_struct *vma, unsigned long address, struct page *page_m, spinlock_t *ptl)
33756 +{
33757 +       struct mm_struct *mm = vma->vm_mm;
33758 +       unsigned long address_m;
33759 +       spinlock_t *ptl_m;
33760 +       struct vm_area_struct *vma_m;
33761 +       pmd_t *pmd_m;
33762 +       pte_t *pte_m, entry_m;
33763 +
33764 +       BUG_ON(!page_m || PageAnon(page_m));
33765 +
33766 +       vma_m = pax_find_mirror_vma(vma);
33767 +       if (!vma_m)
33768 +               return;
33769 +
33770 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33771 +       address_m = address + SEGMEXEC_TASK_SIZE;
33772 +       pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33773 +       pte_m = pte_offset_map_nested(pmd_m, address_m);
33774 +       ptl_m = pte_lockptr(mm, pmd_m);
33775 +       if (ptl != ptl_m) {
33776 +               spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33777 +               if (!pte_none(*pte_m))
33778 +                       goto out;
33779 +       }
33780 +
33781 +       entry_m = pfn_pte(page_to_pfn(page_m), vma_m->vm_page_prot);
33782 +       page_cache_get(page_m);
33783 +       page_add_file_rmap(page_m);
33784 +       inc_mm_counter(mm, file_rss);
33785 +       set_pte_at(mm, address_m, pte_m, entry_m);
33786 +       update_mmu_cache(vma_m, address_m, entry_m);
33787 +out:
33788 +       if (ptl != ptl_m)
33789 +               spin_unlock(ptl_m);
33790 +       pte_unmap_nested(pte_m);
33791 +}
33792 +
33793 +static void pax_mirror_pfn_pte(struct vm_area_struct *vma, unsigned long address, unsigned long pfn_m, spinlock_t *ptl)
33794 +{
33795 +       struct mm_struct *mm = vma->vm_mm;
33796 +       unsigned long address_m;
33797 +       spinlock_t *ptl_m;
33798 +       struct vm_area_struct *vma_m;
33799 +       pmd_t *pmd_m;
33800 +       pte_t *pte_m, entry_m;
33801 +
33802 +       vma_m = pax_find_mirror_vma(vma);
33803 +       if (!vma_m)
33804 +               return;
33805 +
33806 +       BUG_ON(address >= SEGMEXEC_TASK_SIZE);
33807 +       address_m = address + SEGMEXEC_TASK_SIZE;
33808 +       pmd_m = pmd_offset(pud_offset(pgd_offset(mm, address_m), address_m), address_m);
33809 +       pte_m = pte_offset_map_nested(pmd_m, address_m);
33810 +       ptl_m = pte_lockptr(mm, pmd_m);
33811 +       if (ptl != ptl_m) {
33812 +               spin_lock_nested(ptl_m, SINGLE_DEPTH_NESTING);
33813 +               if (!pte_none(*pte_m))
33814 +                       goto out;
33815 +       }
33816 +
33817 +       entry_m = pfn_pte(pfn_m, vma_m->vm_page_prot);
33818 +       set_pte_at(mm, address_m, pte_m, entry_m);
33819 +out:
33820 +       if (ptl != ptl_m)
33821 +               spin_unlock(ptl_m);
33822 +       pte_unmap_nested(pte_m);
33823 +}
33824 +
33825 +static void pax_mirror_pte(struct vm_area_struct *vma, unsigned long address, pte_t *pte, pmd_t *pmd, spinlock_t *ptl)
33826 +{
33827 +       struct page *page_m;
33828 +       pte_t entry;
33829 +
33830 +       if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC))
33831 +               goto out;
33832 +
33833 +       entry = *pte;
33834 +       page_m  = vm_normal_page(vma, address, entry);
33835 +       if (!page_m)
33836 +               pax_mirror_pfn_pte(vma, address, pte_pfn(entry), ptl);
33837 +       else if (PageAnon(page_m)) {
33838 +               if (pax_find_mirror_vma(vma)) {
33839 +                       pte_unmap_unlock(pte, ptl);
33840 +                       lock_page(page_m);
33841 +                       pte = pte_offset_map_lock(vma->vm_mm, pmd, address, &ptl);
33842 +                       if (pte_same(entry, *pte))
33843 +                               pax_mirror_anon_pte(vma, address, page_m, ptl);
33844 +                       else
33845 +                               unlock_page(page_m);
33846 +               }
33847 +       } else
33848 +               pax_mirror_file_pte(vma, address, page_m, ptl);
33849 +
33850 +out:
33851 +       pte_unmap_unlock(pte, ptl);
33852 +}
33853 +#endif
33854 +
33855  /*
33856   * This routine handles present pages, when users try to write
33857   * to a shared page. It is done by copying the page to a new address
33858 @@ -1869,6 +2050,12 @@ gotten:
33859          */
33860         page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33861         if (likely(pte_same(*page_table, orig_pte))) {
33862 +
33863 +#ifdef CONFIG_PAX_SEGMEXEC
33864 +               if (pax_find_mirror_vma(vma))
33865 +                       BUG_ON(!trylock_page(new_page));
33866 +#endif
33867 +
33868                 if (old_page) {
33869                         if (!PageAnon(old_page)) {
33870                                 dec_mm_counter(mm, file_rss);
33871 @@ -1917,6 +2104,10 @@ gotten:
33872                         page_remove_rmap(old_page, vma);
33873                 }
33874  
33875 +#ifdef CONFIG_PAX_SEGMEXEC
33876 +               pax_mirror_anon_pte(vma, address, new_page, ptl);
33877 +#endif
33878 +
33879                 /* Free the old page.. */
33880                 new_page = old_page;
33881                 ret |= VM_FAULT_WRITE;
33882 @@ -2176,6 +2367,7 @@ int vmtruncate(struct inode * inode, lof
33883                 unsigned long limit;
33884  
33885                 limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
33886 +               gr_learn_resource(current, RLIMIT_FSIZE, offset, 1);
33887                 if (limit != RLIM_INFINITY && offset > limit)
33888                         goto out_sig;
33889                 if (offset > inode->i_sb->s_maxbytes)
33890 @@ -2326,6 +2518,11 @@ static int do_swap_page(struct mm_struct
33891         swap_free(entry);
33892         if (vm_swap_full())
33893                 remove_exclusive_swap_page(page);
33894 +
33895 +#ifdef CONFIG_PAX_SEGMEXEC
33896 +       if (write_access || !pax_find_mirror_vma(vma))
33897 +#endif
33898 +
33899         unlock_page(page);
33900  
33901         if (write_access) {
33902 @@ -2337,6 +2534,11 @@ static int do_swap_page(struct mm_struct
33903  
33904         /* No need to invalidate - it was non-present before */
33905         update_mmu_cache(vma, address, pte);
33906 +
33907 +#ifdef CONFIG_PAX_SEGMEXEC
33908 +       pax_mirror_anon_pte(vma, address, page, ptl);
33909 +#endif
33910 +
33911  unlock:
33912         pte_unmap_unlock(page_table, ptl);
33913  out:
33914 @@ -2381,6 +2583,12 @@ static int do_anonymous_page(struct mm_s
33915         page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
33916         if (!pte_none(*page_table))
33917                 goto release;
33918 +
33919 +#ifdef CONFIG_PAX_SEGMEXEC
33920 +       if (pax_find_mirror_vma(vma))
33921 +               BUG_ON(!trylock_page(page));
33922 +#endif
33923 +
33924         inc_mm_counter(mm, anon_rss);
33925         lru_cache_add_active(page);
33926         page_add_new_anon_rmap(page, vma, address);
33927 @@ -2388,6 +2596,11 @@ static int do_anonymous_page(struct mm_s
33928  
33929         /* No need to invalidate - it was non-present before */
33930         update_mmu_cache(vma, address, entry);
33931 +
33932 +#ifdef CONFIG_PAX_SEGMEXEC
33933 +       pax_mirror_anon_pte(vma, address, page, ptl);
33934 +#endif
33935 +
33936  unlock:
33937         pte_unmap_unlock(page_table, ptl);
33938         return 0;
33939 @@ -2516,6 +2729,12 @@ static int __do_fault(struct mm_struct *
33940          */
33941         /* Only go through if we didn't race with anybody else... */
33942         if (likely(pte_same(*page_table, orig_pte))) {
33943 +
33944 +#ifdef CONFIG_PAX_SEGMEXEC
33945 +               if (anon && pax_find_mirror_vma(vma))
33946 +                       BUG_ON(!trylock_page(page));
33947 +#endif
33948 +
33949                 flush_icache_page(vma, page);
33950                 entry = mk_pte(page, vma->vm_page_prot);
33951                 if (flags & FAULT_FLAG_WRITE)
33952 @@ -2536,6 +2755,14 @@ static int __do_fault(struct mm_struct *
33953  
33954                 /* no need to invalidate: a not-present page won't be cached */
33955                 update_mmu_cache(vma, address, entry);
33956 +
33957 +#ifdef CONFIG_PAX_SEGMEXEC
33958 +               if (anon)
33959 +                       pax_mirror_anon_pte(vma, address, page, ptl);
33960 +               else
33961 +                       pax_mirror_file_pte(vma, address, page, ptl);
33962 +#endif
33963 +
33964         } else {
33965                 mem_cgroup_uncharge_page(page);
33966                 if (anon)
33967 @@ -2668,6 +2895,12 @@ static inline int handle_pte_fault(struc
33968                 if (write_access)
33969                         flush_tlb_page(vma, address);
33970         }
33971 +
33972 +#ifdef CONFIG_PAX_SEGMEXEC
33973 +       pax_mirror_pte(vma, address, pte, pmd, ptl);
33974 +       return 0;
33975 +#endif
33976 +
33977  unlock:
33978         pte_unmap_unlock(pte, ptl);
33979         return 0;
33980 @@ -2684,6 +2917,10 @@ int handle_mm_fault(struct mm_struct *mm
33981         pmd_t *pmd;
33982         pte_t *pte;
33983  
33984 +#ifdef CONFIG_PAX_SEGMEXEC
33985 +       struct vm_area_struct *vma_m;
33986 +#endif
33987 +
33988         __set_current_state(TASK_RUNNING);
33989  
33990         count_vm_event(PGFAULT);
33991 @@ -2691,6 +2928,34 @@ int handle_mm_fault(struct mm_struct *mm
33992         if (unlikely(is_vm_hugetlb_page(vma)))
33993                 return hugetlb_fault(mm, vma, address, write_access);
33994  
33995 +#ifdef CONFIG_PAX_SEGMEXEC
33996 +       vma_m = pax_find_mirror_vma(vma);
33997 +       if (vma_m) {
33998 +               unsigned long address_m;
33999 +               pgd_t *pgd_m;
34000 +               pud_t *pud_m;
34001 +               pmd_t *pmd_m;
34002 +
34003 +               if (vma->vm_start > vma_m->vm_start) {
34004 +                       address_m = address;
34005 +                       address -= SEGMEXEC_TASK_SIZE;
34006 +                       vma = vma_m;
34007 +               } else
34008 +                       address_m = address + SEGMEXEC_TASK_SIZE;
34009 +
34010 +               pgd_m = pgd_offset(mm, address_m);
34011 +               pud_m = pud_alloc(mm, pgd_m, address_m);
34012 +               if (!pud_m)
34013 +                       return VM_FAULT_OOM;
34014 +               pmd_m = pmd_alloc(mm, pud_m, address_m);
34015 +               if (!pmd_m)
34016 +                       return VM_FAULT_OOM;
34017 +               if (!pmd_present(*pmd_m) && __pte_alloc(mm, pmd_m, address_m))
34018 +                       return VM_FAULT_OOM;
34019 +               pax_unmap_mirror_pte(vma_m, address_m, pmd_m);
34020 +       }
34021 +#endif
34022 +
34023         pgd = pgd_offset(mm, address);
34024         pud = pud_alloc(mm, pgd, address);
34025         if (!pud)
34026 @@ -2798,7 +3063,7 @@ static int __init gate_vma_init(void)
34027         gate_vma.vm_start = FIXADDR_USER_START;
34028         gate_vma.vm_end = FIXADDR_USER_END;
34029         gate_vma.vm_flags = VM_READ | VM_MAYREAD | VM_EXEC | VM_MAYEXEC;
34030 -       gate_vma.vm_page_prot = __P101;
34031 +       gate_vma.vm_page_prot = vm_get_page_prot(gate_vma.vm_flags);
34032         /*
34033          * Make sure the vDSO gets into every core dump.
34034          * Dumping its contents makes post-mortem fully interpretable later
34035 diff -urNp linux-2.6.27.10/mm/mempolicy.c linux-2.6.27.10/mm/mempolicy.c
34036 --- linux-2.6.27.10/mm/mempolicy.c      2008-11-07 12:55:34.000000000 -0500
34037 +++ linux-2.6.27.10/mm/mempolicy.c      2008-11-18 03:38:45.000000000 -0500
34038 @@ -555,6 +555,10 @@ static int mbind_range(struct vm_area_st
34039         struct vm_area_struct *next;
34040         int err;
34041  
34042 +#ifdef CONFIG_PAX_SEGMEXEC
34043 +       struct vm_area_struct *vma_m;
34044 +#endif
34045 +
34046         err = 0;
34047         for (; vma && vma->vm_start < end; vma = next) {
34048                 next = vma->vm_next;
34049 @@ -566,6 +570,16 @@ static int mbind_range(struct vm_area_st
34050                         err = policy_vma(vma, new);
34051                 if (err)
34052                         break;
34053 +
34054 +#ifdef CONFIG_PAX_SEGMEXEC
34055 +               vma_m = pax_find_mirror_vma(vma);
34056 +               if (vma_m) {
34057 +                       err = policy_vma(vma_m, new);
34058 +                       if (err)
34059 +                               break;
34060 +               }
34061 +#endif
34062 +
34063         }
34064         return err;
34065  }
34066 @@ -951,6 +965,17 @@ static long do_mbind(unsigned long start
34067  
34068         if (end < start)
34069                 return -EINVAL;
34070 +
34071 +#ifdef CONFIG_PAX_SEGMEXEC
34072 +       if (mm->pax_flags & MF_PAX_SEGMEXEC) {
34073 +               if (end > SEGMEXEC_TASK_SIZE)
34074 +                       return -EINVAL;
34075 +       } else
34076 +#endif
34077 +
34078 +       if (end > TASK_SIZE)
34079 +               return -EINVAL;
34080 +
34081         if (end == start)
34082                 return 0;
34083  
34084 diff -urNp linux-2.6.27.10/mm/mlock.c linux-2.6.27.10/mm/mlock.c
34085 --- linux-2.6.27.10/mm/mlock.c  2008-11-07 12:55:34.000000000 -0500
34086 +++ linux-2.6.27.10/mm/mlock.c  2008-11-18 03:38:45.000000000 -0500
34087 @@ -12,6 +12,7 @@
34088  #include <linux/sched.h>
34089  #include <linux/module.h>
34090  #include <linux/vs_memory.h>
34091 +#include <linux/grsecurity.h>
34092  
34093  int can_do_mlock(void)
34094  {
34095 @@ -93,6 +94,17 @@ static int do_mlock(unsigned long start,
34096                 return -EINVAL;
34097         if (end == start)
34098                 return 0;
34099 +
34100 +#ifdef CONFIG_PAX_SEGMEXEC
34101 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
34102 +               if (end > SEGMEXEC_TASK_SIZE)
34103 +                       return -EINVAL;
34104 +       } else
34105 +#endif
34106 +
34107 +       if (end > TASK_SIZE)
34108 +               return -EINVAL;
34109 +
34110         vma = find_vma_prev(current->mm, start, &prev);
34111         if (!vma || vma->vm_start > start)
34112                 return -ENOMEM;
34113 @@ -150,6 +162,7 @@ asmlinkage long sys_mlock(unsigned long 
34114         lock_limit >>= PAGE_SHIFT;
34115  
34116         /* check against resource limits */
34117 +       gr_learn_resource(current, RLIMIT_MEMLOCK, (current->mm->locked_vm << PAGE_SHIFT) + len, 1);
34118         if ((locked <= lock_limit) || capable(CAP_IPC_LOCK))
34119                 error = do_mlock(start, len, 1);
34120         up_write(&current->mm->mmap_sem);
34121 @@ -171,10 +184,10 @@ asmlinkage long sys_munlock(unsigned lon
34122  static int do_mlockall(int flags)
34123  {
34124         struct vm_area_struct * vma, * prev = NULL;
34125 -       unsigned int def_flags = 0;
34126 +       unsigned int def_flags = current->mm->def_flags & ~VM_LOCKED;
34127  
34128         if (flags & MCL_FUTURE)
34129 -               def_flags = VM_LOCKED;
34130 +               def_flags |= VM_LOCKED;
34131         current->mm->def_flags = def_flags;
34132         if (flags == MCL_FUTURE)
34133                 goto out;
34134 @@ -182,6 +195,12 @@ static int do_mlockall(int flags)
34135         for (vma = current->mm->mmap; vma ; vma = prev->vm_next) {
34136                 unsigned int newflags;
34137  
34138 +#ifdef CONFIG_PAX_SEGMEXEC
34139 +               if ((current->mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE))
34140 +                       break;
34141 +#endif
34142 +
34143 +               BUG_ON(vma->vm_end > TASK_SIZE);
34144                 newflags = vma->vm_flags | VM_LOCKED;
34145                 if (!(flags & MCL_CURRENT))
34146                         newflags &= ~VM_LOCKED;
34147 @@ -211,6 +230,7 @@ asmlinkage long sys_mlockall(int flags)
34148         lock_limit >>= PAGE_SHIFT;
34149  
34150         ret = -ENOMEM;
34151 +       gr_learn_resource(current, RLIMIT_MEMLOCK, current->mm->total_vm, 1);
34152         if (!vx_vmlocked_avail(current->mm, current->mm->total_vm))
34153                 goto out;
34154         if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) ||
34155 diff -urNp linux-2.6.27.10/mm/mmap.c linux-2.6.27.10/mm/mmap.c
34156 --- linux-2.6.27.10/mm/mmap.c   2008-11-07 12:55:34.000000000 -0500
34157 +++ linux-2.6.27.10/mm/mmap.c   2008-12-21 00:44:29.000000000 -0500
34158 @@ -27,6 +27,7 @@
34159  #include <linux/mempolicy.h>
34160  #include <linux/rmap.h>
34161  #include <linux/mmu_notifier.h>
34162 +#include <linux/grsecurity.h>
34163  
34164  #include <asm/uaccess.h>
34165  #include <asm/cacheflush.h>
34166 @@ -43,6 +44,16 @@
34167  #define arch_rebalance_pgtables(addr, len)             (addr)
34168  #endif
34169  
34170 +static inline void verify_mm_writelocked(struct mm_struct *mm)
34171 +{
34172 +#if defined(CONFIG_DEBUG_VM) || defined(CONFIG_PAX)
34173 +       if (unlikely(down_read_trylock(&mm->mmap_sem))) {
34174 +               up_read(&mm->mmap_sem);
34175 +               BUG();
34176 +       }
34177 +#endif
34178 +}
34179 +
34180  static void unmap_region(struct mm_struct *mm,
34181                 struct vm_area_struct *vma, struct vm_area_struct *prev,
34182                 unsigned long start, unsigned long end);
34183 @@ -68,16 +79,25 @@ static void unmap_region(struct mm_struc
34184   *             x: (no) no      x: (no) yes     x: (no) yes     x: (yes) yes
34185   *
34186   */
34187 -pgprot_t protection_map[16] = {
34188 +pgprot_t protection_map[16] __read_only = {
34189         __P000, __P001, __P010, __P011, __P100, __P101, __P110, __P111,
34190         __S000, __S001, __S010, __S011, __S100, __S101, __S110, __S111
34191  };
34192  
34193  pgprot_t vm_get_page_prot(unsigned long vm_flags)
34194  {
34195 -       return __pgprot(pgprot_val(protection_map[vm_flags &
34196 +       pgprot_t prot = __pgprot(pgprot_val(protection_map[vm_flags &
34197                                 (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]) |
34198                         pgprot_val(arch_vm_get_page_prot(vm_flags)));
34199 +
34200 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34201 +       if (!nx_enabled &&
34202 +           (vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC &&
34203 +           (vm_flags & (VM_READ | VM_WRITE)))
34204 +               prot = __pgprot(pte_val(pte_exprotect(__pte(pgprot_val(prot)))));
34205 +#endif
34206 +
34207 +       return prot;
34208  }
34209  EXPORT_SYMBOL(vm_get_page_prot);
34210  
34211 @@ -232,6 +252,7 @@ static struct vm_area_struct *remove_vma
34212         struct vm_area_struct *next = vma->vm_next;
34213  
34214         might_sleep();
34215 +       BUG_ON(vma->vm_mirror);
34216         if (vma->vm_ops && vma->vm_ops->close)
34217                 vma->vm_ops->close(vma);
34218         if (vma->vm_file) {
34219 @@ -268,6 +289,7 @@ asmlinkage unsigned long sys_brk(unsigne
34220          * not page aligned -Ram Gupta
34221          */
34222         rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
34223 +       gr_learn_resource(current, RLIMIT_DATA, (brk - mm->start_brk) + (mm->end_data - mm->start_data), 1);
34224         if (rlim < RLIM_INFINITY && (brk - mm->start_brk) +
34225                         (mm->end_data - mm->start_data) > rlim)
34226                 goto out;
34227 @@ -697,6 +719,12 @@ static int
34228  can_vma_merge_before(struct vm_area_struct *vma, unsigned long vm_flags,
34229         struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34230  {
34231 +
34232 +#ifdef CONFIG_PAX_SEGMEXEC
34233 +       if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_start == SEGMEXEC_TASK_SIZE)
34234 +               return 0;
34235 +#endif
34236 +
34237         if (is_mergeable_vma(vma, file, vm_flags) &&
34238             is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34239                 if (vma->vm_pgoff == vm_pgoff)
34240 @@ -716,6 +744,12 @@ static int
34241  can_vma_merge_after(struct vm_area_struct *vma, unsigned long vm_flags,
34242         struct anon_vma *anon_vma, struct file *file, pgoff_t vm_pgoff)
34243  {
34244 +
34245 +#ifdef CONFIG_PAX_SEGMEXEC
34246 +       if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end == SEGMEXEC_TASK_SIZE)
34247 +               return 0;
34248 +#endif
34249 +
34250         if (is_mergeable_vma(vma, file, vm_flags) &&
34251             is_mergeable_anon_vma(anon_vma, vma->anon_vma)) {
34252                 pgoff_t vm_pglen;
34253 @@ -758,12 +792,19 @@ can_vma_merge_after(struct vm_area_struc
34254  struct vm_area_struct *vma_merge(struct mm_struct *mm,
34255                         struct vm_area_struct *prev, unsigned long addr,
34256                         unsigned long end, unsigned long vm_flags,
34257 -                       struct anon_vma *anon_vma, struct file *file,
34258 +                       struct anon_vma *anon_vma, struct file *file,
34259                         pgoff_t pgoff, struct mempolicy *policy)
34260  {
34261         pgoff_t pglen = (end - addr) >> PAGE_SHIFT;
34262         struct vm_area_struct *area, *next;
34263  
34264 +#ifdef CONFIG_PAX_SEGMEXEC
34265 +       unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE, end_m = end + SEGMEXEC_TASK_SIZE;
34266 +       struct vm_area_struct *area_m = NULL, *next_m = NULL, *prev_m = NULL;
34267 +
34268 +       BUG_ON((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE < end);
34269 +#endif
34270 +
34271         /*
34272          * We later require that vma->vm_flags == vm_flags,
34273          * so this tests vma->vm_flags & VM_SPECIAL, too.
34274 @@ -779,6 +820,15 @@ struct vm_area_struct *vma_merge(struct 
34275         if (next && next->vm_end == end)                /* cases 6, 7, 8 */
34276                 next = next->vm_next;
34277  
34278 +#ifdef CONFIG_PAX_SEGMEXEC
34279 +       if (prev)
34280 +               prev_m = pax_find_mirror_vma(prev);
34281 +       if (area)
34282 +               area_m = pax_find_mirror_vma(area);
34283 +       if (next)
34284 +               next_m = pax_find_mirror_vma(next);
34285 +#endif
34286 +
34287         /*
34288          * Can it merge with the predecessor?
34289          */
34290 @@ -798,9 +848,24 @@ struct vm_area_struct *vma_merge(struct 
34291                                                         /* cases 1, 6 */
34292                         vma_adjust(prev, prev->vm_start,
34293                                 next->vm_end, prev->vm_pgoff, NULL);
34294 -               } else                                  /* cases 2, 5, 7 */
34295 +
34296 +#ifdef CONFIG_PAX_SEGMEXEC
34297 +                       if (prev_m)
34298 +                               vma_adjust(prev_m, prev_m->vm_start,
34299 +                                       next_m->vm_end, prev_m->vm_pgoff, NULL);
34300 +#endif
34301 +
34302 +               } else {                                /* cases 2, 5, 7 */
34303                         vma_adjust(prev, prev->vm_start,
34304                                 end, prev->vm_pgoff, NULL);
34305 +
34306 +#ifdef CONFIG_PAX_SEGMEXEC
34307 +                       if (prev_m)
34308 +                               vma_adjust(prev_m, prev_m->vm_start,
34309 +                                       end_m, prev_m->vm_pgoff, NULL);
34310 +#endif
34311 +
34312 +               }
34313                 return prev;
34314         }
34315  
34316 @@ -811,12 +876,27 @@ struct vm_area_struct *vma_merge(struct 
34317                         mpol_equal(policy, vma_policy(next)) &&
34318                         can_vma_merge_before(next, vm_flags,
34319                                         anon_vma, file, pgoff+pglen)) {
34320 -               if (prev && addr < prev->vm_end)        /* case 4 */
34321 +               if (prev && addr < prev->vm_end) {      /* case 4 */
34322                         vma_adjust(prev, prev->vm_start,
34323                                 addr, prev->vm_pgoff, NULL);
34324 -               else                                    /* cases 3, 8 */
34325 +
34326 +#ifdef CONFIG_PAX_SEGMEXEC
34327 +                       if (prev_m)
34328 +                               vma_adjust(prev_m, prev_m->vm_start,
34329 +                                       addr_m, prev_m->vm_pgoff, NULL);
34330 +#endif
34331 +
34332 +               } else {                                /* cases 3, 8 */
34333                         vma_adjust(area, addr, next->vm_end,
34334                                 next->vm_pgoff - pglen, NULL);
34335 +
34336 +#ifdef CONFIG_PAX_SEGMEXEC
34337 +                       if (area_m)
34338 +                               vma_adjust(area_m, addr_m, next_m->vm_end,
34339 +                                       next_m->vm_pgoff - pglen, NULL);
34340 +#endif
34341 +
34342 +               }
34343                 return area;
34344         }
34345  
34346 @@ -891,14 +971,11 @@ none:
34347  void vm_stat_account(struct mm_struct *mm, unsigned long flags,
34348                                                 struct file *file, long pages)
34349  {
34350 -       const unsigned long stack_flags
34351 -               = VM_STACK_FLAGS & (VM_GROWSUP|VM_GROWSDOWN);
34352 -
34353         if (file) {
34354                 mm->shared_vm += pages;
34355                 if ((flags & (VM_EXEC|VM_WRITE)) == VM_EXEC)
34356                         mm->exec_vm += pages;
34357 -       } else if (flags & stack_flags)
34358 +       } else if (flags & (VM_GROWSUP|VM_GROWSDOWN))
34359                 mm->stack_vm += pages;
34360         if (flags & (VM_RESERVED|VM_IO))
34361                 mm->reserved_vm += pages;
34362 @@ -926,7 +1003,7 @@ unsigned long do_mmap_pgoff(struct file 
34363          * (the exception is when the underlying filesystem is noexec
34364          *  mounted, in which case we dont add PROT_EXEC.)
34365          */
34366 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
34367 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
34368                 if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
34369                         prot |= PROT_EXEC;
34370  
34371 @@ -936,15 +1013,15 @@ unsigned long do_mmap_pgoff(struct file 
34372         if (!(flags & MAP_FIXED))
34373                 addr = round_hint_to_min(addr);
34374  
34375 -       error = arch_mmap_check(addr, len, flags);
34376 -       if (error)
34377 -               return error;
34378 -
34379         /* Careful about overflows.. */
34380         len = PAGE_ALIGN(len);
34381         if (!len || len > TASK_SIZE)
34382                 return -ENOMEM;
34383  
34384 +       error = arch_mmap_check(addr, len, flags);
34385 +       if (error)
34386 +               return error;
34387 +
34388         /* offset overflow? */
34389         if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
34390                 return -EOVERFLOW;
34391 @@ -956,7 +1033,7 @@ unsigned long do_mmap_pgoff(struct file 
34392         /* Obtain the address to map to. we verify (or select) it and ensure
34393          * that it represents a valid section of the address space.
34394          */
34395 -       addr = get_unmapped_area(file, addr, len, pgoff, flags);
34396 +       addr = get_unmapped_area(file, addr, len, pgoff, flags | ((prot & PROT_EXEC) ? MAP_EXECUTABLE : 0));
34397         if (addr & ~PAGE_MASK)
34398                 return addr;
34399  
34400 @@ -967,6 +1044,26 @@ unsigned long do_mmap_pgoff(struct file 
34401         vm_flags = calc_vm_prot_bits(prot) | calc_vm_flag_bits(flags) |
34402                         mm->def_flags | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC;
34403  
34404 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
34405 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
34406 +
34407 +#ifdef CONFIG_PAX_MPROTECT
34408 +               if (mm->pax_flags & MF_PAX_MPROTECT) {
34409 +                       if ((prot & (PROT_WRITE | PROT_EXEC)) != PROT_EXEC)
34410 +                               vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
34411 +                       else
34412 +                               vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
34413 +               }
34414 +#endif
34415 +
34416 +       }
34417 +#endif
34418 +
34419 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34420 +       if ((mm->pax_flags & MF_PAX_PAGEEXEC) && file)
34421 +               vm_flags &= ~VM_PAGEEXEC;
34422 +#endif
34423 +
34424         if (flags & MAP_LOCKED) {
34425                 if (!can_do_mlock())
34426                         return -EPERM;
34427 @@ -979,6 +1076,7 @@ unsigned long do_mmap_pgoff(struct file 
34428                 locked += mm->locked_vm;
34429                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
34430                 lock_limit >>= PAGE_SHIFT;
34431 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34432                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
34433                         return -EAGAIN;
34434         }
34435 @@ -1051,6 +1149,9 @@ unsigned long do_mmap_pgoff(struct file 
34436         if (error)
34437                 return error;
34438  
34439 +       if (!gr_acl_handle_mmap(file, prot))
34440 +               return -EACCES;
34441 +
34442         return mmap_region(file, addr, len, flags, vm_flags, pgoff,
34443                            accountable);
34444  }
34445 @@ -1064,10 +1165,10 @@ EXPORT_SYMBOL(do_mmap_pgoff);
34446   */
34447  int vma_wants_writenotify(struct vm_area_struct *vma)
34448  {
34449 -       unsigned int vm_flags = vma->vm_flags;
34450 +       unsigned long vm_flags = vma->vm_flags;
34451  
34452         /* If it was private or non-writable, the write bit is already clear */
34453 -       if ((vm_flags & (VM_WRITE|VM_SHARED)) != ((VM_WRITE|VM_SHARED)))
34454 +       if ((vm_flags & (VM_WRITE|VM_SHARED)) != (VM_WRITE|VM_SHARED))
34455                 return 0;
34456  
34457         /* The backer wishes to know when pages are first written to? */
34458 @@ -1101,14 +1202,24 @@ unsigned long mmap_region(struct file *f
34459         unsigned long charged = 0;
34460         struct inode *inode =  file ? file->f_path.dentry->d_inode : NULL;
34461  
34462 +#ifdef CONFIG_PAX_SEGMEXEC
34463 +       struct vm_area_struct *vma_m = NULL;
34464 +#endif
34465 +
34466 +       /*
34467 +        * mm->mmap_sem is required to protect against another thread
34468 +        * changing the mappings in case we sleep.
34469 +        */
34470 +       verify_mm_writelocked(mm);
34471 +
34472         /* Clear old maps */
34473         error = -ENOMEM;
34474 -munmap_back:
34475         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34476         if (vma && vma->vm_start < addr + len) {
34477                 if (do_munmap(mm, addr, len))
34478                         return -ENOMEM;
34479 -               goto munmap_back;
34480 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
34481 +               BUG_ON(vma && vma->vm_start < addr + len);
34482         }
34483  
34484         /* Check against address space limit. */
34485 @@ -1155,6 +1266,16 @@ munmap_back:
34486                 goto unacct_error;
34487         }
34488  
34489 +#ifdef CONFIG_PAX_SEGMEXEC
34490 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vm_flags & VM_EXEC)) {
34491 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
34492 +               if (!vma_m) {
34493 +                       error = -ENOMEM;
34494 +                       goto free_vma;
34495 +               }
34496 +       }
34497 +#endif
34498 +
34499         vma->vm_mm = mm;
34500         vma->vm_start = addr;
34501         vma->vm_end = addr + len;
34502 @@ -1177,6 +1298,19 @@ munmap_back:
34503                 error = file->f_op->mmap(file, vma);
34504                 if (error)
34505                         goto unmap_and_free_vma;
34506 +
34507 +#ifdef CONFIG_PAX_SEGMEXEC
34508 +               if (vma_m && (vm_flags & VM_EXECUTABLE))
34509 +                       added_exe_file_vma(mm);
34510 +#endif
34511 +
34512 +#if defined(CONFIG_PAX_PAGEEXEC) && defined(CONFIG_X86_32)
34513 +               if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(vma->vm_flags & VM_SPECIAL)) {
34514 +                       vma->vm_flags |= VM_PAGEEXEC;
34515 +                       vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
34516 +               }
34517 +#endif
34518 +
34519                 if (vm_flags & VM_EXECUTABLE)
34520                         added_exe_file_vma(mm);
34521         } else if (vm_flags & VM_SHARED) {
34522 @@ -1209,12 +1343,29 @@ munmap_back:
34523                         vma->vm_flags, NULL, file, pgoff, vma_policy(vma))) {
34524                 mpol_put(vma_policy(vma));
34525                 kmem_cache_free(vm_area_cachep, vma);
34526 +               vma = NULL;
34527                 fput(file);
34528 +
34529 +#ifdef CONFIG_PAX_SEGMEXEC
34530 +               if (vma_m) {
34531 +                       kmem_cache_free(vm_area_cachep, vma_m);
34532 +
34533 +                       if (vm_flags & VM_EXECUTABLE)
34534 +                               removed_exe_file_vma(mm);
34535 +               }
34536 +#endif
34537 +
34538                 if (vm_flags & VM_EXECUTABLE)
34539                         removed_exe_file_vma(mm);
34540         } else {
34541                 vma_link(mm, vma, prev, rb_link, rb_parent);
34542                 file = vma->vm_file;
34543 +
34544 +#ifdef CONFIG_PAX_SEGMEXEC
34545 +               if (vma_m)
34546 +                       pax_mirror_vma(vma_m, vma);
34547 +#endif
34548 +
34549         }
34550  
34551         /* Once vma denies write, undo our temporary denial count */
34552 @@ -1223,6 +1374,7 @@ munmap_back:
34553  out:
34554         mm->total_vm += len >> PAGE_SHIFT;
34555         vm_stat_account(mm, vm_flags, file, len >> PAGE_SHIFT);
34556 +       track_exec_limit(mm, addr, addr + len, vm_flags);
34557         if (vm_flags & VM_LOCKED) {
34558                 mm->locked_vm += len >> PAGE_SHIFT;
34559                 make_pages_present(addr, addr + len);
34560 @@ -1241,6 +1393,12 @@ unmap_and_free_vma:
34561         unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end);
34562         charged = 0;
34563  free_vma:
34564 +
34565 +#ifdef CONFIG_PAX_SEGMEXEC
34566 +       if (vma_m)
34567 +               kmem_cache_free(vm_area_cachep, vma_m);
34568 +#endif
34569 +
34570         kmem_cache_free(vm_area_cachep, vma);
34571  unacct_error:
34572         if (charged)
34573 @@ -1274,6 +1432,10 @@ arch_get_unmapped_area(struct file *filp
34574         if (flags & MAP_FIXED)
34575                 return addr;
34576  
34577 +#ifdef CONFIG_PAX_RANDMMAP
34578 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34579 +#endif
34580 +
34581         if (addr) {
34582                 addr = PAGE_ALIGN(addr);
34583                 vma = find_vma(mm, addr);
34584 @@ -1282,10 +1444,10 @@ arch_get_unmapped_area(struct file *filp
34585                         return addr;
34586         }
34587         if (len > mm->cached_hole_size) {
34588 -               start_addr = addr = mm->free_area_cache;
34589 +               start_addr = addr = mm->free_area_cache;
34590         } else {
34591 -               start_addr = addr = TASK_UNMAPPED_BASE;
34592 -               mm->cached_hole_size = 0;
34593 +               start_addr = addr = mm->mmap_base;
34594 +               mm->cached_hole_size = 0;
34595         }
34596  
34597  full_search:
34598 @@ -1296,9 +1458,8 @@ full_search:
34599                          * Start a new search - just in case we missed
34600                          * some holes.
34601                          */
34602 -                       if (start_addr != TASK_UNMAPPED_BASE) {
34603 -                               addr = TASK_UNMAPPED_BASE;
34604 -                               start_addr = addr;
34605 +                       if (start_addr != mm->mmap_base) {
34606 +                               start_addr = addr = mm->mmap_base;
34607                                 mm->cached_hole_size = 0;
34608                                 goto full_search;
34609                         }
34610 @@ -1320,10 +1481,16 @@ full_search:
34611  
34612  void arch_unmap_area(struct mm_struct *mm, unsigned long addr)
34613  {
34614 +
34615 +#ifdef CONFIG_PAX_SEGMEXEC
34616 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34617 +               return;
34618 +#endif
34619 +
34620         /*
34621          * Is this a new hole at the lowest possible address?
34622          */
34623 -       if (addr >= TASK_UNMAPPED_BASE && addr < mm->free_area_cache) {
34624 +       if (addr >= mm->mmap_base && addr < mm->free_area_cache) {
34625                 mm->free_area_cache = addr;
34626                 mm->cached_hole_size = ~0UL;
34627         }
34628 @@ -1341,7 +1508,7 @@ arch_get_unmapped_area_topdown(struct fi
34629  {
34630         struct vm_area_struct *vma;
34631         struct mm_struct *mm = current->mm;
34632 -       unsigned long addr = addr0;
34633 +       unsigned long base = mm->mmap_base, addr = addr0;
34634  
34635         /* requested length too big for entire address space */
34636         if (len > TASK_SIZE)
34637 @@ -1350,6 +1517,10 @@ arch_get_unmapped_area_topdown(struct fi
34638         if (flags & MAP_FIXED)
34639                 return addr;
34640  
34641 +#ifdef CONFIG_PAX_RANDMMAP
34642 +       if (!(mm->pax_flags & MF_PAX_RANDMMAP))
34643 +#endif
34644 +
34645         /* requesting a specific address */
34646         if (addr) {
34647                 addr = PAGE_ALIGN(addr);
34648 @@ -1407,13 +1578,21 @@ bottomup:
34649          * can happen with large stack limits and large mmap()
34650          * allocations.
34651          */
34652 +       mm->mmap_base = TASK_UNMAPPED_BASE;
34653 +
34654 +#ifdef CONFIG_PAX_RANDMMAP
34655 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
34656 +               mm->mmap_base += mm->delta_mmap;
34657 +#endif
34658 +
34659 +       mm->free_area_cache = mm->mmap_base;
34660         mm->cached_hole_size = ~0UL;
34661 -       mm->free_area_cache = TASK_UNMAPPED_BASE;
34662         addr = arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
34663         /*
34664          * Restore the topdown base:
34665          */
34666 -       mm->free_area_cache = mm->mmap_base;
34667 +       mm->mmap_base = base;
34668 +       mm->free_area_cache = base;
34669         mm->cached_hole_size = ~0UL;
34670  
34671         return addr;
34672 @@ -1422,6 +1601,12 @@ bottomup:
34673  
34674  void arch_unmap_area_topdown(struct mm_struct *mm, unsigned long addr)
34675  {
34676 +
34677 +#ifdef CONFIG_PAX_SEGMEXEC
34678 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && SEGMEXEC_TASK_SIZE <= addr)
34679 +               return;
34680 +#endif
34681 +
34682         /*
34683          * Is this a new hole at the highest possible address?
34684          */
34685 @@ -1429,8 +1614,10 @@ void arch_unmap_area_topdown(struct mm_s
34686                 mm->free_area_cache = addr;
34687  
34688         /* dont allow allocations above current base */
34689 -       if (mm->free_area_cache > mm->mmap_base)
34690 +       if (mm->free_area_cache > mm->mmap_base) {
34691                 mm->free_area_cache = mm->mmap_base;
34692 +               mm->cached_hole_size = ~0UL;
34693 +       }
34694  }
34695  
34696  unsigned long
34697 @@ -1530,6 +1717,27 @@ out:
34698         return prev ? prev->vm_next : vma;
34699  }
34700  
34701 +#ifdef CONFIG_PAX_SEGMEXEC
34702 +struct vm_area_struct *pax_find_mirror_vma(struct vm_area_struct *vma)
34703 +{
34704 +       struct vm_area_struct *vma_m;
34705 +
34706 +       BUG_ON(!vma || vma->vm_start >= vma->vm_end);
34707 +       if (!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC)) {
34708 +               BUG_ON(vma->vm_mirror);
34709 +               return NULL;
34710 +       }
34711 +       BUG_ON(vma->vm_start < SEGMEXEC_TASK_SIZE && SEGMEXEC_TASK_SIZE < vma->vm_end);
34712 +       vma_m = vma->vm_mirror;
34713 +       BUG_ON(!vma_m || vma_m->vm_mirror != vma);
34714 +       BUG_ON(vma->vm_file != vma_m->vm_file);
34715 +       BUG_ON(vma->vm_end - vma->vm_start != vma_m->vm_end - vma_m->vm_start);
34716 +       BUG_ON(vma->vm_pgoff != vma_m->vm_pgoff || vma->anon_vma != vma_m->anon_vma);
34717 +       BUG_ON((vma->vm_flags ^ vma_m->vm_flags) & ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED));
34718 +       return vma_m;
34719 +}
34720 +#endif
34721 +
34722  /*
34723   * Verify that the stack growth is acceptable and
34724   * update accounting. This is shared with both the
34725 @@ -1546,6 +1754,7 @@ static int acct_stack_growth(struct vm_a
34726                 return -ENOMEM;
34727  
34728         /* Stack limit test */
34729 +       gr_learn_resource(current, RLIMIT_STACK, size, 1);
34730         if (size > rlim[RLIMIT_STACK].rlim_cur)
34731                 return -ENOMEM;
34732  
34733 @@ -1555,6 +1764,7 @@ static int acct_stack_growth(struct vm_a
34734                 unsigned long limit;
34735                 locked = mm->locked_vm + grow;
34736                 limit = rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
34737 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
34738                 if (locked > limit && !capable(CAP_IPC_LOCK))
34739                         return -ENOMEM;
34740         }
34741 @@ -1569,7 +1779,7 @@ static int acct_stack_growth(struct vm_a
34742          * Overcommit..  This must be the final test, as it will
34743          * update security statistics.
34744          */
34745 -       if (security_vm_enough_memory(grow))
34746 +       if (security_vm_enough_memory_mm(mm, grow))
34747                 return -ENOMEM;
34748  
34749         /* Ok, everything looks good - let it rip */
34750 @@ -1590,35 +1800,40 @@ static inline
34751  #endif
34752  int expand_upwards(struct vm_area_struct *vma, unsigned long address)
34753  {
34754 -       int error;
34755 +       int error, locknext;
34756  
34757         if (!(vma->vm_flags & VM_GROWSUP))
34758                 return -EFAULT;
34759  
34760 +       /* Also guard against wrapping around to address 0. */
34761 +       if (address < PAGE_ALIGN(address+1))
34762 +               address = PAGE_ALIGN(address+1);
34763 +       else
34764 +               return -ENOMEM;
34765 +
34766         /*
34767          * We must make sure the anon_vma is allocated
34768          * so that the anon_vma locking is not a noop.
34769          */
34770         if (unlikely(anon_vma_prepare(vma)))
34771                 return -ENOMEM;
34772 +       locknext = vma->vm_next && (vma->vm_next->vm_flags & VM_GROWSDOWN);
34773 +       if (locknext && unlikely(anon_vma_prepare(vma->vm_next)))
34774 +               return -ENOMEM;
34775         anon_vma_lock(vma);
34776 +       if (locknext)
34777 +               anon_vma_lock(vma->vm_next);
34778  
34779         /*
34780          * vma->vm_start/vm_end cannot change under us because the caller
34781          * is required to hold the mmap_sem in read mode.  We need the
34782 -        * anon_vma lock to serialize against concurrent expand_stacks.
34783 -        * Also guard against wrapping around to address 0.
34784 +        * anon_vma locks to serialize against concurrent expand_stacks
34785 +        * and expand_upwards.
34786          */
34787 -       if (address < PAGE_ALIGN(address+4))
34788 -               address = PAGE_ALIGN(address+4);
34789 -       else {
34790 -               anon_vma_unlock(vma);
34791 -               return -ENOMEM;
34792 -       }
34793         error = 0;
34794  
34795         /* Somebody else might have raced and expanded it already */
34796 -       if (address > vma->vm_end) {
34797 +       if (address > vma->vm_end && (!locknext || vma->vm_next->vm_start >= address)) {
34798                 unsigned long size, grow;
34799  
34800                 size = address - vma->vm_start;
34801 @@ -1628,6 +1843,8 @@ int expand_upwards(struct vm_area_struct
34802                 if (!error)
34803                         vma->vm_end = address;
34804         }
34805 +       if (locknext)
34806 +               anon_vma_unlock(vma->vm_next);
34807         anon_vma_unlock(vma);
34808         return error;
34809  }
34810 @@ -1639,7 +1856,8 @@ int expand_upwards(struct vm_area_struct
34811  static inline int expand_downwards(struct vm_area_struct *vma,
34812                                    unsigned long address)
34813  {
34814 -       int error;
34815 +       int error, lockprev = 0;
34816 +       struct vm_area_struct *prev = NULL;
34817  
34818         /*
34819          * We must make sure the anon_vma is allocated
34820 @@ -1653,6 +1871,15 @@ static inline int expand_downwards(struc
34821         if (error)
34822                 return error;
34823  
34824 +#if defined(CONFIG_STACK_GROWSUP) || defined(CONFIG_IA64)
34825 +       find_vma_prev(vma->vm_mm, address, &prev);
34826 +       lockprev = prev && (prev->vm_flags & VM_GROWSUP);
34827 +#endif
34828 +       if (lockprev && unlikely(anon_vma_prepare(prev)))
34829 +               return -ENOMEM;
34830 +       if (lockprev)
34831 +               anon_vma_lock(prev);
34832 +
34833         anon_vma_lock(vma);
34834  
34835         /*
34836 @@ -1662,9 +1889,15 @@ static inline int expand_downwards(struc
34837          */
34838  
34839         /* Somebody else might have raced and expanded it already */
34840 -       if (address < vma->vm_start) {
34841 +       if (address < vma->vm_start && (!lockprev || prev->vm_end <= address)) {
34842                 unsigned long size, grow;
34843  
34844 +#ifdef CONFIG_PAX_SEGMEXEC
34845 +               struct vm_area_struct *vma_m;
34846 +
34847 +               vma_m = pax_find_mirror_vma(vma);
34848 +#endif
34849 +
34850                 size = vma->vm_end - address;
34851                 grow = (vma->vm_start - address) >> PAGE_SHIFT;
34852  
34853 @@ -1672,9 +1905,20 @@ static inline int expand_downwards(struc
34854                 if (!error) {
34855                         vma->vm_start = address;
34856                         vma->vm_pgoff -= grow;
34857 +                       track_exec_limit(vma->vm_mm, vma->vm_start, vma->vm_end, vma->vm_flags);
34858 +
34859 +#ifdef CONFIG_PAX_SEGMEXEC
34860 +                       if (vma_m) {
34861 +                               vma_m->vm_start -= grow << PAGE_SHIFT;
34862 +                               vma_m->vm_pgoff -= grow;
34863 +                       }
34864 +#endif
34865 +
34866                 }
34867         }
34868         anon_vma_unlock(vma);
34869 +       if (lockprev)
34870 +               anon_vma_unlock(prev);
34871         return error;
34872  }
34873  
34874 @@ -1746,6 +1990,13 @@ static void remove_vma_list(struct mm_st
34875         do {
34876                 long nrpages = vma_pages(vma);
34877  
34878 +#ifdef CONFIG_PAX_SEGMEXEC
34879 +               if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_start >= SEGMEXEC_TASK_SIZE)) {
34880 +                       vma = remove_vma(vma);
34881 +                       continue;
34882 +               }
34883 +#endif
34884 +
34885                 vx_vmpages_sub(mm, nrpages);
34886                 if (vma->vm_flags & VM_LOCKED)
34887                         mm->locked_vm -= nrpages;
34888 @@ -1792,6 +2043,16 @@ detach_vmas_to_be_unmapped(struct mm_str
34889  
34890         insertion_point = (prev ? &prev->vm_next : &mm->mmap);
34891         do {
34892 +
34893 +#ifdef CONFIG_PAX_SEGMEXEC
34894 +               if (vma->vm_mirror) {
34895 +                       BUG_ON(!vma->vm_mirror->vm_mirror || vma->vm_mirror->vm_mirror != vma);
34896 +                       vma->vm_mirror->vm_mirror = NULL;
34897 +                       vma->vm_mirror->vm_flags &= ~VM_EXEC;
34898 +                       vma->vm_mirror = NULL;
34899 +               }
34900 +#endif
34901 +
34902                 rb_erase(&vma->vm_rb, &mm->mm_rb);
34903                 mm->map_count--;
34904                 tail_vma = vma;
34905 @@ -1811,6 +2072,108 @@ detach_vmas_to_be_unmapped(struct mm_str
34906   * Split a vma into two pieces at address 'addr', a new vma is allocated
34907   * either for the first part or the tail.
34908   */
34909 +
34910 +#ifdef CONFIG_PAX_SEGMEXEC
34911 +int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
34912 +             unsigned long addr, int new_below)
34913 +{
34914 +       struct mempolicy *pol;
34915 +       struct vm_area_struct *new, *vma_m, *new_m = NULL;
34916 +       unsigned long addr_m = addr + SEGMEXEC_TASK_SIZE;
34917 +
34918 +       if (is_vm_hugetlb_page(vma) && (addr & ~HPAGE_MASK))
34919 +               return -EINVAL;
34920 +
34921 +       vma_m = pax_find_mirror_vma(vma);
34922 +       if (vma_m) {
34923 +               BUG_ON(vma->vm_end > SEGMEXEC_TASK_SIZE);
34924 +               if (mm->map_count >= sysctl_max_map_count-1)
34925 +                       return -ENOMEM;
34926 +       } else if (mm->map_count >= sysctl_max_map_count)
34927 +               return -ENOMEM;
34928 +
34929 +       new = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34930 +       if (!new)
34931 +               return -ENOMEM;
34932 +
34933 +       if (vma_m) {
34934 +               new_m = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
34935 +               if (!new_m) {
34936 +                       kmem_cache_free(vm_area_cachep, new);
34937 +                       return -ENOMEM;
34938 +               }
34939 +       }
34940 +
34941 +       /* most fields are the same, copy all, and then fixup */
34942 +       *new = *vma;
34943 +
34944 +       if (new_below)
34945 +               new->vm_end = addr;
34946 +       else {
34947 +               new->vm_start = addr;
34948 +               new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT);
34949 +       }
34950 +
34951 +       if (vma_m) {
34952 +               *new_m = *vma_m;
34953 +               new_m->vm_mirror = new;
34954 +               new->vm_mirror = new_m;
34955 +
34956 +               if (new_below)
34957 +                       new_m->vm_end = addr_m;
34958 +               else {
34959 +                       new_m->vm_start = addr_m;
34960 +                       new_m->vm_pgoff += ((addr_m - vma_m->vm_start) >> PAGE_SHIFT);
34961 +               }
34962 +       }
34963 +
34964 +       pol = mpol_dup(vma_policy(vma));
34965 +       if (IS_ERR(pol)) {
34966 +               if (new_m)
34967 +                       kmem_cache_free(vm_area_cachep, new_m);
34968 +               kmem_cache_free(vm_area_cachep, new);
34969 +               return PTR_ERR(pol);
34970 +       }
34971 +       vma_set_policy(new, pol);
34972 +
34973 +       if (new->vm_file) {
34974 +               get_file(new->vm_file);
34975 +               if (vma->vm_flags & VM_EXECUTABLE)
34976 +                       added_exe_file_vma(mm);
34977 +       }
34978 +
34979 +       if (new->vm_ops && new->vm_ops->open)
34980 +               new->vm_ops->open(new);
34981 +
34982 +       if (new_below)
34983 +               vma_adjust(vma, addr, vma->vm_end, vma->vm_pgoff +
34984 +                       ((addr - new->vm_start) >> PAGE_SHIFT), new);
34985 +       else
34986 +               vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
34987 +
34988 +       if (vma_m) {
34989 +               mpol_get(pol);
34990 +               vma_set_policy(new_m, pol);
34991 +
34992 +               if (new_m->vm_file) {
34993 +                       get_file(new_m->vm_file);
34994 +                       if (vma_m->vm_flags & VM_EXECUTABLE)
34995 +                               added_exe_file_vma(mm);
34996 +               }
34997 +
34998 +               if (new_m->vm_ops && new_m->vm_ops->open)
34999 +                       new_m->vm_ops->open(new_m);
35000 +
35001 +               if (new_below)
35002 +                       vma_adjust(vma_m, addr_m, vma_m->vm_end, vma_m->vm_pgoff +
35003 +                               ((addr_m - new_m->vm_start) >> PAGE_SHIFT), new_m);
35004 +               else
35005 +                       vma_adjust(vma_m, vma_m->vm_start, addr_m, vma_m->vm_pgoff, new_m);
35006 +       }
35007 +
35008 +       return 0;
35009 +}
35010 +#else
35011  int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
35012               unsigned long addr, int new_below)
35013  {
35014 @@ -1862,17 +2225,37 @@ int split_vma(struct mm_struct * mm, str
35015  
35016         return 0;
35017  }
35018 +#endif
35019  
35020  /* Munmap is split into 2 main parts -- this part which finds
35021   * what needs doing, and the areas themselves, which do the
35022   * work.  This now handles partial unmappings.
35023   * Jeremy Fitzhardinge <jeremy@goop.org>
35024   */
35025 +#ifdef CONFIG_PAX_SEGMEXEC
35026  int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35027  {
35028 +       int ret = __do_munmap(mm, start, len);
35029 +       if (ret || !(mm->pax_flags & MF_PAX_SEGMEXEC))
35030 +               return ret;
35031 +
35032 +       return __do_munmap(mm, start + SEGMEXEC_TASK_SIZE, len);
35033 +}
35034 +
35035 +int __do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35036 +#else
35037 +int do_munmap(struct mm_struct *mm, unsigned long start, size_t len)
35038 +#endif
35039 +{
35040         unsigned long end;
35041         struct vm_area_struct *vma, *prev, *last;
35042  
35043 +       /*
35044 +        * mm->mmap_sem is required to protect against another thread
35045 +        * changing the mappings in case we sleep.
35046 +        */
35047 +       verify_mm_writelocked(mm);
35048 +
35049         if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start)
35050                 return -EINVAL;
35051  
35052 @@ -1922,6 +2305,8 @@ int do_munmap(struct mm_struct *mm, unsi
35053         /* Fix up all other VM information */
35054         remove_vma_list(mm, vma);
35055  
35056 +       track_exec_limit(mm, start, end, 0UL);
35057 +
35058         return 0;
35059  }
35060  
35061 @@ -1934,22 +2319,18 @@ asmlinkage long sys_munmap(unsigned long
35062  
35063         profile_munmap(addr);
35064  
35065 +#ifdef CONFIG_PAX_SEGMEXEC
35066 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) &&
35067 +           (len > SEGMEXEC_TASK_SIZE || addr > SEGMEXEC_TASK_SIZE-len))
35068 +               return -EINVAL;
35069 +#endif
35070 +
35071         down_write(&mm->mmap_sem);
35072         ret = do_munmap(mm, addr, len);
35073         up_write(&mm->mmap_sem);
35074         return ret;
35075  }
35076  
35077 -static inline void verify_mm_writelocked(struct mm_struct *mm)
35078 -{
35079 -#ifdef CONFIG_DEBUG_VM
35080 -       if (unlikely(down_read_trylock(&mm->mmap_sem))) {
35081 -               WARN_ON(1);
35082 -               up_read(&mm->mmap_sem);
35083 -       }
35084 -#endif
35085 -}
35086 -
35087  /*
35088   *  this is really a simplified "do_mmap".  it only handles
35089   *  anonymous maps.  eventually we may be able to do some
35090 @@ -1963,6 +2344,11 @@ unsigned long do_brk(unsigned long addr,
35091         struct rb_node ** rb_link, * rb_parent;
35092         pgoff_t pgoff = addr >> PAGE_SHIFT;
35093         int error;
35094 +       unsigned long charged;
35095 +
35096 +#ifdef CONFIG_PAX_SEGMEXEC
35097 +       struct vm_area_struct *vma_m = NULL;
35098 +#endif
35099  
35100         len = PAGE_ALIGN(len);
35101         if (!len)
35102 @@ -1980,19 +2366,34 @@ unsigned long do_brk(unsigned long addr,
35103  
35104         flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags;
35105  
35106 +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC)
35107 +       if (mm->pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) {
35108 +               flags &= ~VM_EXEC;
35109 +
35110 +#ifdef CONFIG_PAX_MPROTECT
35111 +               if (mm->pax_flags & MF_PAX_MPROTECT)
35112 +                       flags &= ~VM_MAYEXEC;
35113 +#endif
35114 +
35115 +       }
35116 +#endif
35117 +
35118         error = arch_mmap_check(addr, len, flags);
35119         if (error)
35120                 return error;
35121  
35122 +       charged = len >> PAGE_SHIFT;
35123 +
35124         /*
35125          * mlock MCL_FUTURE?
35126          */
35127         if (mm->def_flags & VM_LOCKED) {
35128                 unsigned long locked, lock_limit;
35129 -               locked = len >> PAGE_SHIFT;
35130 +               locked = charged;
35131                 locked += mm->locked_vm;
35132                 lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur;
35133                 lock_limit >>= PAGE_SHIFT;
35134 +               gr_learn_resource(current, RLIMIT_MEMLOCK, locked << PAGE_SHIFT, 1);
35135                 if (locked > lock_limit && !capable(CAP_IPC_LOCK))
35136                         return -EAGAIN;
35137         }
35138 @@ -2006,23 +2407,23 @@ unsigned long do_brk(unsigned long addr,
35139         /*
35140          * Clear old maps.  this also does some error checking for us
35141          */
35142 - munmap_back:
35143         vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35144         if (vma && vma->vm_start < addr + len) {
35145                 if (do_munmap(mm, addr, len))
35146                         return -ENOMEM;
35147 -               goto munmap_back;
35148 +               vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
35149 +               BUG_ON(vma && vma->vm_start < addr + len);
35150         }
35151  
35152         /* Check against address space limits *after* clearing old maps... */
35153 -       if (!may_expand_vm(mm, len >> PAGE_SHIFT))
35154 +       if (!may_expand_vm(mm, charged))
35155                 return -ENOMEM;
35156  
35157         if (mm->map_count > sysctl_max_map_count)
35158                 return -ENOMEM;
35159  
35160 -       if (security_vm_enough_memory(len >> PAGE_SHIFT) ||
35161 -               !vx_vmpages_avail(mm, len >> PAGE_SHIFT))
35162 +       if (security_vm_enough_memory(charged) ||
35163 +               !vx_vmpages_avail(mm, charged))
35164                 return -ENOMEM;
35165  
35166         /* Can we just expand an old private anonymous mapping? */
35167 @@ -2034,10 +2435,21 @@ unsigned long do_brk(unsigned long addr,
35168          */
35169         vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35170         if (!vma) {
35171 -               vm_unacct_memory(len >> PAGE_SHIFT);
35172 +               vm_unacct_memory(charged);
35173                 return -ENOMEM;
35174         }
35175  
35176 +#ifdef CONFIG_PAX_SEGMEXEC
35177 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (flags & VM_EXEC)) {
35178 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35179 +               if (!vma_m) {
35180 +                       kmem_cache_free(vm_area_cachep, vma);
35181 +                       vm_unacct_memory(charged);
35182 +                       return -ENOMEM;
35183 +               }
35184 +       }
35185 +#endif
35186 +
35187         vma->vm_mm = mm;
35188         vma->vm_start = addr;
35189         vma->vm_end = addr + len;
35190 @@ -2045,12 +2457,19 @@ unsigned long do_brk(unsigned long addr,
35191         vma->vm_flags = flags;
35192         vma->vm_page_prot = vm_get_page_prot(flags);
35193         vma_link(mm, vma, prev, rb_link, rb_parent);
35194 +
35195 +#ifdef CONFIG_PAX_SEGMEXEC
35196 +       if (vma_m)
35197 +               pax_mirror_vma(vma_m, vma);
35198 +#endif
35199 +
35200  out:
35201 -       vx_vmpages_add(mm, len >> PAGE_SHIFT);
35202 +       vx_vmpages_add(mm, charged);
35203         if (flags & VM_LOCKED) {
35204 -               vx_vmlocked_add(mm, len >> PAGE_SHIFT);
35205 +               vx_vmlocked_add(mm, charged);
35206                 make_pages_present(addr, addr + len);
35207         }
35208 +       track_exec_limit(mm, addr, addr + len, flags);
35209         return addr;
35210  }
35211  
35212 @@ -2082,8 +2501,10 @@ void exit_mmap(struct mm_struct *mm)
35213          * Walk the list again, actually closing and freeing it,
35214          * with preemption enabled, without holding any MM locks.
35215          */
35216 -       while (vma)
35217 +       while (vma) {
35218 +               vma->vm_mirror = NULL;
35219                 vma = remove_vma(vma);
35220 +       }
35221  
35222         BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT);
35223  }
35224 @@ -2097,6 +2518,10 @@ int insert_vm_struct(struct mm_struct * 
35225         struct vm_area_struct * __vma, * prev;
35226         struct rb_node ** rb_link, * rb_parent;
35227  
35228 +#ifdef CONFIG_PAX_SEGMEXEC
35229 +       struct vm_area_struct *vma_m = NULL;
35230 +#endif
35231 +
35232         /*
35233          * The vm_pgoff of a purely anonymous vma should be irrelevant
35234          * until its first write fault, when page's anon_vma and index
35235 @@ -2119,7 +2544,22 @@ int insert_vm_struct(struct mm_struct * 
35236         if ((vma->vm_flags & VM_ACCOUNT) &&
35237              security_vm_enough_memory_mm(mm, vma_pages(vma)))
35238                 return -ENOMEM;
35239 +
35240 +#ifdef CONFIG_PAX_SEGMEXEC
35241 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (vma->vm_flags & VM_EXEC)) {
35242 +               vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35243 +               if (!vma_m)
35244 +                       return -ENOMEM;
35245 +       }
35246 +#endif
35247 +
35248         vma_link(mm, vma, prev, rb_link, rb_parent);
35249 +
35250 +#ifdef CONFIG_PAX_SEGMEXEC
35251 +       if (vma_m)
35252 +               pax_mirror_vma(vma_m, vma);
35253 +#endif
35254 +
35255         return 0;
35256  }
35257  
35258 @@ -2137,6 +2577,8 @@ struct vm_area_struct *copy_vma(struct v
35259         struct rb_node **rb_link, *rb_parent;
35260         struct mempolicy *pol;
35261  
35262 +       BUG_ON(vma->vm_mirror);
35263 +
35264         /*
35265          * If anonymous vma has not yet been faulted, update new pgoff
35266          * to match new location, to increase its chance of merging.
35267 @@ -2180,6 +2622,35 @@ struct vm_area_struct *copy_vma(struct v
35268         return new_vma;
35269  }
35270  
35271 +#ifdef CONFIG_PAX_SEGMEXEC
35272 +void pax_mirror_vma(struct vm_area_struct *vma_m, struct vm_area_struct *vma)
35273 +{
35274 +       struct vm_area_struct *prev_m;
35275 +       struct rb_node **rb_link_m, *rb_parent_m;
35276 +       struct mempolicy *pol_m;
35277 +
35278 +       BUG_ON(!(vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) || !(vma->vm_flags & VM_EXEC));
35279 +       BUG_ON(vma->vm_mirror || vma_m->vm_mirror);
35280 +       BUG_ON(!mpol_equal(vma_policy(vma), vma_policy(vma_m)));
35281 +       *vma_m = *vma;
35282 +       pol_m = vma_policy(vma_m);
35283 +       mpol_get(pol_m);
35284 +       vma_set_policy(vma_m, pol_m);
35285 +       vma_m->vm_start += SEGMEXEC_TASK_SIZE;
35286 +       vma_m->vm_end += SEGMEXEC_TASK_SIZE;
35287 +       vma_m->vm_flags &= ~(VM_WRITE | VM_MAYWRITE | VM_ACCOUNT | VM_LOCKED);
35288 +       vma_m->vm_page_prot = vm_get_page_prot(vma_m->vm_flags);
35289 +       if (vma_m->vm_file)
35290 +               get_file(vma_m->vm_file);
35291 +       if (vma_m->vm_ops && vma_m->vm_ops->open)
35292 +               vma_m->vm_ops->open(vma_m);
35293 +       find_vma_prepare(vma->vm_mm, vma_m->vm_start, &prev_m, &rb_link_m, &rb_parent_m);
35294 +       vma_link(vma->vm_mm, vma_m, prev_m, rb_link_m, rb_parent_m);
35295 +       vma_m->vm_mirror = vma;
35296 +       vma->vm_mirror = vma_m;
35297 +}
35298 +#endif
35299 +
35300  /*
35301   * Return true if the calling process may expand its vm space by the passed
35302   * number of pages
35303 @@ -2190,7 +2661,7 @@ int may_expand_vm(struct mm_struct *mm, 
35304         unsigned long lim;
35305  
35306         lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
35307 -
35308 +       gr_learn_resource(current, RLIMIT_AS, (cur + npages) << PAGE_SHIFT, 1);
35309         if (cur + npages > lim)
35310                 return 0;
35311         return 1;
35312 @@ -2259,6 +2730,15 @@ int install_special_mapping(struct mm_st
35313         vma->vm_start = addr;
35314         vma->vm_end = addr + len;
35315  
35316 +#ifdef CONFIG_PAX_MPROTECT
35317 +       if (mm->pax_flags & MF_PAX_MPROTECT) {
35318 +               if ((vm_flags & (VM_WRITE | VM_EXEC)) != VM_EXEC)
35319 +                       vm_flags &= ~(VM_EXEC | VM_MAYEXEC);
35320 +               else
35321 +                       vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
35322 +       }
35323 +#endif
35324 +
35325         vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND;
35326         vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
35327  
35328 diff -urNp linux-2.6.27.10/mm/mprotect.c linux-2.6.27.10/mm/mprotect.c
35329 --- linux-2.6.27.10/mm/mprotect.c       2008-11-07 12:55:34.000000000 -0500
35330 +++ linux-2.6.27.10/mm/mprotect.c       2008-12-21 00:45:45.000000000 -0500
35331 @@ -22,10 +22,17 @@
35332  #include <linux/swap.h>
35333  #include <linux/swapops.h>
35334  #include <linux/mmu_notifier.h>
35335 +#include <linux/grsecurity.h>
35336 +
35337 +#ifdef CONFIG_PAX_MPROTECT
35338 +#include <linux/elf.h>
35339 +#endif
35340 +
35341  #include <asm/uaccess.h>
35342  #include <asm/pgtable.h>
35343  #include <asm/cacheflush.h>
35344  #include <asm/tlbflush.h>
35345 +#include <asm/mmu_context.h>
35346  
35347  #ifndef pgprot_modify
35348  static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
35349 @@ -133,6 +140,48 @@ static void change_protection(struct vm_
35350         flush_tlb_range(vma, start, end);
35351  }
35352  
35353 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35354 +/* called while holding the mmap semaphor for writing except stack expansion */
35355 +void track_exec_limit(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long prot)
35356 +{
35357 +       unsigned long oldlimit, newlimit = 0UL;
35358 +
35359 +       if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || nx_enabled)
35360 +               return;
35361 +
35362 +       spin_lock(&mm->page_table_lock);
35363 +       oldlimit = mm->context.user_cs_limit;
35364 +       if ((prot & VM_EXEC) && oldlimit < end)
35365 +               /* USER_CS limit moved up */
35366 +               newlimit = end;
35367 +       else if (!(prot & VM_EXEC) && start < oldlimit && oldlimit <= end)
35368 +               /* USER_CS limit moved down */
35369 +               newlimit = start;
35370 +
35371 +       if (newlimit) {
35372 +               mm->context.user_cs_limit = newlimit;
35373 +
35374 +#ifdef CONFIG_SMP
35375 +               wmb();
35376 +               cpus_clear(mm->context.cpu_user_cs_mask);
35377 +               cpu_set(smp_processor_id(), mm->context.cpu_user_cs_mask);
35378 +#endif
35379 +
35380 +               set_user_cs(mm->context.user_cs_base, mm->context.user_cs_limit, smp_processor_id());
35381 +       }
35382 +       spin_unlock(&mm->page_table_lock);
35383 +       if (newlimit == end) {
35384 +               struct vm_area_struct *vma = find_vma(mm, oldlimit);
35385 +
35386 +               for (; vma && vma->vm_start < end; vma = vma->vm_next)
35387 +                       if (is_vm_hugetlb_page(vma))
35388 +                               hugetlb_change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot);
35389 +                       else
35390 +                               change_protection(vma, vma->vm_start, vma->vm_end, vma->vm_page_prot, vma_wants_writenotify(vma));
35391 +       }
35392 +}
35393 +#endif
35394 +
35395  int
35396  mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
35397         unsigned long start, unsigned long end, unsigned long newflags)
35398 @@ -145,6 +194,14 @@ mprotect_fixup(struct vm_area_struct *vm
35399         int error;
35400         int dirty_accountable = 0;
35401  
35402 +#ifdef CONFIG_PAX_SEGMEXEC
35403 +       struct vm_area_struct *vma_m = NULL;
35404 +       unsigned long start_m, end_m;
35405 +
35406 +       start_m = start + SEGMEXEC_TASK_SIZE;
35407 +       end_m = end + SEGMEXEC_TASK_SIZE;
35408 +#endif
35409 +
35410         if (newflags == oldflags) {
35411                 *pprev = vma;
35412                 return 0;
35413 @@ -165,6 +222,38 @@ mprotect_fixup(struct vm_area_struct *vm
35414                 }
35415         }
35416  
35417 +#ifdef CONFIG_PAX_SEGMEXEC
35418 +       if ((mm->pax_flags & MF_PAX_SEGMEXEC) && ((oldflags ^ newflags) & VM_EXEC)) {
35419 +               if (start != vma->vm_start) {
35420 +                       error = split_vma(mm, vma, start, 1);
35421 +                       if (error)
35422 +                               goto fail;
35423 +                       BUG_ON(!*pprev || (*pprev)->vm_next == vma);
35424 +                       *pprev = (*pprev)->vm_next;
35425 +               }
35426 +
35427 +               if (end != vma->vm_end) {
35428 +                       error = split_vma(mm, vma, end, 0);
35429 +                       if (error)
35430 +                               goto fail;
35431 +               }
35432 +
35433 +               if (pax_find_mirror_vma(vma)) {
35434 +                       error = __do_munmap(mm, start_m, end_m - start_m);
35435 +                       if (error)
35436 +                               goto fail;
35437 +               } else {
35438 +                       vma_m = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
35439 +                       if (!vma_m) {
35440 +                               error = -ENOMEM;
35441 +                               goto fail;
35442 +                       }
35443 +                       vma->vm_flags = newflags;
35444 +                       pax_mirror_vma(vma_m, vma);
35445 +               }
35446 +       }
35447 +#endif
35448 +
35449         /*
35450          * First try to merge with previous and/or next vma.
35451          */
35452 @@ -196,8 +285,14 @@ success:
35453          * held in write mode.
35454          */
35455         vma->vm_flags = newflags;
35456 +
35457 +#ifdef CONFIG_PAX_MPROTECT
35458 +       if (current->binfmt && current->binfmt->handle_mprotect)
35459 +               current->binfmt->handle_mprotect(vma, newflags);
35460 +#endif
35461 +
35462         vma->vm_page_prot = pgprot_modify(vma->vm_page_prot,
35463 -                                         vm_get_page_prot(newflags));
35464 +                                         vm_get_page_prot(vma->vm_flags));
35465  
35466         if (vma_wants_writenotify(vma)) {
35467                 vma->vm_page_prot = vm_get_page_prot(newflags & ~VM_SHARED);
35468 @@ -238,6 +333,17 @@ sys_mprotect(unsigned long start, size_t
35469         end = start + len;
35470         if (end <= start)
35471                 return -ENOMEM;
35472 +
35473 +#ifdef CONFIG_PAX_SEGMEXEC
35474 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC) {
35475 +               if (end > SEGMEXEC_TASK_SIZE)
35476 +                       return -EINVAL;
35477 +       } else
35478 +#endif
35479 +
35480 +       if (end > TASK_SIZE)
35481 +               return -EINVAL;
35482 +
35483         if (!arch_validate_prot(prot))
35484                 return -EINVAL;
35485  
35486 @@ -245,7 +351,7 @@ sys_mprotect(unsigned long start, size_t
35487         /*
35488          * Does the application expect PROT_READ to imply PROT_EXEC:
35489          */
35490 -       if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
35491 +       if ((prot & (PROT_READ | PROT_WRITE)) && (current->personality & READ_IMPLIES_EXEC))
35492                 prot |= PROT_EXEC;
35493  
35494         vm_flags = calc_vm_prot_bits(prot);
35495 @@ -277,6 +383,16 @@ sys_mprotect(unsigned long start, size_t
35496         if (start > vma->vm_start)
35497                 prev = vma;
35498  
35499 +       if (!gr_acl_handle_mprotect(vma->vm_file, prot)) {
35500 +               error = -EACCES;
35501 +               goto out;
35502 +       }
35503 +
35504 +#ifdef CONFIG_PAX_MPROTECT
35505 +       if (current->binfmt && current->binfmt->handle_mprotect)
35506 +               current->binfmt->handle_mprotect(vma, vm_flags);
35507 +#endif
35508 +
35509         for (nstart = start ; ; ) {
35510                 unsigned long newflags;
35511  
35512 @@ -300,6 +416,9 @@ sys_mprotect(unsigned long start, size_t
35513                 error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
35514                 if (error)
35515                         goto out;
35516 +
35517 +               track_exec_limit(current->mm, nstart, tmp, vm_flags);
35518 +
35519                 nstart = tmp;
35520  
35521                 if (nstart < prev->vm_end)
35522 diff -urNp linux-2.6.27.10/mm/mremap.c linux-2.6.27.10/mm/mremap.c
35523 --- linux-2.6.27.10/mm/mremap.c 2008-11-07 12:55:34.000000000 -0500
35524 +++ linux-2.6.27.10/mm/mremap.c 2008-11-18 03:38:45.000000000 -0500
35525 @@ -111,6 +111,12 @@ static void move_ptes(struct vm_area_str
35526                         continue;
35527                 pte = ptep_clear_flush(vma, old_addr, old_pte);
35528                 pte = move_pte(pte, new_vma->vm_page_prot, old_addr, new_addr);
35529 +
35530 +#ifdef CONFIG_ARCH_TRACK_EXEC_LIMIT
35531 +               if (!nx_enabled && (new_vma->vm_flags & (VM_PAGEEXEC | VM_EXEC)) == VM_PAGEEXEC)
35532 +                       pte = pte_exprotect(pte);
35533 +#endif
35534 +
35535                 set_pte_at(mm, new_addr, new_pte, pte);
35536         }
35537  
35538 @@ -260,6 +266,7 @@ unsigned long do_mremap(unsigned long ad
35539         struct vm_area_struct *vma;
35540         unsigned long ret = -EINVAL;
35541         unsigned long charged = 0;
35542 +       unsigned long pax_task_size = TASK_SIZE;
35543  
35544         if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
35545                 goto out;
35546 @@ -278,6 +285,15 @@ unsigned long do_mremap(unsigned long ad
35547         if (!new_len)
35548                 goto out;
35549  
35550 +#ifdef CONFIG_PAX_SEGMEXEC
35551 +       if (current->mm->pax_flags & MF_PAX_SEGMEXEC)
35552 +               pax_task_size = SEGMEXEC_TASK_SIZE;
35553 +#endif
35554 +
35555 +       if (new_len > pax_task_size || addr > pax_task_size-new_len ||
35556 +           old_len > pax_task_size || addr > pax_task_size-old_len)
35557 +               goto out;
35558 +
35559         /* new_addr is only valid if MREMAP_FIXED is specified */
35560         if (flags & MREMAP_FIXED) {
35561                 if (new_addr & ~PAGE_MASK)
35562 @@ -285,16 +301,13 @@ unsigned long do_mremap(unsigned long ad
35563                 if (!(flags & MREMAP_MAYMOVE))
35564                         goto out;
35565  
35566 -               if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
35567 +               if (new_addr > pax_task_size - new_len)
35568                         goto out;
35569  
35570                 /* Check if the location we're moving into overlaps the
35571                  * old location at all, and fail if it does.
35572                  */
35573 -               if ((new_addr <= addr) && (new_addr+new_len) > addr)
35574 -                       goto out;
35575 -
35576 -               if ((addr <= new_addr) && (addr+old_len) > new_addr)
35577 +               if (addr + old_len > new_addr && new_addr + new_len > addr)
35578                         goto out;
35579  
35580                 ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1);
35581 @@ -332,6 +345,14 @@ unsigned long do_mremap(unsigned long ad
35582                 ret = -EINVAL;
35583                 goto out;
35584         }
35585 +
35586 +#ifdef CONFIG_PAX_SEGMEXEC
35587 +       if (pax_find_mirror_vma(vma)) {
35588 +               ret = -EINVAL;
35589 +               goto out;
35590 +       }
35591 +#endif
35592 +
35593         /* We can't remap across vm area boundaries */
35594         if (old_len > vma->vm_end - addr)
35595                 goto out;
35596 @@ -365,7 +386,7 @@ unsigned long do_mremap(unsigned long ad
35597         if (old_len == vma->vm_end - addr &&
35598             !((flags & MREMAP_FIXED) && (addr != new_addr)) &&
35599             (old_len != new_len || !(flags & MREMAP_MAYMOVE))) {
35600 -               unsigned long max_addr = TASK_SIZE;
35601 +               unsigned long max_addr = pax_task_size;
35602                 if (vma->vm_next)
35603                         max_addr = vma->vm_next->vm_start;
35604                 /* can we just expand the current mapping? */
35605 @@ -383,6 +404,7 @@ unsigned long do_mremap(unsigned long ad
35606                                                    addr + new_len);
35607                         }
35608                         ret = addr;
35609 +                       track_exec_limit(vma->vm_mm, vma->vm_start, addr + new_len, vma->vm_flags);
35610                         goto out;
35611                 }
35612         }
35613 @@ -393,8 +415,8 @@ unsigned long do_mremap(unsigned long ad
35614          */
35615         ret = -ENOMEM;
35616         if (flags & MREMAP_MAYMOVE) {
35617 +               unsigned long map_flags = 0;
35618                 if (!(flags & MREMAP_FIXED)) {
35619 -                       unsigned long map_flags = 0;
35620                         if (vma->vm_flags & VM_MAYSHARE)
35621                                 map_flags |= MAP_SHARED;
35622  
35623 @@ -409,7 +431,12 @@ unsigned long do_mremap(unsigned long ad
35624                         if (ret)
35625                                 goto out;
35626                 }
35627 +               map_flags = vma->vm_flags;
35628                 ret = move_vma(vma, addr, old_len, new_len, new_addr);
35629 +               if (!(ret & ~PAGE_MASK)) {
35630 +                       track_exec_limit(current->mm, addr, addr + old_len, 0UL);
35631 +                       track_exec_limit(current->mm, new_addr, new_addr + new_len, map_flags);
35632 +               }
35633         }
35634  out:
35635         if (ret & ~PAGE_MASK)
35636 diff -urNp linux-2.6.27.10/mm/nommu.c linux-2.6.27.10/mm/nommu.c
35637 --- linux-2.6.27.10/mm/nommu.c  2008-11-07 12:55:34.000000000 -0500
35638 +++ linux-2.6.27.10/mm/nommu.c  2008-11-18 03:38:45.000000000 -0500
35639 @@ -437,15 +437,6 @@ struct vm_area_struct *find_vma(struct m
35640  }
35641  EXPORT_SYMBOL(find_vma);
35642  
35643 -/*
35644 - * find a VMA
35645 - * - we don't extend stack VMAs under NOMMU conditions
35646 - */
35647 -struct vm_area_struct *find_extend_vma(struct mm_struct *mm, unsigned long addr)
35648 -{
35649 -       return find_vma(mm, addr);
35650 -}
35651 -
35652  int expand_stack(struct vm_area_struct *vma, unsigned long address)
35653  {
35654         return -ENOMEM;
35655 diff -urNp linux-2.6.27.10/mm/page_alloc.c linux-2.6.27.10/mm/page_alloc.c
35656 --- linux-2.6.27.10/mm/page_alloc.c     2008-12-21 01:18:12.000000000 -0500
35657 +++ linux-2.6.27.10/mm/page_alloc.c     2008-12-21 01:18:22.000000000 -0500
35658 @@ -515,9 +515,20 @@ static void free_pages_bulk(struct zone 
35659  
35660  static void free_one_page(struct zone *zone, struct page *page, int order)
35661  {
35662 +
35663 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35664 +       unsigned long index = 1UL << order;
35665 +#endif
35666 +
35667         spin_lock(&zone->lock);
35668         zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
35669         zone->pages_scanned = 0;
35670 +
35671 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35672 +       for (; index; --index)
35673 +               sanitize_highpage(page + index - 1);
35674 +#endif
35675 +
35676         __free_one_page(page, zone, order);
35677         spin_unlock(&zone->lock);
35678  }
35679 @@ -635,8 +646,10 @@ static int prep_new_page(struct page *pa
35680         arch_alloc_page(page, order);
35681         kernel_map_pages(page, 1 << order, 1);
35682  
35683 +#ifndef CONFIG_PAX_MEMORY_SANITIZE
35684         if (gfp_flags & __GFP_ZERO)
35685                 prep_zero_page(page, order, gfp_flags);
35686 +#endif
35687  
35688         if (order && (gfp_flags & __GFP_COMP))
35689                 prep_compound_page(page, order);
35690 @@ -1009,6 +1022,11 @@ static void free_hot_cold_page(struct pa
35691                 list_add(&page->lru, &pcp->list);
35692         set_page_private(page, get_pageblock_migratetype(page));
35693         pcp->count++;
35694 +
35695 +#ifdef CONFIG_PAX_MEMORY_SANITIZE
35696 +       sanitize_highpage(page);
35697 +#endif
35698 +
35699         if (pcp->count >= pcp->high) {
35700                 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
35701                 pcp->count -= pcp->batch;
35702 diff -urNp linux-2.6.27.10/mm/rmap.c linux-2.6.27.10/mm/rmap.c
35703 --- linux-2.6.27.10/mm/rmap.c   2008-11-07 12:55:34.000000000 -0500
35704 +++ linux-2.6.27.10/mm/rmap.c   2008-11-18 03:38:45.000000000 -0500
35705 @@ -91,6 +91,10 @@ int anon_vma_prepare(struct vm_area_stru
35706                 struct mm_struct *mm = vma->vm_mm;
35707                 struct anon_vma *allocated;
35708  
35709 +#ifdef CONFIG_PAX_SEGMEXEC
35710 +               struct vm_area_struct *vma_m;
35711 +#endif
35712 +
35713                 anon_vma = find_mergeable_anon_vma(vma);
35714                 allocated = NULL;
35715                 if (!anon_vma) {
35716 @@ -104,6 +108,15 @@ int anon_vma_prepare(struct vm_area_stru
35717                 /* page_table_lock to protect against threads */
35718                 spin_lock(&mm->page_table_lock);
35719                 if (likely(!vma->anon_vma)) {
35720 +
35721 +#ifdef CONFIG_PAX_SEGMEXEC
35722 +                       vma_m = pax_find_mirror_vma(vma);
35723 +                       if (vma_m) {
35724 +                               vma_m->anon_vma = anon_vma;
35725 +                               __anon_vma_link(vma_m);
35726 +                       }
35727 +#endif
35728 +
35729                         vma->anon_vma = anon_vma;
35730                         list_add_tail(&vma->anon_vma_node, &anon_vma->head);
35731                         allocated = NULL;
35732 diff -urNp linux-2.6.27.10/mm/shmem.c linux-2.6.27.10/mm/shmem.c
35733 --- linux-2.6.27.10/mm/shmem.c  2008-11-07 12:55:34.000000000 -0500
35734 +++ linux-2.6.27.10/mm/shmem.c  2008-11-18 03:38:45.000000000 -0500
35735 @@ -2483,7 +2483,7 @@ static struct file_system_type tmpfs_fs_
35736         .get_sb         = shmem_get_sb,
35737         .kill_sb        = kill_litter_super,
35738  };
35739 -static struct vfsmount *shm_mnt;
35740 +struct vfsmount *shm_mnt;
35741  
35742  static int __init init_tmpfs(void)
35743  {
35744 diff -urNp linux-2.6.27.10/mm/slab.c linux-2.6.27.10/mm/slab.c
35745 --- linux-2.6.27.10/mm/slab.c   2008-11-07 12:55:34.000000000 -0500
35746 +++ linux-2.6.27.10/mm/slab.c   2008-11-18 03:38:45.000000000 -0500
35747 @@ -304,7 +304,7 @@ struct kmem_list3 {
35748   * Need this for bootstrapping a per node allocator.
35749   */
35750  #define NUM_INIT_LISTS (3 * MAX_NUMNODES)
35751 -struct kmem_list3 __initdata initkmem_list3[NUM_INIT_LISTS];
35752 +struct kmem_list3 initkmem_list3[NUM_INIT_LISTS];
35753  #define        CACHE_CACHE 0
35754  #define        SIZE_AC MAX_NUMNODES
35755  #define        SIZE_L3 (2 * MAX_NUMNODES)
35756 @@ -653,14 +653,14 @@ struct cache_names {
35757  static struct cache_names __initdata cache_names[] = {
35758  #define CACHE(x) { .name = "size-" #x, .name_dma = "size-" #x "(DMA)" },
35759  #include <linux/kmalloc_sizes.h>
35760 -       {NULL,}
35761 +       {NULL, NULL}
35762  #undef CACHE
35763  };
35764  
35765  static struct arraycache_init initarray_cache __initdata =
35766 -    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35767 +    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35768  static struct arraycache_init initarray_generic =
35769 -    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0} };
35770 +    { {0, BOOT_CPUCACHE_ENTRIES, 1, 0}, {NULL} };
35771  
35772  /* internal cache of cache description objs */
35773  static struct kmem_cache cache_cache = {
35774 @@ -2996,7 +2996,7 @@ retry:
35775                  * there must be at least one object available for
35776                  * allocation.
35777                  */
35778 -               BUG_ON(slabp->inuse < 0 || slabp->inuse >= cachep->num);
35779 +               BUG_ON(slabp->inuse >= cachep->num);
35780  
35781                 while (slabp->inuse < cachep->num && batchcount--) {
35782                         STATS_INC_ALLOCED(cachep);
35783 diff -urNp linux-2.6.27.10/mm/tiny-shmem.c linux-2.6.27.10/mm/tiny-shmem.c
35784 --- linux-2.6.27.10/mm/tiny-shmem.c     2008-11-07 12:55:34.000000000 -0500
35785 +++ linux-2.6.27.10/mm/tiny-shmem.c     2008-11-18 03:38:45.000000000 -0500
35786 @@ -26,7 +26,7 @@ static struct file_system_type tmpfs_fs_
35787         .kill_sb        = kill_litter_super,
35788  };
35789  
35790 -static struct vfsmount *shm_mnt;
35791 +struct vfsmount *shm_mnt;
35792  
35793  static int __init init_tmpfs(void)
35794  {
35795 diff -urNp linux-2.6.27.10/mm/util.c linux-2.6.27.10/mm/util.c
35796 --- linux-2.6.27.10/mm/util.c   2008-11-07 12:55:34.000000000 -0500
35797 +++ linux-2.6.27.10/mm/util.c   2008-11-18 03:38:45.000000000 -0500
35798 @@ -167,6 +167,12 @@ EXPORT_SYMBOL(strndup_user);
35799  void arch_pick_mmap_layout(struct mm_struct *mm)
35800  {
35801         mm->mmap_base = TASK_UNMAPPED_BASE;
35802 +
35803 +#ifdef CONFIG_PAX_RANDMMAP
35804 +       if (mm->pax_flags & MF_PAX_RANDMMAP)
35805 +               mm->mmap_base += mm->delta_mmap;
35806 +#endif
35807 +
35808         mm->get_unmapped_area = arch_get_unmapped_area;
35809         mm->unmap_area = arch_unmap_area;
35810  }
35811 diff -urNp linux-2.6.27.10/mm/vmalloc.c linux-2.6.27.10/mm/vmalloc.c
35812 --- linux-2.6.27.10/mm/vmalloc.c        2008-11-07 12:55:34.000000000 -0500
35813 +++ linux-2.6.27.10/mm/vmalloc.c        2008-11-18 03:38:45.000000000 -0500
35814 @@ -98,19 +98,36 @@ static int vmap_pte_range(pmd_t *pmd, un
35815                         unsigned long end, pgprot_t prot, struct page ***pages)
35816  {
35817         pte_t *pte;
35818 +       int ret = -ENOMEM;
35819 +
35820 +#ifdef CONFIG_PAX_KERNEXEC
35821 +       unsigned long cr0;
35822 +#endif
35823  
35824         pte = pte_alloc_kernel(pmd, addr);
35825         if (!pte)
35826                 return -ENOMEM;
35827 +
35828 +#ifdef CONFIG_PAX_KERNEXEC
35829 +       pax_open_kernel(cr0);
35830 +#endif
35831 +
35832         do {
35833                 struct page *page = **pages;
35834                 WARN_ON(!pte_none(*pte));
35835                 if (!page)
35836 -                       return -ENOMEM;
35837 +                       goto out;
35838                 set_pte_at(&init_mm, addr, pte, mk_pte(page, prot));
35839                 (*pages)++;
35840         } while (pte++, addr += PAGE_SIZE, addr != end);
35841 -       return 0;
35842 +       ret = 0;
35843 +out:
35844 +
35845 +#ifdef CONFIG_PAX_KERNEXEC
35846 +       pax_close_kernel(cr0);
35847 +#endif
35848 +
35849 +       return ret;
35850  }
35851  
35852  static inline int vmap_pmd_range(pud_t *pud, unsigned long addr,
35853 @@ -215,6 +232,16 @@ __get_vm_area_node(unsigned long size, u
35854         unsigned long addr;
35855  
35856         BUG_ON(in_interrupt());
35857 +
35858 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35859 +       if (flags & VM_KERNEXEC) {
35860 +               if (start != VMALLOC_START || end != VMALLOC_END)
35861 +                       return NULL;
35862 +               start = (unsigned long)MODULES_VADDR;
35863 +               end = (unsigned long)MODULES_END;
35864 +       }
35865 +#endif
35866 +
35867         if (flags & VM_IOREMAP) {
35868                 int bit = fls(size);
35869  
35870 @@ -248,20 +275,15 @@ __get_vm_area_node(unsigned long size, u
35871                                              (unsigned long)tmp->addr, align);
35872                         continue;
35873                 }
35874 -               if ((size + addr) < addr)
35875 -                       goto out;
35876                 if (size + addr <= (unsigned long)tmp->addr)
35877 -                       goto found;
35878 +                       break;
35879                 addr = ALIGN(tmp->size + (unsigned long)tmp->addr, align);
35880 -               if (addr > end - size)
35881 -                       goto out;
35882         }
35883         if ((size + addr) < addr)
35884                 goto out;
35885         if (addr > end - size)
35886                 goto out;
35887  
35888 -found:
35889         area->next = *p;
35890         *p = area;
35891  
35892 @@ -466,6 +488,11 @@ void *vmap(struct page **pages, unsigned
35893         if (count > num_physpages)
35894                 return NULL;
35895  
35896 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35897 +       if (!(pgprot_val(prot) & _PAGE_NX))
35898 +               flags |= VM_KERNEXEC;
35899 +#endif
35900 +
35901         area = get_vm_area_caller((count << PAGE_SHIFT), flags,
35902                                         __builtin_return_address(0));
35903         if (!area)
35904 @@ -560,6 +587,13 @@ static void *__vmalloc_node(unsigned lon
35905         if (!size || (size >> PAGE_SHIFT) > num_physpages)
35906                 return NULL;
35907  
35908 +#if defined(CONFIG_MODULES) && defined(CONFIG_X86_32) && defined(CONFIG_PAX_KERNEXEC)
35909 +       if (!(pgprot_val(prot) & _PAGE_NX))
35910 +               area = __get_vm_area_node(size, VM_ALLOC | VM_KERNEXEC, VMALLOC_START, VMALLOC_END,
35911 +                                               node, gfp_mask, caller);
35912 +       else
35913 +#endif
35914 +
35915         area = __get_vm_area_node(size, VM_ALLOC, VMALLOC_START, VMALLOC_END,
35916                                                 node, gfp_mask, caller);
35917  
35918 @@ -651,7 +685,7 @@ EXPORT_SYMBOL(vmalloc_node);
35919  
35920  void *vmalloc_exec(unsigned long size)
35921  {
35922 -       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM, PAGE_KERNEL_EXEC);
35923 +       return __vmalloc(size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, PAGE_KERNEL_EXEC);
35924  }
35925  
35926  #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32)
35927 diff -urNp linux-2.6.27.10/net/bridge/br_stp_if.c linux-2.6.27.10/net/bridge/br_stp_if.c
35928 --- linux-2.6.27.10/net/bridge/br_stp_if.c      2008-11-07 12:55:34.000000000 -0500
35929 +++ linux-2.6.27.10/net/bridge/br_stp_if.c      2008-11-18 03:38:45.000000000 -0500
35930 @@ -146,7 +146,7 @@ static void br_stp_stop(struct net_bridg
35931         char *envp[] = { NULL };
35932  
35933         if (br->stp_enabled == BR_USER_STP) {
35934 -               r = call_usermodehelper(BR_STP_PROG, argv, envp, 1);
35935 +               r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC);
35936                 printk(KERN_INFO "%s: userspace STP stopped, return code %d\n",
35937                         br->dev->name, r);
35938  
35939 diff -urNp linux-2.6.27.10/net/core/flow.c linux-2.6.27.10/net/core/flow.c
35940 --- linux-2.6.27.10/net/core/flow.c     2008-11-07 12:55:34.000000000 -0500
35941 +++ linux-2.6.27.10/net/core/flow.c     2008-11-18 03:38:45.000000000 -0500
35942 @@ -39,7 +39,7 @@ atomic_t flow_cache_genid = ATOMIC_INIT(
35943  
35944  static u32 flow_hash_shift;
35945  #define flow_hash_size (1 << flow_hash_shift)
35946 -static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
35947 +static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables);
35948  
35949  #define flow_table(cpu) (per_cpu(flow_tables, cpu))
35950  
35951 @@ -52,7 +52,7 @@ struct flow_percpu_info {
35952         u32 hash_rnd;
35953         int count;
35954  };
35955 -static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info) = { 0 };
35956 +static DEFINE_PER_CPU(struct flow_percpu_info, flow_hash_info);
35957  
35958  #define flow_hash_rnd_recalc(cpu) \
35959         (per_cpu(flow_hash_info, cpu).hash_rnd_recalc)
35960 @@ -69,7 +69,7 @@ struct flow_flush_info {
35961         atomic_t cpuleft;
35962         struct completion completion;
35963  };
35964 -static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets) = { NULL };
35965 +static DEFINE_PER_CPU(struct tasklet_struct, flow_flush_tasklets);
35966  
35967  #define flow_flush_tasklet(cpu) (&per_cpu(flow_flush_tasklets, cpu))
35968  
35969 diff -urNp linux-2.6.27.10/net/dccp/ccids/ccid3.c linux-2.6.27.10/net/dccp/ccids/ccid3.c
35970 --- linux-2.6.27.10/net/dccp/ccids/ccid3.c      2008-11-07 12:55:34.000000000 -0500
35971 +++ linux-2.6.27.10/net/dccp/ccids/ccid3.c      2008-11-18 03:38:45.000000000 -0500
35972 @@ -43,7 +43,7 @@
35973  static int ccid3_debug;
35974  #define ccid3_pr_debug(format, a...)   DCCP_PR_DEBUG(ccid3_debug, format, ##a)
35975  #else
35976 -#define ccid3_pr_debug(format, a...)
35977 +#define ccid3_pr_debug(format, a...) do {} while (0)
35978  #endif
35979  
35980  /*
35981 diff -urNp linux-2.6.27.10/net/dccp/dccp.h linux-2.6.27.10/net/dccp/dccp.h
35982 --- linux-2.6.27.10/net/dccp/dccp.h     2008-11-07 12:55:34.000000000 -0500
35983 +++ linux-2.6.27.10/net/dccp/dccp.h     2008-11-18 03:38:45.000000000 -0500
35984 @@ -43,8 +43,8 @@ extern int dccp_debug;
35985  #define dccp_pr_debug(format, a...)      DCCP_PR_DEBUG(dccp_debug, format, ##a)
35986  #define dccp_pr_debug_cat(format, a...)   DCCP_PRINTK(dccp_debug, format, ##a)
35987  #else
35988 -#define dccp_pr_debug(format, a...)
35989 -#define dccp_pr_debug_cat(format, a...)
35990 +#define dccp_pr_debug(format, a...) do {} while (0)
35991 +#define dccp_pr_debug_cat(format, a...) do {} while (0)
35992  #endif
35993  
35994  extern struct inet_hashinfo dccp_hashinfo;
35995 diff -urNp linux-2.6.27.10/net/ipv4/inet_connection_sock.c linux-2.6.27.10/net/ipv4/inet_connection_sock.c
35996 --- linux-2.6.27.10/net/ipv4/inet_connection_sock.c     2008-11-07 12:55:34.000000000 -0500
35997 +++ linux-2.6.27.10/net/ipv4/inet_connection_sock.c     2008-11-18 03:38:45.000000000 -0500
35998 @@ -15,6 +15,7 @@
35999  
36000  #include <linux/module.h>
36001  #include <linux/jhash.h>
36002 +#include <linux/grsecurity.h>
36003  
36004  #include <net/inet_connection_sock.h>
36005  #include <net/inet_hashtables.h>
36006 diff -urNp linux-2.6.27.10/net/ipv4/inet_hashtables.c linux-2.6.27.10/net/ipv4/inet_hashtables.c
36007 --- linux-2.6.27.10/net/ipv4/inet_hashtables.c  2008-11-07 12:55:34.000000000 -0500
36008 +++ linux-2.6.27.10/net/ipv4/inet_hashtables.c  2008-11-18 03:38:45.000000000 -0500
36009 @@ -18,12 +18,15 @@
36010  #include <linux/sched.h>
36011  #include <linux/slab.h>
36012  #include <linux/wait.h>
36013 +#include <linux/grsecurity.h>
36014  
36015  #include <net/inet_connection_sock.h>
36016  #include <net/inet_hashtables.h>
36017  #include <net/route.h>
36018  #include <net/ip.h>
36019  
36020 +extern void gr_update_task_in_ip_table(struct task_struct *task, const struct inet_sock *inet);
36021 +
36022  /*
36023   * Allocate and initialize a new local port bind bucket.
36024   * The bindhash mutex for snum's hash chain must be held here.
36025 @@ -487,6 +490,8 @@ ok:
36026                 }
36027                 spin_unlock(&head->lock);
36028  
36029 +               gr_update_task_in_ip_table(current, inet_sk(sk));
36030 +
36031                 if (tw) {
36032                         inet_twsk_deschedule(tw, death_row);
36033                         inet_twsk_put(tw);
36034 diff -urNp linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c
36035 --- linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c    1969-12-31 19:00:00.000000000 -0500
36036 +++ linux-2.6.27.10/net/ipv4/netfilter/ipt_stealth.c    2008-11-18 03:38:45.000000000 -0500
36037 @@ -0,0 +1,114 @@
36038 +/* Kernel module to add stealth support.
36039 + *
36040 + * Copyright (C) 2002-2006 Brad Spengler  <spender@grsecurity.net>
36041 + *
36042 + */
36043 +
36044 +#include <linux/kernel.h>
36045 +#include <linux/module.h>
36046 +#include <linux/skbuff.h>
36047 +#include <linux/net.h>
36048 +#include <linux/sched.h>
36049 +#include <linux/inet.h>
36050 +#include <linux/stddef.h>
36051 +
36052 +#include <net/ip.h>
36053 +#include <net/sock.h>
36054 +#include <net/tcp.h>
36055 +#include <net/udp.h>
36056 +#include <net/route.h>
36057 +#include <net/inet_common.h>
36058 +
36059 +#include <linux/netfilter_ipv4/ip_tables.h>
36060 +
36061 +MODULE_LICENSE("GPL");
36062 +
36063 +extern struct sock *udp_v4_lookup(struct net *net, u32 saddr, u16 sport, u32 daddr, u16 dport, int dif);
36064 +
36065 +static bool
36066 +match(const struct sk_buff *skb,
36067 +      const struct net_device *in,
36068 +      const struct net_device *out,
36069 +      const struct xt_match *match,
36070 +      const void *matchinfo,
36071 +      int offset,
36072 +      unsigned int protoff,
36073 +      bool *hotdrop)
36074 +{
36075 +       struct iphdr *ip = ip_hdr(skb);
36076 +       struct tcphdr th;
36077 +       struct udphdr uh;
36078 +       struct sock *sk = NULL;
36079 +
36080 +       if (!ip || offset) return false;
36081 +
36082 +       switch(ip->protocol) {
36083 +       case IPPROTO_TCP:
36084 +               if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &th, sizeof(th)) < 0) {
36085 +                       *hotdrop = true;
36086 +                       return false;
36087 +               }
36088 +               if (!(th.syn && !th.ack)) return false;
36089 +               sk = inet_lookup_listener(dev_net(skb->dev), &tcp_hashinfo, ip->daddr, th.dest, inet_iif(skb)); 
36090 +               break;
36091 +       case IPPROTO_UDP:
36092 +               if (skb_copy_bits(skb, (ip_hdr(skb))->ihl*4, &uh, sizeof(uh)) < 0) {
36093 +                       *hotdrop = true;
36094 +                       return false;
36095 +               }
36096 +               sk = udp_v4_lookup(dev_net(skb->dev), ip->saddr, uh.source, ip->daddr, uh.dest, skb->dev->ifindex);
36097 +               break;
36098 +       default:
36099 +               return false;
36100 +       }
36101 +
36102 +       if(!sk) // port is being listened on, match this
36103 +               return true;
36104 +       else {
36105 +               sock_put(sk);
36106 +               return false;
36107 +       }
36108 +}
36109 +
36110 +/* Called when user tries to insert an entry of this type. */
36111 +static bool
36112 +checkentry(const char *tablename,
36113 +           const void *nip,
36114 +          const struct xt_match *match,
36115 +           void *matchinfo,
36116 +           unsigned int hook_mask)
36117 +{
36118 +       const struct ipt_ip *ip = (const struct ipt_ip *)nip;
36119 +
36120 +       if(((ip->proto == IPPROTO_TCP && !(ip->invflags & IPT_INV_PROTO)) ||
36121 +               ((ip->proto == IPPROTO_UDP) && !(ip->invflags & IPT_INV_PROTO)))
36122 +               && (hook_mask & (1 << NF_INET_LOCAL_IN)))
36123 +                       return true;
36124 +
36125 +       printk("stealth: Only works on TCP and UDP for the INPUT chain.\n");
36126 +
36127 +        return false;
36128 +}
36129 +
36130 +
36131 +static struct xt_match stealth_match __read_mostly = {
36132 +       .name = "stealth",
36133 +       .family = AF_INET,
36134 +       .match = match,
36135 +       .checkentry = checkentry,
36136 +       .destroy = NULL,
36137 +       .me = THIS_MODULE
36138 +};
36139 +
36140 +static int __init init(void)
36141 +{
36142 +       return xt_register_match(&stealth_match);
36143 +}
36144 +
36145 +static void __exit fini(void)
36146 +{
36147 +       xt_unregister_match(&stealth_match);
36148 +}
36149 +
36150 +module_init(init);
36151 +module_exit(fini);
36152 diff -urNp linux-2.6.27.10/net/ipv4/netfilter/Kconfig linux-2.6.27.10/net/ipv4/netfilter/Kconfig
36153 --- linux-2.6.27.10/net/ipv4/netfilter/Kconfig  2008-11-07 12:55:34.000000000 -0500
36154 +++ linux-2.6.27.10/net/ipv4/netfilter/Kconfig  2008-11-18 03:38:45.000000000 -0500
36155 @@ -111,6 +111,21 @@ config IP_NF_MATCH_ADDRTYPE
36156           If you want to compile it as a module, say M here and read
36157           <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
36158  
36159 +config IP_NF_MATCH_STEALTH
36160 +       tristate "stealth match support"
36161 +       depends on IP_NF_IPTABLES
36162 +       help
36163 +         Enabling this option will drop all syn packets coming to unserved tcp
36164 +         ports as well as all packets coming to unserved udp ports.  If you
36165 +         are using your system to route any type of packets (ie. via NAT)
36166 +         you should put this module at the end of your ruleset, since it will
36167 +         drop packets that aren't going to ports that are listening on your
36168 +         machine itself, it doesn't take into account that the packet might be
36169 +         destined for someone on your internal network if you're using NAT for
36170 +         instance.
36171 +
36172 +         To compile it as a module, choose M here.  If unsure, say N.
36173 +
36174  # `filter', generic and specific targets
36175  config IP_NF_FILTER
36176         tristate "Packet filtering"
36177 @@ -407,4 +422,3 @@ config IP_NF_ARP_MANGLE
36178           hardware and network addresses.
36179  
36180  endmenu
36181 -
36182 diff -urNp linux-2.6.27.10/net/ipv4/netfilter/Makefile linux-2.6.27.10/net/ipv4/netfilter/Makefile
36183 --- linux-2.6.27.10/net/ipv4/netfilter/Makefile 2008-11-07 12:55:34.000000000 -0500
36184 +++ linux-2.6.27.10/net/ipv4/netfilter/Makefile 2008-11-18 03:38:45.000000000 -0500
36185 @@ -59,6 +59,7 @@ obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) +=
36186  obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
36187  obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
36188  obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
36189 +obj-$(CONFIG_IP_NF_MATCH_STEALTH) += ipt_stealth.o
36190  obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o
36191  obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o
36192  
36193 diff -urNp linux-2.6.27.10/net/ipv4/tcp_ipv4.c linux-2.6.27.10/net/ipv4/tcp_ipv4.c
36194 --- linux-2.6.27.10/net/ipv4/tcp_ipv4.c 2008-11-07 12:55:34.000000000 -0500
36195 +++ linux-2.6.27.10/net/ipv4/tcp_ipv4.c 2008-11-18 03:38:45.000000000 -0500
36196 @@ -59,6 +59,7 @@
36197  #include <linux/jhash.h>
36198  #include <linux/init.h>
36199  #include <linux/times.h>
36200 +#include <linux/grsecurity.h>
36201  
36202  #include <net/net_namespace.h>
36203  #include <net/icmp.h>
36204 diff -urNp linux-2.6.27.10/net/ipv4/udp.c linux-2.6.27.10/net/ipv4/udp.c
36205 --- linux-2.6.27.10/net/ipv4/udp.c      2008-12-21 01:16:52.000000000 -0500
36206 +++ linux-2.6.27.10/net/ipv4/udp.c      2008-12-21 01:13:47.000000000 -0500
36207 @@ -97,6 +97,7 @@
36208  #include <linux/skbuff.h>
36209  #include <linux/proc_fs.h>
36210  #include <linux/seq_file.h>
36211 +#include <linux/grsecurity.h>
36212  #include <net/net_namespace.h>
36213  #include <net/icmp.h>
36214  #include <net/route.h>
36215 @@ -104,6 +105,11 @@
36216  #include <net/xfrm.h>
36217  #include "udp_impl.h"
36218  
36219 +extern int gr_search_udp_recvmsg(const struct sock *sk,
36220 +                                const struct sk_buff *skb);
36221 +extern int gr_search_udp_sendmsg(const struct sock *sk,
36222 +                                const struct sockaddr_in *addr);
36223 +
36224  /*
36225   *     Snmp MIB for the UDP layer
36226   */
36227 @@ -302,6 +308,13 @@ static struct sock *__udp4_lib_lookup(st
36228         return result;
36229  }
36230  
36231 +struct sock *udp_v4_lookup(struct net *net, __be32 saddr, __be16 sport,
36232 +                          __be32 daddr, __be16 dport, int dif)
36233 +{
36234 +       return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
36235 +}
36236 +
36237 +
36238  static inline struct sock *udp_v4_mcast_next(struct net *net, struct sock *sk,
36239                                              __be16 loc_port, __be32 loc_addr,
36240                                              __be16 rmt_port, __be32 rmt_addr,
36241 @@ -592,9 +605,16 @@ int udp_sendmsg(struct kiocb *iocb, stru
36242                 dport = usin->sin_port;
36243                 if (dport == 0)
36244                         return -EINVAL;
36245 +
36246 +               if (!gr_search_udp_sendmsg(sk, usin))
36247 +                       return -EPERM;
36248         } else {
36249                 if (sk->sk_state != TCP_ESTABLISHED)
36250                         return -EDESTADDRREQ;
36251 +
36252 +               if (!gr_search_udp_sendmsg(sk, NULL))
36253 +                       return -EPERM;
36254 +
36255                 daddr = inet->daddr;
36256                 dport = inet->dport;
36257                 /* Open fast path for connected socket.
36258 @@ -859,6 +879,11 @@ try_again:
36259         if (!skb)
36260                 goto out;
36261  
36262 +       if (!gr_search_udp_recvmsg(sk, skb)) {
36263 +               err = -EPERM;
36264 +               goto out_free;
36265 +       }
36266 +
36267         ulen = skb->len - sizeof(struct udphdr);
36268         copied = len;
36269         if (copied > ulen)
36270 diff -urNp linux-2.6.27.10/net/ipv6/exthdrs.c linux-2.6.27.10/net/ipv6/exthdrs.c
36271 --- linux-2.6.27.10/net/ipv6/exthdrs.c  2008-11-07 12:55:34.000000000 -0500
36272 +++ linux-2.6.27.10/net/ipv6/exthdrs.c  2008-11-18 03:38:45.000000000 -0500
36273 @@ -624,7 +624,7 @@ static struct tlvtype_proc tlvprochopopt
36274                 .type   = IPV6_TLV_JUMBO,
36275                 .func   = ipv6_hop_jumbo,
36276         },
36277 -       { -1, }
36278 +       { -1, NULL }
36279  };
36280  
36281  int ipv6_parse_hopopts(struct sk_buff *skb)
36282 diff -urNp linux-2.6.27.10/net/ipv6/raw.c linux-2.6.27.10/net/ipv6/raw.c
36283 --- linux-2.6.27.10/net/ipv6/raw.c      2008-11-07 12:55:34.000000000 -0500
36284 +++ linux-2.6.27.10/net/ipv6/raw.c      2008-11-18 03:38:45.000000000 -0500
36285 @@ -600,7 +600,7 @@ out:
36286         return err;
36287  }
36288  
36289 -static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
36290 +static int rawv6_send_hdrinc(struct sock *sk, void *from, unsigned int length,
36291                         struct flowi *fl, struct rt6_info *rt,
36292                         unsigned int flags)
36293  {
36294 diff -urNp linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c
36295 --- linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c        2008-11-07 12:55:34.000000000 -0500
36296 +++ linux-2.6.27.10/net/irda/ircomm/ircomm_tty.c        2008-11-18 03:38:45.000000000 -0500
36297 @@ -371,7 +371,7 @@ static int ircomm_tty_open(struct tty_st
36298         IRDA_DEBUG(2, "%s()\n", __func__ );
36299  
36300         line = tty->index;
36301 -       if ((line < 0) || (line >= IRCOMM_TTY_PORTS)) {
36302 +       if (line >= IRCOMM_TTY_PORTS) {
36303                 return -ENODEV;
36304         }
36305  
36306 diff -urNp linux-2.6.27.10/net/sctp/socket.c linux-2.6.27.10/net/sctp/socket.c
36307 --- linux-2.6.27.10/net/sctp/socket.c   2008-11-07 12:55:34.000000000 -0500
36308 +++ linux-2.6.27.10/net/sctp/socket.c   2008-11-18 03:38:45.000000000 -0500
36309 @@ -1434,7 +1434,7 @@ SCTP_STATIC int sctp_sendmsg(struct kioc
36310         struct sctp_sndrcvinfo *sinfo;
36311         struct sctp_initmsg *sinit;
36312         sctp_assoc_t associd = 0;
36313 -       sctp_cmsgs_t cmsgs = { NULL };
36314 +       sctp_cmsgs_t cmsgs = { NULL, NULL };
36315         int err;
36316         sctp_scope_t scope;
36317         long timeo;
36318 @@ -5616,7 +5616,6 @@ pp_found:
36319                  */
36320                 int reuse = sk->sk_reuse;
36321                 struct sock *sk2;
36322 -               struct hlist_node *node;
36323  
36324                 SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
36325                 if (pp->fastreuse && sk->sk_reuse &&
36326 diff -urNp linux-2.6.27.10/net/socket.c linux-2.6.27.10/net/socket.c
36327 --- linux-2.6.27.10/net/socket.c        2008-11-07 12:55:34.000000000 -0500
36328 +++ linux-2.6.27.10/net/socket.c        2008-11-18 03:38:45.000000000 -0500
36329 @@ -87,6 +87,7 @@
36330  #include <linux/audit.h>
36331  #include <linux/wireless.h>
36332  #include <linux/nsproxy.h>
36333 +#include <linux/in.h>
36334  
36335  #include <asm/uaccess.h>
36336  #include <asm/unistd.h>
36337 @@ -97,6 +98,21 @@
36338  #include <net/sock.h>
36339  #include <linux/netfilter.h>
36340  
36341 +extern void gr_attach_curr_ip(const struct sock *sk);
36342 +extern int gr_handle_sock_all(const int family, const int type,
36343 +                             const int protocol);
36344 +extern int gr_handle_sock_server(const struct sockaddr *sck);
36345 +extern int gr_handle_sock_server_other(const struct socket *sck);
36346 +extern int gr_handle_sock_client(const struct sockaddr *sck);
36347 +extern int gr_search_connect(const struct socket * sock,
36348 +                            const struct sockaddr_in * addr);
36349 +extern int gr_search_bind(const struct socket * sock,
36350 +                          const struct sockaddr_in * addr);
36351 +extern int gr_search_listen(const struct socket * sock);
36352 +extern int gr_search_accept(const struct socket * sock);
36353 +extern int gr_search_socket(const int domain, const int type,
36354 +                           const int protocol);
36355 +
36356  static int sock_no_open(struct inode *irrelevant, struct file *dontcare);
36357  static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
36358                          unsigned long nr_segs, loff_t pos);
36359 @@ -300,7 +316,7 @@ static int sockfs_get_sb(struct file_sys
36360                              mnt);
36361  }
36362  
36363 -static struct vfsmount *sock_mnt __read_mostly;
36364 +struct vfsmount *sock_mnt __read_mostly;
36365  
36366  static struct file_system_type sock_fs_type = {
36367         .name =         "sockfs",
36368 @@ -1236,6 +1252,16 @@ asmlinkage long sys_socket(int family, i
36369         if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK))
36370                 flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK;
36371  
36372 +       if(!gr_search_socket(family, type, protocol)) {
36373 +               retval = -EACCES;
36374 +               goto out;
36375 +       }
36376 +
36377 +       if (gr_handle_sock_all(family, type, protocol)) {
36378 +               retval = -EACCES;
36379 +               goto out;
36380 +       }
36381 +
36382         retval = sock_create(family, type, protocol, &sock);
36383         if (retval < 0)
36384                 goto out;
36385 @@ -1375,6 +1401,12 @@ asmlinkage long sys_bind(int fd, struct 
36386         if (sock) {
36387                 err = move_addr_to_kernel(umyaddr, addrlen, (struct sockaddr *)&address);
36388                 if (err >= 0) {
36389 +                       if (!gr_search_bind(sock, (struct sockaddr_in *)&address) ||
36390 +                           gr_handle_sock_server((struct sockaddr *)&address)) {
36391 +                               err = -EACCES;
36392 +                               goto error;
36393 +                       }
36394 +
36395                         err = security_socket_bind(sock,
36396                                                    (struct sockaddr *)&address,
36397                                                    addrlen);
36398 @@ -1383,6 +1415,7 @@ asmlinkage long sys_bind(int fd, struct 
36399                                                       (struct sockaddr *)
36400                                                       &address, addrlen);
36401                 }
36402 +error:
36403                 fput_light(sock->file, fput_needed);
36404         }
36405         return err;
36406 @@ -1406,10 +1439,17 @@ asmlinkage long sys_listen(int fd, int b
36407                 if ((unsigned)backlog > somaxconn)
36408                         backlog = somaxconn;
36409  
36410 +               if (gr_handle_sock_server_other(sock) ||
36411 +                   !gr_search_listen(sock)) {
36412 +                       err = -EPERM;
36413 +                       goto error;
36414 +               }
36415 +
36416                 err = security_socket_listen(sock, backlog);
36417                 if (!err)
36418                         err = sock->ops->listen(sock, backlog);
36419  
36420 +error:
36421                 fput_light(sock->file, fput_needed);
36422         }
36423         return err;
36424 @@ -1452,6 +1492,13 @@ long do_accept(int fd, struct sockaddr _
36425         newsock->type = sock->type;
36426         newsock->ops = sock->ops;
36427  
36428 +       if (gr_handle_sock_server_other(sock) ||
36429 +           !gr_search_accept(sock)) {
36430 +               err = -EPERM;
36431 +               sock_release(newsock);
36432 +               goto out_put;
36433 +       }
36434 +
36435         /*
36436          * We don't need try_module_get here, as the listening socket (sock)
36437          * has the protocol module (sock->ops->owner) held.
36438 @@ -1495,6 +1542,7 @@ long do_accept(int fd, struct sockaddr _
36439         err = newfd;
36440  
36441         security_socket_post_accept(sock, newsock);
36442 +       gr_attach_curr_ip(newsock->sk);
36443  
36444  out_put:
36445         fput_light(sock->file, fput_needed);
36446 @@ -1589,6 +1637,7 @@ asmlinkage long sys_connect(int fd, stru
36447                             int addrlen)
36448  {
36449         struct socket *sock;
36450 +       struct sockaddr *sck;
36451         struct sockaddr_storage address;
36452         int err, fput_needed;
36453  
36454 @@ -1599,6 +1648,13 @@ asmlinkage long sys_connect(int fd, stru
36455         if (err < 0)
36456                 goto out_put;
36457  
36458 +       sck = (struct sockaddr *)&address;
36459 +       if (!gr_search_connect(sock, (struct sockaddr_in *)sck) ||
36460 +           gr_handle_sock_client(sck)) {
36461 +               err = -EACCES;
36462 +               goto out_put;
36463 +       }
36464 +
36465         err =
36466             security_socket_connect(sock, (struct sockaddr *)&address, addrlen);
36467         if (err)
36468 @@ -1866,6 +1922,7 @@ asmlinkage long sys_shutdown(int fd, int
36469                         err = sock->ops->shutdown(sock, how);
36470                 fput_light(sock->file, fput_needed);
36471         }
36472 +
36473         return err;
36474  }
36475  
36476 diff -urNp linux-2.6.27.10/net/unix/af_unix.c linux-2.6.27.10/net/unix/af_unix.c
36477 --- linux-2.6.27.10/net/unix/af_unix.c  2008-12-21 01:16:52.000000000 -0500
36478 +++ linux-2.6.27.10/net/unix/af_unix.c  2008-12-21 01:13:47.000000000 -0500
36479 @@ -114,6 +114,7 @@
36480  #include <linux/security.h>
36481  #include <linux/vs_context.h>
36482  #include <linux/vs_limit.h>
36483 +#include <linux/grsecurity.h>
36484  
36485  static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
36486  static DEFINE_SPINLOCK(unix_table_lock);
36487 @@ -725,6 +726,12 @@ static struct sock *unix_find_other(stru
36488                 err = -ECONNREFUSED;
36489                 if (!S_ISSOCK(nd.path.dentry->d_inode->i_mode))
36490                         goto put_fail;
36491 +
36492 +               if (!gr_acl_handle_unix(nd.path.dentry, nd.path.mnt)) {
36493 +                       err = -EACCES;
36494 +                       goto put_fail;
36495 +               }
36496 +
36497                 u = unix_find_socket_byinode(net, nd.path.dentry->d_inode);
36498                 if (!u)
36499                         goto put_fail;
36500 @@ -745,6 +752,13 @@ static struct sock *unix_find_other(stru
36501                 if (u) {
36502                         struct dentry *dentry;
36503                         dentry = unix_sk(u)->dentry;
36504 +
36505 +                       if (!gr_handle_chroot_unix(u->sk_peercred.pid)) {
36506 +                               err = -EPERM;
36507 +                               sock_put(u);
36508 +                               goto fail;
36509 +                       }
36510 +
36511                         if (dentry)
36512                                 touch_atime(unix_sk(u)->mnt, dentry);
36513                 } else
36514 @@ -827,10 +841,20 @@ static int unix_bind(struct socket *sock
36515                 err = mnt_want_write(nd.path.mnt);
36516                 if (err)
36517                         goto out_mknod_dput;
36518 +
36519 +               if (!gr_acl_handle_mknod(dentry, nd.path.dentry, nd.path.mnt, mode)) {
36520 +                       err = -EACCES;
36521 +                       mnt_drop_write(nd.path.mnt);
36522 +                       goto out_mknod_dput;
36523 +               }
36524 +
36525                 err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
36526                 mnt_drop_write(nd.path.mnt);
36527                 if (err)
36528                         goto out_mknod_dput;
36529 +
36530 +               gr_handle_create(dentry, nd.path.mnt);
36531 +
36532                 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
36533                 dput(nd.path.dentry);
36534                 nd.path.dentry = dentry;
36535 @@ -848,6 +872,10 @@ static int unix_bind(struct socket *sock
36536                         goto out_unlock;
36537                 }
36538  
36539 +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX
36540 +               sk->sk_peercred.pid = current->pid;
36541 +#endif
36542 +
36543                 list = &unix_socket_table[addr->hash];
36544         } else {
36545                 list = &unix_socket_table[dentry->d_inode->i_ino & (UNIX_HASH_SIZE-1)];
36546 diff -urNp linux-2.6.27.10/scripts/pnmtologo.c linux-2.6.27.10/scripts/pnmtologo.c
36547 --- linux-2.6.27.10/scripts/pnmtologo.c 2008-11-07 12:55:34.000000000 -0500
36548 +++ linux-2.6.27.10/scripts/pnmtologo.c 2008-11-18 03:38:45.000000000 -0500
36549 @@ -237,14 +237,14 @@ static void write_header(void)
36550      fprintf(out, " *  Linux logo %s\n", logoname);
36551      fputs(" */\n\n", out);
36552      fputs("#include <linux/linux_logo.h>\n\n", out);
36553 -    fprintf(out, "static unsigned char %s_data[] __initdata = {\n",
36554 +    fprintf(out, "static unsigned char %s_data[] = {\n",
36555             logoname);
36556  }
36557  
36558  static void write_footer(void)
36559  {
36560      fputs("\n};\n\n", out);
36561 -    fprintf(out, "struct linux_logo %s __initdata = {\n", logoname);
36562 +    fprintf(out, "struct linux_logo %s = {\n", logoname);
36563      fprintf(out, "    .type\t= %s,\n", logo_types[logo_type]);
36564      fprintf(out, "    .width\t= %d,\n", logo_width);
36565      fprintf(out, "    .height\t= %d,\n", logo_height);
36566 @@ -374,7 +374,7 @@ static void write_logo_clut224(void)
36567      fputs("\n};\n\n", out);
36568  
36569      /* write logo clut */
36570 -    fprintf(out, "static unsigned char %s_clut[] __initdata = {\n",
36571 +    fprintf(out, "static unsigned char %s_clut[] = {\n",
36572             logoname);
36573      write_hex_cnt = 0;
36574      for (i = 0; i < logo_clutsize; i++) {
36575 diff -urNp linux-2.6.27.10/security/commoncap.c linux-2.6.27.10/security/commoncap.c
36576 --- linux-2.6.27.10/security/commoncap.c        2008-11-07 12:55:34.000000000 -0500
36577 +++ linux-2.6.27.10/security/commoncap.c        2008-11-18 03:38:45.000000000 -0500
36578 @@ -26,10 +26,13 @@
36579  #include <linux/prctl.h>
36580  #include <linux/securebits.h>
36581  #include <linux/vs_context.h>
36582 +#include <linux/grsecurity.h>
36583 +
36584 +extern kernel_cap_t gr_cap_rtnetlink(struct sock *sk);
36585  
36586  int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
36587  {
36588 -       NETLINK_CB(skb).eff_cap = vx_mbcaps(current->cap_effective);
36589 +       NETLINK_CB(skb).eff_cap = gr_cap_rtnetlink(sk);
36590         return 0;
36591  }
36592  
36593 @@ -51,7 +54,15 @@ EXPORT_SYMBOL(cap_netlink_recv);
36594  int cap_capable (struct task_struct *tsk, int cap)
36595  {
36596         /* Derived from include/linux/sched.h:capable. */
36597 -       if (vx_cap_raised(vxi, tsk->cap_effective, cap))
36598 +       if (vx_cap_raised(vxi, tsk->cap_effective, cap))
36599 +               return 0;
36600 +       return -EPERM;
36601 +}
36602 +
36603 +int cap_capable_nolog (struct task_struct *tsk, int cap)
36604 +{
36605 +       /* tsk = current for all callers */
36606 +       if (cap_raised(tsk->cap_effective, cap) && gr_is_capable_nolog(cap))
36607                 return 0;
36608         return -EPERM;
36609  }
36610 @@ -379,8 +390,11 @@ void cap_bprm_apply_creds (struct linux_
36611                 }
36612         }
36613  
36614 -       current->suid = current->euid = current->fsuid = bprm->e_uid;
36615 -       current->sgid = current->egid = current->fsgid = bprm->e_gid;
36616 +       if (!gr_check_user_change(-1, bprm->e_uid, bprm->e_uid))
36617 +               current->suid = current->euid = current->fsuid = bprm->e_uid;
36618 +
36619 +       if (!gr_check_group_change(-1, bprm->e_gid, bprm->e_gid))
36620 +               current->sgid = current->egid = current->fsgid = bprm->e_gid;
36621  
36622         /* For init, we want to retain the capabilities set
36623          * in the init_task struct. Thus we skip the usual
36624 @@ -393,6 +407,8 @@ void cap_bprm_apply_creds (struct linux_
36625                         cap_clear(current->cap_effective);
36626         }
36627  
36628 +       gr_handle_chroot_caps(current);
36629 +
36630         /* AUD: Audit candidate if current->cap_effective is set */
36631  
36632         current->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
36633 @@ -705,7 +721,7 @@ int cap_vm_enough_memory(struct mm_struc
36634  {
36635         int cap_sys_admin = 0;
36636  
36637 -       if (cap_capable(current, CAP_SYS_ADMIN) == 0)
36638 +       if (cap_capable_nolog(current, CAP_SYS_ADMIN) == 0)
36639                 cap_sys_admin = 1;
36640         return __vm_enough_memory(mm, pages, cap_sys_admin);
36641  }
36642 diff -urNp linux-2.6.27.10/security/Kconfig linux-2.6.27.10/security/Kconfig
36643 --- linux-2.6.27.10/security/Kconfig    2008-11-07 12:55:34.000000000 -0500
36644 +++ linux-2.6.27.10/security/Kconfig    2008-11-18 03:38:45.000000000 -0500
36645 @@ -4,6 +4,447 @@
36646  
36647  menu "Security options"
36648  
36649 +source grsecurity/Kconfig
36650 +
36651 +menu "PaX"
36652 +
36653 +config PAX
36654 +       bool "Enable various PaX features"
36655 +       depends on GRKERNSEC && (ALPHA || ARM || AVR32 || IA64 || MIPS32 || MIPS64 || PARISC || PPC32 || PPC64 || SPARC32 || SPARC64 || X86)
36656 +       help
36657 +         This allows you to enable various PaX features.  PaX adds
36658 +         intrusion prevention mechanisms to the kernel that reduce
36659 +         the risks posed by exploitable memory corruption bugs.
36660 +
36661 +menu "PaX Control"
36662 +       depends on PAX
36663 +
36664 +config PAX_SOFTMODE
36665 +       bool 'Support soft mode'
36666 +       help
36667 +         Enabling this option will allow you to run PaX in soft mode, that
36668 +         is, PaX features will not be enforced by default, only on executables
36669 +         marked explicitly.  You must also enable PT_PAX_FLAGS support as it
36670 +         is the only way to mark executables for soft mode use.
36671 +
36672 +         Soft mode can be activated by using the "pax_softmode=1" kernel command
36673 +         line option on boot.  Furthermore you can control various PaX features
36674 +         at runtime via the entries in /proc/sys/kernel/pax.
36675 +
36676 +config PAX_EI_PAX
36677 +       bool 'Use legacy ELF header marking'
36678 +       help
36679 +         Enabling this option will allow you to control PaX features on
36680 +         a per executable basis via the 'chpax' utility available at
36681 +         http://pax.grsecurity.net/.  The control flags will be read from
36682 +         an otherwise reserved part of the ELF header.  This marking has
36683 +         numerous drawbacks (no support for soft-mode, toolchain does not
36684 +         know about the non-standard use of the ELF header) therefore it
36685 +         has been deprecated in favour of PT_PAX_FLAGS support.
36686 +
36687 +         If you have applications not marked by the PT_PAX_FLAGS ELF
36688 +         program header then you MUST enable this option otherwise they
36689 +         will not get any protection.
36690 +
36691 +         Note that if you enable PT_PAX_FLAGS marking support as well,
36692 +         the PT_PAX_FLAG marks will override the legacy EI_PAX marks.
36693 +
36694 +config PAX_PT_PAX_FLAGS
36695 +       bool 'Use ELF program header marking'
36696 +       help
36697 +         Enabling this option will allow you to control PaX features on
36698 +         a per executable basis via the 'paxctl' utility available at
36699 +         http://pax.grsecurity.net/.  The control flags will be read from
36700 +         a PaX specific ELF program header (PT_PAX_FLAGS).  This marking
36701 +         has the benefits of supporting both soft mode and being fully
36702 +         integrated into the toolchain (the binutils patch is available
36703 +         from http://pax.grsecurity.net).
36704 +
36705 +         If you have applications not marked by the PT_PAX_FLAGS ELF
36706 +         program header then you MUST enable the EI_PAX marking support
36707 +         otherwise they will not get any protection.
36708 +
36709 +         Note that if you enable the legacy EI_PAX marking support as well,
36710 +         the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks.
36711 +
36712 +choice
36713 +       prompt 'MAC system integration'
36714 +       default PAX_HAVE_ACL_FLAGS
36715 +       help
36716 +         Mandatory Access Control systems have the option of controlling
36717 +         PaX flags on a per executable basis, choose the method supported
36718 +         by your particular system.
36719 +
36720 +         - "none": if your MAC system does not interact with PaX,
36721 +         - "direct": if your MAC system defines pax_set_initial_flags() itself,
36722 +         - "hook": if your MAC system uses the pax_set_initial_flags_func callback.
36723 +
36724 +         NOTE: this option is for developers/integrators only.
36725 +
36726 +       config PAX_NO_ACL_FLAGS
36727 +               bool 'none'
36728 +
36729 +       config PAX_HAVE_ACL_FLAGS
36730 +               bool 'direct'
36731 +
36732 +       config PAX_HOOK_ACL_FLAGS
36733 +               bool 'hook'
36734 +endchoice
36735 +
36736 +endmenu
36737 +
36738 +menu "Non-executable pages"
36739 +       depends on PAX
36740 +
36741 +config PAX_NOEXEC
36742 +       bool "Enforce non-executable pages"
36743 +       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)
36744 +       help
36745 +         By design some architectures do not allow for protecting memory
36746 +         pages against execution or even if they do, Linux does not make
36747 +         use of this feature.  In practice this means that if a page is
36748 +         readable (such as the stack or heap) it is also executable.
36749 +
36750 +         There is a well known exploit technique that makes use of this
36751 +         fact and a common programming mistake where an attacker can
36752 +         introduce code of his choice somewhere in the attacked program's
36753 +         memory (typically the stack or the heap) and then execute it.
36754 +
36755 +         If the attacked program was running with different (typically
36756 +         higher) privileges than that of the attacker, then he can elevate
36757 +         his own privilege level (e.g. get a root shell, write to files for
36758 +         which he does not have write access to, etc).
36759 +
36760 +         Enabling this option will let you choose from various features
36761 +         that prevent the injection and execution of 'foreign' code in
36762 +         a program.
36763 +
36764 +         This will also break programs that rely on the old behaviour and
36765 +         expect that dynamically allocated memory via the malloc() family
36766 +         of functions is executable (which it is not).  Notable examples
36767 +         are the XFree86 4.x server, the java runtime and wine.
36768 +
36769 +config PAX_PAGEEXEC
36770 +       bool "Paging based non-executable pages"
36771 +       depends on !COMPAT_VDSO && PAX_NOEXEC && (!X86_32 || M586 || M586TSC || M586MMX || M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC || MK7 || MK8 || MWINCHIPC6 || MWINCHIP2 || MWINCHIP3D || MVIAC3_2 || MVIAC7)
36772 +       help
36773 +         This implementation is based on the paging feature of the CPU.
36774 +         On i386 without hardware non-executable bit support there is a
36775 +         variable but usually low performance impact, however on Intel's
36776 +         P4 core based CPUs it is very high so you should not enable this
36777 +         for kernels meant to be used on such CPUs.
36778 +
36779 +         On alpha, avr32, ia64, parisc, sparc, sparc64, x86_64 and i386
36780 +         with hardware non-executable bit support there is no performance
36781 +         impact, on ppc the impact is negligible.
36782 +
36783 +         Note that several architectures require various emulations due to
36784 +         badly designed userland ABIs, this will cause a performance impact
36785 +         but will disappear as soon as userland is fixed (e.g., ppc users
36786 +         can make use of the secure-plt feature found in binutils).
36787 +
36788 +config PAX_SEGMEXEC
36789 +       bool "Segmentation based non-executable pages"
36790 +       depends on !COMPAT_VDSO && PAX_NOEXEC && X86_32
36791 +       help
36792 +         This implementation is based on the segmentation feature of the
36793 +         CPU and has a very small performance impact, however applications
36794 +         will be limited to a 1.5 GB address space instead of the normal
36795 +         3 GB.
36796 +
36797 +config PAX_EMUTRAMP
36798 +       bool "Emulate trampolines" if (PAX_PAGEEXEC || PAX_SEGMEXEC) && (PARISC || PPC32 || X86)
36799 +       default y if PARISC || PPC32
36800 +       help
36801 +         There are some programs and libraries that for one reason or
36802 +         another attempt to execute special small code snippets from
36803 +         non-executable memory pages.  Most notable examples are the
36804 +         signal handler return code generated by the kernel itself and
36805 +         the GCC trampolines.
36806 +
36807 +         If you enabled CONFIG_PAX_PAGEEXEC or CONFIG_PAX_SEGMEXEC then
36808 +         such programs will no longer work under your kernel.
36809 +
36810 +         As a remedy you can say Y here and use the 'chpax' or 'paxctl'
36811 +         utilities to enable trampoline emulation for the affected programs
36812 +         yet still have the protection provided by the non-executable pages.
36813 +
36814 +         On parisc and ppc you MUST enable this option and EMUSIGRT as
36815 +         well, otherwise your system will not even boot.
36816 +
36817 +         Alternatively you can say N here and use the 'chpax' or 'paxctl'
36818 +         utilities to disable CONFIG_PAX_PAGEEXEC and CONFIG_PAX_SEGMEXEC
36819 +         for the affected files.
36820 +
36821 +         NOTE: enabling this feature *may* open up a loophole in the
36822 +         protection provided by non-executable pages that an attacker
36823 +         could abuse.  Therefore the best solution is to not have any
36824 +         files on your system that would require this option.  This can
36825 +         be achieved by not using libc5 (which relies on the kernel
36826 +         signal handler return code) and not using or rewriting programs
36827 +         that make use of the nested function implementation of GCC.
36828 +         Skilled users can just fix GCC itself so that it implements
36829 +         nested function calls in a way that does not interfere with PaX.
36830 +
36831 +config PAX_EMUSIGRT
36832 +       bool "Automatically emulate sigreturn trampolines"
36833 +       depends on PAX_EMUTRAMP && (PARISC || PPC32)
36834 +       default y
36835 +       help
36836 +         Enabling this option will have the kernel automatically detect
36837 +         and emulate signal return trampolines executing on the stack
36838 +         that would otherwise lead to task termination.
36839 +
36840 +         This solution is intended as a temporary one for users with
36841 +         legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17,
36842 +         Modula-3 runtime, etc) or executables linked to such, basically
36843 +         everything that does not specify its own SA_RESTORER function in
36844 +         normal executable memory like glibc 2.1+ does.
36845 +
36846 +         On parisc and ppc you MUST enable this option, otherwise your
36847 +         system will not even boot.
36848 +
36849 +         NOTE: this feature cannot be disabled on a per executable basis
36850 +         and since it *does* open up a loophole in the protection provided
36851 +         by non-executable pages, the best solution is to not have any
36852 +         files on your system that would require this option.
36853 +
36854 +config PAX_MPROTECT
36855 +       bool "Restrict mprotect()"
36856 +       depends on (PAX_PAGEEXEC || PAX_SEGMEXEC) && !PPC64
36857 +       help
36858 +         Enabling this option will prevent programs from
36859 +          - changing the executable status of memory pages that were
36860 +            not originally created as executable,
36861 +          - making read-only executable pages writable again,
36862 +          - creating executable pages from anonymous memory.
36863 +
36864 +         You should say Y here to complete the protection provided by
36865 +         the enforcement of non-executable pages.
36866 +
36867 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36868 +         this feature on a per file basis.
36869 +
36870 +config PAX_NOELFRELOCS
36871 +       bool "Disallow ELF text relocations"
36872 +       depends on PAX_MPROTECT && !PAX_ETEXECRELOCS && (IA64 || X86)
36873 +       help
36874 +         Non-executable pages and mprotect() restrictions are effective
36875 +         in preventing the introduction of new executable code into an
36876 +         attacked task's address space.  There remain only two venues
36877 +         for this kind of attack: if the attacker can execute already
36878 +         existing code in the attacked task then he can either have it
36879 +         create and mmap() a file containing his code or have it mmap()
36880 +         an already existing ELF library that does not have position
36881 +         independent code in it and use mprotect() on it to make it
36882 +         writable and copy his code there.  While protecting against
36883 +         the former approach is beyond PaX, the latter can be prevented
36884 +         by having only PIC ELF libraries on one's system (which do not
36885 +         need to relocate their code).  If you are sure this is your case,
36886 +         then enable this option otherwise be careful as you may not even
36887 +         be able to boot or log on your system (for example, some PAM
36888 +         modules are erroneously compiled as non-PIC by default).
36889 +
36890 +         NOTE: if you are using dynamic ELF executables (as suggested
36891 +         when using ASLR) then you must have made sure that you linked
36892 +         your files using the PIC version of crt1 (the et_dyn.tar.gz package
36893 +         referenced there has already been updated to support this).
36894 +
36895 +config PAX_ETEXECRELOCS
36896 +       bool "Allow ELF ET_EXEC text relocations"
36897 +       depends on PAX_MPROTECT && (ALPHA || IA64 || PARISC)
36898 +       default y
36899 +       help
36900 +         On some architectures there are incorrectly created applications
36901 +         that require text relocations and would not work without enabling
36902 +         this option.  If you are an alpha, ia64 or parisc user, you should
36903 +         enable this option and disable it once you have made sure that
36904 +         none of your applications need it.
36905 +
36906 +config PAX_EMUPLT
36907 +       bool "Automatically emulate ELF PLT"
36908 +       depends on PAX_MPROTECT && (ALPHA || PARISC || PPC32 || SPARC32 || SPARC64)
36909 +       default y
36910 +       help
36911 +         Enabling this option will have the kernel automatically detect
36912 +         and emulate the Procedure Linkage Table entries in ELF files.
36913 +         On some architectures such entries are in writable memory, and
36914 +         become non-executable leading to task termination.  Therefore
36915 +         it is mandatory that you enable this option on alpha, parisc,
36916 +         ppc (if secure-plt is not used throughout in userland), sparc
36917 +         and sparc64, otherwise your system would not even boot.
36918 +
36919 +         NOTE: this feature *does* open up a loophole in the protection
36920 +         provided by the non-executable pages, therefore the proper
36921 +         solution is to modify the toolchain to produce a PLT that does
36922 +         not need to be writable.
36923 +
36924 +config PAX_DLRESOLVE
36925 +       bool
36926 +       depends on PAX_EMUPLT && (SPARC32 || SPARC64)
36927 +       default y
36928 +
36929 +config PAX_SYSCALL
36930 +       bool
36931 +       depends on PAX_PAGEEXEC && PPC32
36932 +       default y
36933 +
36934 +config PAX_KERNEXEC
36935 +       bool "Enforce non-executable kernel pages"
36936 +       depends on PAX_NOEXEC && X86 && !EFI && !COMPAT_VDSO && (!X86_32 || X86_WP_WORKS_OK) && !PARAVIRT
36937 +       help
36938 +         This is the kernel land equivalent of PAGEEXEC and MPROTECT,
36939 +         that is, enabling this option will make it harder to inject
36940 +         and execute 'foreign' code in kernel memory itself.
36941 +
36942 +endmenu
36943 +
36944 +menu "Address Space Layout Randomization"
36945 +       depends on PAX
36946 +
36947 +config PAX_ASLR
36948 +       bool "Address Space Layout Randomization"
36949 +       depends on PAX_EI_PAX || PAX_PT_PAX_FLAGS || PAX_HAVE_ACL_FLAGS || PAX_HOOK_ACL_FLAGS
36950 +       help
36951 +         Many if not most exploit techniques rely on the knowledge of
36952 +         certain addresses in the attacked program.  The following options
36953 +         will allow the kernel to apply a certain amount of randomization
36954 +         to specific parts of the program thereby forcing an attacker to
36955 +         guess them in most cases.  Any failed guess will most likely crash
36956 +         the attacked program which allows the kernel to detect such attempts
36957 +         and react on them.  PaX itself provides no reaction mechanisms,
36958 +         instead it is strongly encouraged that you make use of Nergal's
36959 +         segvguard (ftp://ftp.pl.openwall.com/misc/segvguard/) or grsecurity's
36960 +         (http://www.grsecurity.net/) built-in crash detection features or
36961 +         develop one yourself.
36962 +
36963 +         By saying Y here you can choose to randomize the following areas:
36964 +          - top of the task's kernel stack
36965 +          - top of the task's userland stack
36966 +          - base address for mmap() requests that do not specify one
36967 +            (this includes all libraries)
36968 +          - base address of the main executable
36969 +
36970 +         It is strongly recommended to say Y here as address space layout
36971 +         randomization has negligible impact on performance yet it provides
36972 +         a very effective protection.
36973 +
36974 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control
36975 +         this feature on a per file basis.
36976 +
36977 +config PAX_RANDKSTACK
36978 +       bool "Randomize kernel stack base"
36979 +       depends on PAX_ASLR && X86_TSC && X86_32
36980 +       help
36981 +         By saying Y here the kernel will randomize every task's kernel
36982 +         stack on every system call.  This will not only force an attacker
36983 +         to guess it but also prevent him from making use of possible
36984 +         leaked information about it.
36985 +
36986 +         Since the kernel stack is a rather scarce resource, randomization
36987 +         may cause unexpected stack overflows, therefore you should very
36988 +         carefully test your system.  Note that once enabled in the kernel
36989 +         configuration, this feature cannot be disabled on a per file basis.
36990 +
36991 +config PAX_RANDUSTACK
36992 +       bool "Randomize user stack base"
36993 +       depends on PAX_ASLR
36994 +       help
36995 +         By saying Y here the kernel will randomize every task's userland
36996 +         stack.  The randomization is done in two steps where the second
36997 +         one may apply a big amount of shift to the top of the stack and
36998 +         cause problems for programs that want to use lots of memory (more
36999 +         than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is).
37000 +         For this reason the second step can be controlled by 'chpax' or
37001 +         'paxctl' on a per file basis.
37002 +
37003 +config PAX_RANDMMAP
37004 +       bool "Randomize mmap() base"
37005 +       depends on PAX_ASLR
37006 +       help
37007 +         By saying Y here the kernel will use a randomized base address for
37008 +         mmap() requests that do not specify one themselves.  As a result
37009 +         all dynamically loaded libraries will appear at random addresses
37010 +         and therefore be harder to exploit by a technique where an attacker
37011 +         attempts to execute library code for his purposes (e.g. spawn a
37012 +         shell from an exploited program that is running at an elevated
37013 +         privilege level).
37014 +
37015 +         Furthermore, if a program is relinked as a dynamic ELF file, its
37016 +         base address will be randomized as well, completing the full
37017 +         randomization of the address space layout.  Attacking such programs
37018 +         becomes a guess game.  You can find an example of doing this at
37019 +         http://pax.grsecurity.net/et_dyn.tar.gz and practical samples at
37020 +         http://www.grsecurity.net/grsec-gcc-specs.tar.gz .
37021 +
37022 +         NOTE: you can use the 'chpax' or 'paxctl' utilities to control this
37023 +         feature on a per file basis.
37024 +
37025 +endmenu
37026 +
37027 +menu "Miscellaneous hardening features"
37028 +
37029 +config PAX_MEMORY_SANITIZE
37030 +       bool "Sanitize all freed memory"
37031 +       help
37032 +         By saying Y here the kernel will erase memory pages as soon as they
37033 +         are freed.  This in turn reduces the lifetime of data stored in the
37034 +         pages, making it less likely that sensitive information such as
37035 +         passwords, cryptographic secrets, etc stay in memory for too long.
37036 +
37037 +         This is especially useful for programs whose runtime is short, long
37038 +         lived processes and the kernel itself benefit from this as long as
37039 +         they operate on whole memory pages and ensure timely freeing of pages
37040 +         that may hold sensitive information.
37041 +
37042 +         The tradeoff is performance impact, on a single CPU system kernel
37043 +         compilation sees a 3% slowdown, other systems and workloads may vary
37044 +         and you are advised to test this feature on your expected workload
37045 +         before deploying it.
37046 +
37047 +         Note that this feature does not protect data stored in live pages,
37048 +         e.g., process memory swapped to disk may stay there for a long time.
37049 +
37050 +config PAX_MEMORY_UDEREF
37051 +       bool "Prevent invalid userland pointer dereference"
37052 +       depends on X86_32 && !COMPAT_VDSO && !UML_X86
37053 +       help
37054 +         By saying Y here the kernel will be prevented from dereferencing
37055 +         userland pointers in contexts where the kernel expects only kernel
37056 +         pointers.  This is both a useful runtime debugging feature and a
37057 +         security measure that prevents exploiting a class of kernel bugs.
37058 +
37059 +         The tradeoff is that some virtualization solutions may experience
37060 +         a huge slowdown and therefore you should not enable this feature
37061 +         for kernels meant to run in such environments.  Whether a given VM
37062 +         solution is affected or not is best determined by simply trying it
37063 +         out, the performance impact will be obvious right on boot as this
37064 +         mechanism engages from very early on.  A good rule of thumb is that
37065 +         VMs running on CPUs without hardware virtualization support (i.e.,
37066 +         the majority of IA-32 CPUs) will likely experience the slowdown.
37067 +
37068 +config PAX_REFCOUNT
37069 +       bool "Prevent various kernel object reference counter overflows"
37070 +       depends on X86
37071 +       help
37072 +         By saying Y here the kernel will detect and prevent overflowing
37073 +         various (but not all) kinds of object reference counters.  Such
37074 +         overflows can normally occur due to bugs only and are often, if
37075 +         not always, exploitable.
37076 +
37077 +         The tradeoff is that data structures protected by an oveflowed
37078 +         refcount will never be freed and therefore will leak memory.  Note
37079 +         that this leak also happens even without this protection but in
37080 +         that case the overflow can eventually trigger the freeing of the
37081 +         data structure while it is still being used elsewhere, resulting
37082 +         in the exploitable situation that this feature prevents.
37083 +
37084 +         Since this has a negligible performance impact, you should enable
37085 +         this feature.
37086 +endmenu
37087 +
37088 +endmenu
37089 +
37090  config KEYS
37091         bool "Enable access key retention support"
37092         help
37093 diff -urNp linux-2.6.27.10/sound/core/oss/pcm_oss.c linux-2.6.27.10/sound/core/oss/pcm_oss.c
37094 --- linux-2.6.27.10/sound/core/oss/pcm_oss.c    2008-11-07 12:55:34.000000000 -0500
37095 +++ linux-2.6.27.10/sound/core/oss/pcm_oss.c    2008-11-18 03:38:45.000000000 -0500
37096 @@ -2911,8 +2911,8 @@ static void snd_pcm_oss_proc_done(struct
37097         }
37098  }
37099  #else /* !CONFIG_SND_VERBOSE_PROCFS */
37100 -#define snd_pcm_oss_proc_init(pcm)
37101 -#define snd_pcm_oss_proc_done(pcm)
37102 +#define snd_pcm_oss_proc_init(pcm) do {} while (0)
37103 +#define snd_pcm_oss_proc_done(pcm) do {} while (0)
37104  #endif /* CONFIG_SND_VERBOSE_PROCFS */
37105  
37106  /*
37107 diff -urNp linux-2.6.27.10/sound/core/seq/seq_lock.h linux-2.6.27.10/sound/core/seq/seq_lock.h
37108 --- linux-2.6.27.10/sound/core/seq/seq_lock.h   2008-11-07 12:55:34.000000000 -0500
37109 +++ linux-2.6.27.10/sound/core/seq/seq_lock.h   2008-11-18 03:38:45.000000000 -0500
37110 @@ -23,10 +23,10 @@ void snd_use_lock_sync_helper(snd_use_lo
37111  #else /* SMP || CONFIG_SND_DEBUG */
37112  
37113  typedef spinlock_t snd_use_lock_t;     /* dummy */
37114 -#define snd_use_lock_init(lockp) /**/
37115 -#define snd_use_lock_use(lockp) /**/
37116 -#define snd_use_lock_free(lockp) /**/
37117 -#define snd_use_lock_sync(lockp) /**/
37118 +#define snd_use_lock_init(lockp) do {} while (0)
37119 +#define snd_use_lock_use(lockp) do {} while (0)
37120 +#define snd_use_lock_free(lockp) do {} while (0)
37121 +#define snd_use_lock_sync(lockp) do {} while (0)
37122  
37123  #endif /* SMP || CONFIG_SND_DEBUG */
37124  
37125 diff -urNp linux-2.6.27.10/sound/pci/ac97/ac97_patch.c linux-2.6.27.10/sound/pci/ac97/ac97_patch.c
37126 --- linux-2.6.27.10/sound/pci/ac97/ac97_patch.c 2008-11-07 12:55:34.000000000 -0500
37127 +++ linux-2.6.27.10/sound/pci/ac97/ac97_patch.c 2008-11-18 03:38:45.000000000 -0500
37128 @@ -1498,7 +1498,7 @@ static const struct snd_ac97_res_table a
37129         { AC97_VIDEO, 0x9f1f },
37130         { AC97_AUX, 0x9f1f },
37131         { AC97_PCM, 0x9f1f },
37132 -       { } /* terminator */
37133 +       { 0, 0 } /* terminator */
37134  };
37135  
37136  static int patch_ad1819(struct snd_ac97 * ac97)
37137 @@ -3668,7 +3668,7 @@ static struct snd_ac97_res_table lm4550_
37138         { AC97_AUX, 0x1f1f },
37139         { AC97_PCM, 0x1f1f },
37140         { AC97_REC_GAIN, 0x0f0f },
37141 -       { } /* terminator */
37142 +       { 0, 0 } /* terminator */
37143  };
37144  
37145  static int patch_lm4550(struct snd_ac97 *ac97)
37146 diff -urNp linux-2.6.27.10/sound/pci/ens1370.c linux-2.6.27.10/sound/pci/ens1370.c
37147 --- linux-2.6.27.10/sound/pci/ens1370.c 2008-11-07 12:55:34.000000000 -0500
37148 +++ linux-2.6.27.10/sound/pci/ens1370.c 2008-11-18 03:38:45.000000000 -0500
37149 @@ -452,7 +452,7 @@ static struct pci_device_id snd_audiopci
37150         { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* ES1373 - CT5880 */
37151         { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },   /* Ectiva EV1938 */
37152  #endif
37153 -       { 0, }
37154 +       { 0, 0, 0, 0, 0, 0, 0 }
37155  };
37156  
37157  MODULE_DEVICE_TABLE(pci, snd_audiopci_ids);
37158 diff -urNp linux-2.6.27.10/sound/pci/intel8x0.c linux-2.6.27.10/sound/pci/intel8x0.c
37159 --- linux-2.6.27.10/sound/pci/intel8x0.c        2008-11-07 12:55:34.000000000 -0500
37160 +++ linux-2.6.27.10/sound/pci/intel8x0.c        2008-11-18 03:38:45.000000000 -0500
37161 @@ -437,7 +437,7 @@ static struct pci_device_id snd_intel8x0
37162         { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37163         { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
37164         { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
37165 -       { 0, }
37166 +       { 0, 0, 0, 0, 0, 0, 0 }
37167  };
37168  
37169  MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
37170 @@ -2076,7 +2076,7 @@ static struct ac97_quirk ac97_quirks[] _
37171                 .type = AC97_TUNE_HP_ONLY
37172         },
37173  #endif
37174 -       { } /* terminator */
37175 +       { 0, 0, 0, 0, NULL, 0 } /* terminator */
37176  };
37177  
37178  static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
37179 diff -urNp linux-2.6.27.10/sound/pci/intel8x0m.c linux-2.6.27.10/sound/pci/intel8x0m.c
37180 --- linux-2.6.27.10/sound/pci/intel8x0m.c       2008-11-07 12:55:34.000000000 -0500
37181 +++ linux-2.6.27.10/sound/pci/intel8x0m.c       2008-11-18 03:38:45.000000000 -0500
37182 @@ -239,7 +239,7 @@ static struct pci_device_id snd_intel8x0
37183         { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */
37184         { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI },   /* Ali5455 */
37185  #endif
37186 -       { 0, }
37187 +       { 0, 0, 0, 0, 0, 0, 0 }
37188  };
37189  
37190  MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
37191 @@ -1257,7 +1257,7 @@ static struct shortname_table {
37192         { 0x5455, "ALi M5455" },
37193         { 0x746d, "AMD AMD8111" },
37194  #endif
37195 -       { 0 },
37196 +       { 0, NULL },
37197  };
37198  
37199  static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
37200 diff -urNp linux-2.6.27.10/virt/kvm/kvm_main.c linux-2.6.27.10/virt/kvm/kvm_main.c
37201 --- linux-2.6.27.10/virt/kvm/kvm_main.c 2008-11-07 12:55:34.000000000 -0500
37202 +++ linux-2.6.27.10/virt/kvm/kvm_main.c 2008-11-18 03:38:45.000000000 -0500
37203 @@ -1469,6 +1469,9 @@ static struct miscdevice kvm_dev = {
37204         KVM_MINOR,
37205         "kvm",
37206         &kvm_chardev_ops,
37207 +       {NULL, NULL},
37208 +       NULL,
37209 +       NULL
37210  };
37211  
37212  static void hardware_enable(void *junk)
This page took 2.970676 seconds and 3 git commands to generate.